diff --git a/packages/learn/seed/challenges/05-apis-and-microservices/api-and-microservice-projects.json b/packages/learn/seed/challenges/05-apis-and-microservices/api-and-microservice-projects.json index eca6eab092..a9aea909e3 100644 --- a/packages/learn/seed/challenges/05-apis-and-microservices/api-and-microservice-projects.json +++ b/packages/learn/seed/challenges/05-apis-and-microservices/api-and-microservice-projects.json @@ -170,5 +170,8 @@ } } } - ] -} + ], + "fileName": "05-apis-and-microservices/api-and-microservice-projects.json", + "superBlock": "apis-and-microservices", + "superOrder": 5 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/05-apis-and-microservices/basic-node-and-express.json b/packages/learn/seed/challenges/05-apis-and-microservices/basic-node-and-express.json index 8e66186b4e..6a96c813ff 100644 --- a/packages/learn/seed/challenges/05-apis-and-microservices/basic-node-and-express.json +++ b/packages/learn/seed/challenges/05-apis-and-microservices/basic-node-and-express.json @@ -283,5 +283,8 @@ "challengeType": 2, "translations": {} } - ] -} + ], + "fileName": "05-apis-and-microservices/basic-node-and-express.json", + "superBlock": "apis-and-microservices", + "superOrder": 5 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/05-apis-and-microservices/managing-packages-with-npm.json b/packages/learn/seed/challenges/05-apis-and-microservices/managing-packages-with-npm.json index de61f08dae..d83554ee95 100644 --- a/packages/learn/seed/challenges/05-apis-and-microservices/managing-packages-with-npm.json +++ b/packages/learn/seed/challenges/05-apis-and-microservices/managing-packages-with-npm.json @@ -278,5 +278,8 @@ "challengeType": 2, "translations": {} } - ] -} + ], + "fileName": "05-apis-and-microservices/managing-packages-with-npm.json", + "superBlock": "apis-and-microservices", + "superOrder": 5 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/05-apis-and-microservices/mongodb-and-mongoose.json b/packages/learn/seed/challenges/05-apis-and-microservices/mongodb-and-mongoose.json index 9f42a8e99c..0c5389b3ae 100644 --- a/packages/learn/seed/challenges/05-apis-and-microservices/mongodb-and-mongoose.json +++ b/packages/learn/seed/challenges/05-apis-and-microservices/mongodb-and-mongoose.json @@ -256,5 +256,8 @@ "challengeType": 2, "translations": {} } - ] -} + ], + "fileName": "05-apis-and-microservices/mongodb-and-mongoose.json", + "superBlock": "apis-and-microservices", + "superOrder": 5 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/06-information-security-and-quality-assurance/advanced-express-tools.json b/packages/learn/seed/challenges/06-information-security-and-quality-assurance/advanced-express-tools.json index 3a98bf0a6d..e9a733444e 100644 --- a/packages/learn/seed/challenges/06-information-security-and-quality-assurance/advanced-express-tools.json +++ b/packages/learn/seed/challenges/06-information-security-and-quality-assurance/advanced-express-tools.json @@ -651,5 +651,8 @@ "challengeType": 2, "translations": {} } - ] -} + ], + "fileName": "06-information-security-and-quality-assurance/advanced-express-tools.json", + "superBlock": "information-security-and-quality-assurance", + "superOrder": 6 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/06-information-security-and-quality-assurance/information-security-with-helmetjs.json b/packages/learn/seed/challenges/06-information-security-and-quality-assurance/helmetjs.json similarity index 99% rename from packages/learn/seed/challenges/06-information-security-and-quality-assurance/information-security-with-helmetjs.json rename to packages/learn/seed/challenges/06-information-security-and-quality-assurance/helmetjs.json index 6e7c11a54e..9b1b855a1e 100644 --- a/packages/learn/seed/challenges/06-information-security-and-quality-assurance/information-security-with-helmetjs.json +++ b/packages/learn/seed/challenges/06-information-security-and-quality-assurance/helmetjs.json @@ -333,5 +333,8 @@ "releasedOn": "Feb 17, 2017", "translations": {} } - ] -} + ], + "fileName": "06-information-security-and-quality-assurance/information-security-with-helmetjs.json", + "superBlock": "information-security-and-quality-assurance", + "superOrder": 6 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/06-information-security-and-quality-assurance/quality-assurance-and-information-security-projects.json b/packages/learn/seed/challenges/06-information-security-and-quality-assurance/quality-assurance-and-information-security-projects.json index aed18c6357..d18d75bd76 100644 --- a/packages/learn/seed/challenges/06-information-security-and-quality-assurance/quality-assurance-and-information-security-projects.json +++ b/packages/learn/seed/challenges/06-information-security-and-quality-assurance/quality-assurance-and-information-security-projects.json @@ -294,5 +294,8 @@ "releasedOn": "January 15, 2017", "translations": {} } - ] -} + ], + "fileName": "06-information-security-and-quality-assurance/quality-assurance-and-information-security-projects.json", + "superBlock": "information-security-and-quality-assurance", + "superOrder": 6 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/06-information-security-and-quality-assurance/quality-assurance-and-testing-with-chai.json b/packages/learn/seed/challenges/06-information-security-and-quality-assurance/testing-with-chai.json similarity index 99% rename from packages/learn/seed/challenges/06-information-security-and-quality-assurance/quality-assurance-and-testing-with-chai.json rename to packages/learn/seed/challenges/06-information-security-and-quality-assurance/testing-with-chai.json index 0d8f6e12d0..afc655f95c 100644 --- a/packages/learn/seed/challenges/06-information-security-and-quality-assurance/quality-assurance-and-testing-with-chai.json +++ b/packages/learn/seed/challenges/06-information-security-and-quality-assurance/testing-with-chai.json @@ -811,5 +811,8 @@ "releasedOn": "Feb 17, 2017", "translations": {} } - ] -} + ], + "fileName": "06-information-security-and-quality-assurance/quality-assurance-and-testing-with-chai.json", + "superBlock": "information-security-and-quality-assurance", + "superOrder": 6 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/08-coding-interview-prep/algorithms.json b/packages/learn/seed/challenges/08-coding-interview-prep/algorithms.json new file mode 100644 index 0000000000..0de87438f6 --- /dev/null +++ b/packages/learn/seed/challenges/08-coding-interview-prep/algorithms.json @@ -0,0 +1,689 @@ +{ + "name": "Algorithms", + "order": 1, + "time": "", + "helpRoom": "HelpJavaScript", + "challenges": [ + { + "id": "a3f503de51cf954ede28891d", + "title": "Symmetric Difference", + "description": [ + "Create a function that takes two or more arrays and returns an array of the symmetric difference ( or ) of the provided arrays.", + "Given two sets (for example set A = {1, 2, 3} and set B = {2, 3, 4}), the mathematical term \"symmetric difference\" of two sets is the set of elements which are in either of the two sets, but not in both (A △ B = C = {1, 4}). For every additional symmetric difference you take (say on a set D = {2, 3}), you should get the set with elements which are in either of the two the sets but not both (C △ D = {1, 4} △ {2, 3} = {1, 2, 3, 4}). The resulting array must contain only unique values (no duplicates).", + "Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code." + ], + "solutions": [ + "function sym() {\n var arrays = [].slice.call(arguments);\n return arrays.reduce(function (symDiff, arr) {\n return symDiff.concat(arr).filter(function (val, idx, theArr) {\n return theArr.indexOf(val) === idx \n && (symDiff.indexOf(val) === -1 || arr.indexOf(val) === -1);\n });\n });\n}\nsym([1, 2, 3], [5, 2, 1, 4]);\n" + ], + "tests": [ + { + "text": "sym([1, 2, 3], [5, 2, 1, 4]) should return [3, 4, 5].", + "testString": "assert.sameMembers(sym([1, 2, 3], [5, 2, 1, 4]), [3, 4, 5], 'sym([1, 2, 3], [5, 2, 1, 4]) should return [3, 4, 5].');" + }, + { + "text": "sym([1, 2, 3], [5, 2, 1, 4]) should contain only three elements.", + "testString": "assert.equal(sym([1, 2, 3], [5, 2, 1, 4]).length, 3, 'sym([1, 2, 3], [5, 2, 1, 4]) should contain only three elements.');" + }, + { + "text": "sym([1, 2, 3, 3], [5, 2, 1, 4]) should return [3, 4, 5].", + "testString": "assert.sameMembers(sym([1, 2, 3, 3], [5, 2, 1, 4]), [3, 4, 5], 'sym([1, 2, 3, 3], [5, 2, 1, 4]) should return [3, 4, 5].');" + }, + { + "text": "sym([1, 2, 3, 3], [5, 2, 1, 4]) should contain only three elements.", + "testString": "assert.equal(sym([1, 2, 3, 3], [5, 2, 1, 4]).length, 3, 'sym([1, 2, 3, 3], [5, 2, 1, 4]) should contain only three elements.');" + }, + { + "text": "sym([1, 2, 3], [5, 2, 1, 4, 5]) should return [3, 4, 5].", + "testString": "assert.sameMembers(sym([1, 2, 3], [5, 2, 1, 4, 5]), [3, 4, 5], 'sym([1, 2, 3], [5, 2, 1, 4, 5]) should return [3, 4, 5].');" + }, + { + "text": "sym([1, 2, 3], [5, 2, 1, 4, 5]) should contain only three elements.", + "testString": "assert.equal(sym([1, 2, 3], [5, 2, 1, 4, 5]).length, 3, 'sym([1, 2, 3], [5, 2, 1, 4, 5]) should contain only three elements.');" + }, + { + "text": "sym([1, 2, 5], [2, 3, 5], [3, 4, 5]) should return [1, 4, 5]", + "testString": "assert.sameMembers(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]), [1, 4, 5], 'sym([1, 2, 5], [2, 3, 5], [3, 4, 5]) should return [1, 4, 5]');" + }, + { + "text": "sym([1, 2, 5], [2, 3, 5], [3, 4, 5]) should contain only three elements.", + "testString": "assert.equal(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]).length, 3, 'sym([1, 2, 5], [2, 3, 5], [3, 4, 5]) should contain only three elements.');" + }, + { + "text": "sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]) should return [1, 4, 5].", + "testString": "assert.sameMembers(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]), [1, 4, 5], 'sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]) should return [1, 4, 5].');" + }, + { + "text": "sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]) should contain only three elements.", + "testString": "assert.equal(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]).length, 3, 'sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]) should contain only three elements.');" + }, + { + "text": "sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]) should return [2, 3, 4, 6, 7].", + "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], 'sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]) should return [2, 3, 4, 6, 7].');" + }, + { + "text": "sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]) should contain only five elements.", + "testString": "assert.equal(sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]).length, 5, 'sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]) should contain only five elements.');" + }, + { + "text": "sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1]) should return [1, 2, 4, 5, 6, 7, 8, 9].", + "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], 'sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1]) should return [1, 2, 4, 5, 6, 7, 8, 9].');" + }, + { + "text": "sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1]) should contain only eight elements.", + "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, 'sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3], [5, 3, 9, 8], [1]) should contain only eight elements.');" + } + ], + "type": "bonfire", + "MDNlinks": [ + "Array.prototype.reduce()", + "Symmetric Difference" + ], + "challengeType": 5, + "translations": { + "es": { + "title": "Diferencia Simétrica", + "description": [ + "Crea una función que acepte dos o más arreglos y que devuelva un arreglo conteniendo la diferenia simétrica entre ambos", + "En Matemáticas, el término 'diferencia simétrica' se refiere a los elementos en dos conjuntos que están en el primer conjunto o en el segundo, pero no en ambos.", + "Recuerda utilizar Read-Search-Ask si te sientes atascado. Intenta programar en pareja. Escribe tu propio código." + ] + }, + "it": { + "title": "Differenza Simmetrica", + "description": [ + "Crea una funzione che accetti due o più array e che ritorni un array contenente la differenza simmetrica ( o ) degli stessi.", + "Dati due insiemi (per esempio l'insieme A = {1, 2, 3} e l'insieme B = {2, 3, 4}, il termine matematico \"differenza simmetrica\" di due insiemi è l'insieme degli elementi che sono in almeno uno dei due insiemi, ma non in entrambi (A △ B = C = {1, 4}). Per ogni differenza simmetrica aggiuntiva che fai (per esempio su un insieme D = {2, 3}), devi prendere l'insieme degli elementi che sono in almeno uno dei due insiemi ma non in entrambi (C △ D = {1, 4} △ {2, 3} = {1, 2, 3, 4}).", + "Ricorda di usare Leggi-Cerca-Chiedi se rimani bloccato. Prova a programmare in coppia. Scrivi il codice da te." + ] + }, + "pt-br": { + "title": "Diferença Simétrica", + "description": [ + "Crie uma função que recebe duas ou mais matrizes e retorna a matriz diferença simétrica ( ou ) das matrizes fornecidas.", + "Dado dois conjuntos (por exemplo conjunto A = {1, 2, 3} e conjunto B = {2, 3, 4}), o termo matemático \"diferença simétrica\" dos dois cojuntos é o conjunto dos elementos que estão em um dos conjuntos, mas não nos dois (A △ B = C = {1, 4}). Para cada diferença simétrica adicional que você faz (digamos em um terceiro conjunto D = {2, 3}), voce deve retornar o conjunto no qual os elementos estão em um dos conjuntos mas não nos dois (C △ D = {1, 4} △ {2, 3} = {1, 2, 3, 4}). O conjunto final deve ter somentes valores únicos (sem números repetidos).", + "Lembre-se de usar Ler-Procurar-Perguntar se você ficar preso. Tente programar em par. Escreva seu próprio código." + ] + } + }, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function sym(args) {", + " return args;", + "}", + "", + "sym([1, 2, 3], [5, 2, 1, 4]);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "a56138aff60341a09ed6c480", + "title": "Inventory Update", + "description": [ + "Compare and update the inventory stored in a 2D array against a second 2D array of a fresh delivery. Update the current existing inventory item quantities (in arr1). If an item cannot be found, add the new item and quantity into the inventory array. The returned inventory array should be in alphabetical order by item.", + "Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code." + ], + "solutions": [ + "function updateInventory(arr1, arr2) {\n arr2.forEach(function(item) {\n createOrUpdate(arr1, item);\n });\n // All inventory must be accounted for or you're fired!\n return arr1;\n}\n\nfunction createOrUpdate(arr1, item) {\n var index = -1;\n while (++index < arr1.length) {\n if (arr1[index][1] === item[1]) {\n arr1[index][0] += item[0];\n return;\n }\n if (arr1[index][1] > item[1]) {\n break;\n }\n }\n arr1.splice(index, 0, item);\n}\n\n// Example inventory lists\nvar curInv = [\n [21, 'Bowling Ball'],\n [2, 'Dirty Sock'],\n [1, 'Hair Pin'],\n [5, 'Microphone']\n];\n\nvar newInv = [\n [2, 'Hair Pin'],\n [3, 'Half-Eaten Apple'],\n [67, 'Bowling Ball'],\n [7, 'Toothpaste']\n];\n\nupdateInventory(curInv, newInv);\n" + ], + "tests": [ + { + "text": "The function updateInventory should return an array.", + "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 updateInventory should return an array.');" + }, + { + "text": "updateInventory([[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], [[2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [67, \"Bowling Ball\"], [7, \"Toothpaste\"]]) should return an array with a length of 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, 'updateInventory([[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], [[2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [67, \"Bowling Ball\"], [7, \"Toothpaste\"]]) should return an array with a length of 6.');" + }, + { + "text": "updateInventory([[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], [[2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [67, \"Bowling Ball\"], [7, \"Toothpaste\"]]) should return [[88, \"Bowling Ball\"], [2, \"Dirty Sock\"], [3, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [5, \"Microphone\"], [7, \"Toothpaste\"]].", + "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\"]], 'updateInventory([[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], [[2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [67, \"Bowling Ball\"], [7, \"Toothpaste\"]]) should return [[88, \"Bowling Ball\"], [2, \"Dirty Sock\"], [3, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [5, \"Microphone\"], [7, \"Toothpaste\"]].');" + }, + { + "text": "updateInventory([[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], []) should return [[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]].", + "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\"]], 'updateInventory([[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]], []) should return [[21, \"Bowling Ball\"], [2, \"Dirty Sock\"], [1, \"Hair Pin\"], [5, \"Microphone\"]].');" + }, + { + "text": "updateInventory([], [[2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [67, \"Bowling Ball\"], [7, \"Toothpaste\"]]) should return [[67, \"Bowling Ball\"], [2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [7, \"Toothpaste\"]].", + "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\"]], 'updateInventory([], [[2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [67, \"Bowling Ball\"], [7, \"Toothpaste\"]]) should return [[67, \"Bowling Ball\"], [2, \"Hair Pin\"], [3, \"Half-Eaten Apple\"], [7, \"Toothpaste\"]].');" + }, + { + "text": "updateInventory([[0, \"Bowling Ball\"], [0, \"Dirty Sock\"], [0, \"Hair Pin\"], [0, \"Microphone\"]], [[1, \"Hair Pin\"], [1, \"Half-Eaten Apple\"], [1, \"Bowling Ball\"], [1, \"Toothpaste\"]]) should return [[1, \"Bowling Ball\"], [0, \"Dirty Sock\"], [1, \"Hair Pin\"], [1, \"Half-Eaten Apple\"], [0, \"Microphone\"], [1, \"Toothpaste\"]].", + "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\"]], 'updateInventory([[0, \"Bowling Ball\"], [0, \"Dirty Sock\"], [0, \"Hair Pin\"], [0, \"Microphone\"]], [[1, \"Hair Pin\"], [1, \"Half-Eaten Apple\"], [1, \"Bowling Ball\"], [1, \"Toothpaste\"]]) should return [[1, \"Bowling Ball\"], [0, \"Dirty Sock\"], [1, \"Hair Pin\"], [1, \"Half-Eaten Apple\"], [0, \"Microphone\"], [1, \"Toothpaste\"]].');" + } + ], + "type": "bonfire", + "MDNlinks": [ + "Global Array Object" + ], + "challengeType": 5, + "translations": { + "es": { + "title": "Actualizando el Inventario", + "description": [ + "Compara y actualiza el inventario actual, almacenado en un arreglo bidimensional, contra otro arreglo bidimensional de inventario nuevo. Actualiza las cantidades en el inventario actual y, en caso de recibir una nueva mercancía, añade su nombre y la cantidad recibida al arreglo del inventario en orden alfabético.", + "Recuerda utilizar Read-Search-Ask si te sientes atascado. Intenta programar en pareja. Escribe tu propio código." + ] + }, + "it": { + "title": "Aggiornamento dell'Inventario", + "description": [ + "Confronta e aggiorna l'inventario, contenuto in un array bidimensionale, con un secondo array bidimensionale relativo ad una nuova consegna. Aggiorna le quantità disponibili in inventario (dentro arr1). Se uno degli articoli non è presente nell'inventario, aggiungi allo stesso il nuovo articolo e la sua quantità. Ritorna un array con l'inventario aggiornato, che deve essere ordinato alfabeticamente per articolo.", + "Ricorda di usare Leggi-Cerca-Chiedi se rimani bloccato. Prova a programmare in coppia. Scrivi il codice da te." + ] + }, + "pt-br": { + "title": "Atualizando Inventário", + "description": [ + "Compare e atualize o inventário armazenado em um matriz 2D contra uma segunda matriz 2D de uma entrega recente. Atualize a quantidade de itens no inventário atual (em arr1). Se um item não pode ser encontrado, adicione um novo item e a sua quantidade na matriz do inventário. O inventário retornado deve estar em ordem alfabética por item.", + "Lembre-se de usar Ler-Procurar-Perguntar se você ficar preso. Tente programar em par. Escreva seu próprio código." + ] + } + }, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "a7bf700cd123b9a54eef01d5", + "title": "No Repeats Please", + "description": [ + "Return the number of total permutations of the provided string that don't have repeated consecutive letters. Assume that all characters in the provided string are each unique.", + "For example, aab should return 2 because it has 6 total permutations (aab, aab, aba, aba, baa, baa), but only 2 of them (aba and aba) don't have the same letter (in this case a) repeating.", + "Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code." + ], + "solutions": [ + "function permAlone(str) {\n return permutor(str).filter(function(perm) {\n return !perm.match(/(.)\\1/g);\n }).length;\n}\n\nfunction permutor(str) {\n // http://staff.roguecc.edu/JMiller/JavaScript/permute.html\n //permArr: Global array which holds the list of permutations\n //usedChars: Global utility array which holds a list of \"currently-in-use\" characters\n var permArr = [], usedChars = [];\n function permute(input) {\n //convert input into a char array (one element for each character)\n var i, ch, chars = input.split(\"\");\n for (i = 0; i < chars.length; i++) {\n //get and remove character at index \"i\" from char array\n ch = chars.splice(i, 1);\n //add removed character to the end of used characters\n usedChars.push(ch);\n //when there are no more characters left in char array to add, add used chars to list of permutations\n if (chars.length === 0) permArr[permArr.length] = usedChars.join(\"\");\n //send characters (minus the removed one from above) from char array to be permuted\n permute(chars.join(\"\"));\n //add removed character back into char array in original position\n chars.splice(i, 0, ch);\n //remove the last character used off the end of used characters array\n usedChars.pop();\n }\n }\n permute(str);\n return permArr;\n}\n\npermAlone('aab');\n" + ], + "tests": [ + { + "text": "permAlone(\"aab\") should return a number.", + "testString": "assert.isNumber(permAlone('aab'), 'permAlone(\"aab\") should return a number.');" + }, + { + "text": "permAlone(\"aab\") should return 2.", + "testString": "assert.strictEqual(permAlone('aab'), 2, 'permAlone(\"aab\") should return 2.');" + }, + { + "text": "permAlone(\"aaa\") should return 0.", + "testString": "assert.strictEqual(permAlone('aaa'), 0, 'permAlone(\"aaa\") should return 0.');" + }, + { + "text": "permAlone(\"aabb\") should return 8.", + "testString": "assert.strictEqual(permAlone('aabb'), 8, 'permAlone(\"aabb\") should return 8.');" + }, + { + "text": "permAlone(\"abcdefa\") should return 3600.", + "testString": "assert.strictEqual(permAlone('abcdefa'), 3600, 'permAlone(\"abcdefa\") should return 3600.');" + }, + { + "text": "permAlone(\"abfdefa\") should return 2640.", + "testString": "assert.strictEqual(permAlone('abfdefa'), 2640, 'permAlone(\"abfdefa\") should return 2640.');" + }, + { + "text": "permAlone(\"zzzzzzzz\") should return 0.", + "testString": "assert.strictEqual(permAlone('zzzzzzzz'), 0, 'permAlone(\"zzzzzzzz\") should return 0.');" + }, + { + "text": "permAlone(\"a\") should return 1.", + "testString": "assert.strictEqual(permAlone('a'), 1, 'permAlone(\"a\") should return 1.');" + }, + { + "text": "permAlone(\"aaab\") should return 0.", + "testString": "assert.strictEqual(permAlone('aaab'), 0, 'permAlone(\"aaab\") should return 0.');" + }, + { + "text": "permAlone(\"aaabb\") should return 12.", + "testString": "assert.strictEqual(permAlone('aaabb'), 12, 'permAlone(\"aaabb\") should return 12.');" + } + ], + "type": "bonfire", + "MDNlinks": [ + "Permutations", + "RegExp" + ], + "challengeType": 5, + "translations": { + "es": { + "title": "Sin Repeticiones, por Favor", + "description": [ + "Crea una función que devuelva el número total de permutaciones de las letras en la cadena de texto provista, en las cuales no haya letras consecutivas repetidas", + "Por ejemplo, 'aab' debe retornar 2 porque, del total de 6 permutaciones posibles, solo 2 de ellas no tienen repetida la misma letra (en este caso 'a').", + "Recuerda utilizar Read-Search-Ask si te sientes atascado. Intenta programar en pareja. Escribe tu propio código." + ] + }, + "it": { + "title": "Niente Ripetizioni, per Favore", + "description": [ + "Ritorna il numero totale di permutazioni della stringa passata che non hanno lettere consecutive riptetute. Assumi che tutti i caratteri nella stringa passata siano unici.", + "Per esempio, aab deve ritornare 2, perchè la stringa ha 6 permutazioni possibili in totale (aab, aab, aba, aba, baa, baa), ma solo 2 di loro (aba e aba) non contengono la stessa lettera (in questo caso a ripetuta).", + "Ricorda di usare Leggi-Cerca-Chiedi se rimani bloccato. Prova a programmare in coppia. Scrivi il codice da te." + ] + }, + "pt-br": { + "title": "Sem repetição, por favor", + "description": [ + "Retorne o número total de permutações da string fornecida que não tem letras consecutivas repetidas. Assuma que todos os caracteres na string fornecida são únicos.", + "Por exemplo, aab deve retornar 2 porque tem um total de 6 permutações (aab, aab, aba, aba, baa, baa), mas somente duas delas (aba and aba) não tem a mesma letra (nesse caso a) se repetindo.", + "Lembre-se de usar Ler-Procurar-Perguntar se você ficar preso. Tente programar em par. Escreva seu próprio código." + ] + } + }, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function permAlone(str) {", + " return str;", + "}", + "", + "permAlone('aab');" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "a3f503de51cfab748ff001aa", + "title": "Pairwise", + "description": [ + "Given an array arr, find element pairs whose sum equal the second argument arg and return the sum of their indices.", + "You may use multiple pairs that have the same numeric elements but different indices. Each pair should use the lowest possible available indices. Once an element has been used it cannot be reused to pair with another element.", + "For example pairwise([7, 9, 11, 13, 15], 20) returns 6. The pairs that sum to 20 are [7, 13] and [9, 11]. We can then write out the array with their indices and values.", + "
Index01234
Value79111315
", + "Below we'll take their corresponding indices and add them.", + "7 + 13 = 20 → Indices 0 + 3 = 3
9 + 11 = 20 → Indices 1 + 2 = 3
3 + 3 = 6 → Return 6", + "Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code." + ], + "solutions": [ + "function pairwise(arr, arg) {\n var sum = 0;\n arr.forEach(function(e, i, a) {\n if (e != null) { \n var diff = arg-e;\n a[i] = null;\n var dix = a.indexOf(diff);\n if (dix !== -1) {\n sum += dix;\n sum += i;\n a[dix] = null;\n } \n }\n });\n return sum;\n}\n\npairwise([1,4,2,3,0,5], 7);\n" + ], + "tests": [ + { + "text": "pairwise([1, 4, 2, 3, 0, 5], 7) should return 11.", + "testString": "assert.deepEqual(pairwise([1, 4, 2, 3, 0, 5], 7), 11, 'pairwise([1, 4, 2, 3, 0, 5], 7) should return 11.');" + }, + { + "text": "pairwise([1, 3, 2, 4], 4) should return 1.", + "testString": "assert.deepEqual(pairwise([1, 3, 2, 4], 4), 1, 'pairwise([1, 3, 2, 4], 4) should return 1.');" + }, + { + "text": "pairwise([1, 1, 1], 2) should return 1.", + "testString": "assert.deepEqual(pairwise([1, 1, 1], 2), 1, 'pairwise([1, 1, 1], 2) should return 1.');" + }, + { + "text": "pairwise([0, 0, 0, 0, 1, 1], 1) should return 10.", + "testString": "assert.deepEqual(pairwise([0, 0, 0, 0, 1, 1], 1), 10, 'pairwise([0, 0, 0, 0, 1, 1], 1) should return 10.');" + }, + { + "text": "pairwise([], 100) should return 0.", + "testString": "assert.deepEqual(pairwise([], 100), 0, 'pairwise([], 100) should return 0.');" + } + ], + "type": "bonfire", + "MDNlinks": [ + "Array.prototype.reduce()" + ], + "challengeType": 5, + "translations": { + "es": { + "title": "En Parejas", + "description": [ + "Crea una función que devuelva la suma de todos los índices de los elementos de 'arr' que pueden ser emparejados con otro elemento de tal forma que la suma de ambos equivalga al valor del segundo argumento, 'arg'. Si varias combinaciones son posibles, devuelve la menor suma de índices. Una vez un elemento ha sido usado, no puede ser usado de nuevo para emparejarlo con otro elemento.", + "Por ejemplo, pairwise([1, 4, 2, 3, 0, 5], 7) debe devolver 11 porque 4, 2, 3 y 5 pueden ser emparejados para obtener una suma de 7", + "pairwise([1, 3, 2, 4], 4) devolvería el valor de 1, porque solo los primeros dos elementos pueden ser emparejados para sumar 4. ¡Recuerda que el primer elemento tiene un índice de 0!", + "Recuerda utilizar Read-Search-Ask si te sientes atascado. Intenta programar en pareja. Escribe tu propio código." + ] + }, + "it": { + "title": "A Coppie", + "description": [ + "Dato un array arr, trova le coppie di elementi la cui somma è uguale al secondo argomento passato arg. Ritorna quindi la somma dei loro indici.", + "Se ci sono più coppie possibili che hanno lo stesso valore numerico ma indici differenti, ritorna la somma degli indici minore. Una volta usato un elemento, lo stesso non può essere riutilizzato per essere accoppiato con un altro.", + "Per esempio pairwise([7, 9, 11, 13, 15], 20) ritorna 6. Le coppia la cui somma è 20 sono [7, 13] e [9, 11]. Possiamo quindi osservare l'array con i loro indici e valori.", + "
Indice01234
Valore79111315
", + "Qui sotto prendiamo gli indici corrispondenti e li sommiamo.", + "7 + 13 = 20 → Indici 0 + 3 = 3
9 + 11 = 20 → Indici 1 + 2 = 3
3 + 3 = 6 → Ritorna 6", + "Ricorda di usare Leggi-Cerca-Chiedi se rimani bloccato. Prova a programmare in coppia. Scrivi il codice da te." + ] + }, + "pt-br": { + "title": "Emparelhados", + "description": [ + "Dado uma matriz arr, encontre pares de elementos no qual a soma é igual ao segundo argumento arg e retorne a soma dos seus indices.", + "Se multiplos pares tem o mesmo elemento numérico mas indices diferentes, retorne a soma dos menores indices. Uma vez que um elemento é usado, este não pode ser emparelhado novamente com outro elemento.", + "Por exemplo pairwise([7, 9, 11, 13, 15], 20) retorna 6. Os pares que somam 20 são [7, 13] e [9, 11]. Nós podemos então criar a matriz com seus indices e valores.", + "
Index01234
Value79111315
", + "Abaixo nós pegamos os índices correspondentes e somá-los.", + "7 + 13 = 20 → Indices 0 + 3 = 3
9 + 11 = 20 → Indices 1 + 2 = 3
3 + 3 = 6 → Retorna 6", + "Lembre-se de usar Ler-Procurar-Perguntar se você ficar preso. Tente programar em par. Escreva seu próprio código." + ] + } + }, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function pairwise(arr, arg) {", + " return arg;", + "}", + "", + "pairwise([1,4,2,3,0,5], 7);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "8d5123c8c441eddfaeb5bdef", + "title": "Implement Bubble Sort", + "description": [ + "This is the first of several challenges on sorting algorithms. Given an array of unsorted items, we want to be able to return a sorted array. We will see several different methods to do this and learn some tradeoffs between these different approaches. While most modern languages have built-in sorting methods for operations like this, it is still important to understand some of the common basic approaches and learn how they can be implemented.", + "Here we will see bubble sort. The bubble sort method starts at the beginning of an unsorted array and 'bubbles up' unsorted values towards the end, iterating through the array until it is completely sorted. It does this by comparing adjacent items and swapping them if they are out of order. The method continues looping through the array until no swaps occur at which point the array is sorted.", + "This method requires multiple iterations through the array and for average and worst cases has quadratic time complexity. While simple, it is usually impractical in most situations.", + "Instructions: Write a function bubbleSort which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest.", + "Note:
We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging array to see your sorting alogrithm in action!" + ], + "tests": [ + { + "text": "bubbleSort is a function.", + "testString": "assert(typeof bubbleSort == 'function', 'bubbleSort is a function.');" + }, + { + "text": "bubbleSort returns a sorted array (least to greatest).", + "testString": "assert(isSorted(bubbleSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92])), 'bubbleSort returns a sorted array (least to greatest).');" + }, + { + "text": "bubbleSort returns an array that is unchanged except for order.", + "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], 'bubbleSort returns an array that is unchanged except for order.');" + }, + { + "text": "bubbleSort should not use the built-in .sort() method.", + "testString": "assert.strictEqual(code.search(/\\.sort\\(/), -1, 'bubbleSort should not use the built-in .sort() method.');" + } + ], + "type": "waypoint", + "solutions": [], + "challengeType": 1, + "translations": {}, + "releasedOn": "February 17, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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]" + ], + "head": "", + "tail": "function isSorted(arr) {\n var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);\n return check(0);\n};" + } + } + }, + { + "id": "587d8259367417b2b2512c85", + "title": "Implement Selection Sort", + "description": [ + "Here we will implement selection sort. Selection sort works by selecting the minimum value in a list and swapping it with the first value in the list. It then starts at the second position, selects the smallest value in the remaining list, and swaps it with the second element. It continues iterating through the list and swapping elements until it reaches the end of the list. Now the list is sorted. Selection sort has quadratic time complexity in all cases.", + "Instructions: Write a function selectionSort which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest.", + "Note:
We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging array to see your sorting alogrithm in action!" + ], + "tests": [ + { + "text": "selectionSort is a function.", + "testString": "assert(typeof selectionSort == 'function', 'selectionSort is a function.');" + }, + { + "text": "selectionSort returns a sorted array (least to greatest).", + "testString": "assert(isSorted(selectionSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92])), 'selectionSort returns a sorted array (least to greatest).');" + }, + { + "text": "selectionSort returns an array that is unchanged except for order.", + "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], 'selectionSort returns an array that is unchanged except for order.');" + }, + { + "text": "selectionSort should not use the built-in .sort() method.", + "testString": "assert.strictEqual(code.search(/\\.sort\\(/), -1, 'selectionSort should not use the built-in .sort() method.');" + } + ], + "type": "waypoint", + "solutions": [], + "challengeType": 1, + "translations": {}, + "releasedOn": "February 17, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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]" + ], + "head": "", + "tail": "function isSorted(arr) {\n var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);\n return check(0);\n};" + } + } + }, + { + "id": "587d8259367417b2b2512c86", + "title": "Implement Insertion Sort", + "description": [ + "The next sorting method we'll look at is insertion sort. This method works by building up a sorted array at the beginning of the list. It begins the sorted array with the first element. Then it inspects the next element and swaps it backwards into the sorted array until it is in sorted position. It continues iterating through the list and swapping new items backwards into the sorted portion until it reaches the end. This algorithm has quadratic time complexity in the average and worst cases.", + "Instructions: Write a function insertionSort which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest.", + "Note:
We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging array to see your sorting alogrithm in action!" + ], + "tests": [ + { + "text": "insertionSort is a function.", + "testString": "assert(typeof insertionSort == 'function', 'insertionSort is a function.');" + }, + { + "text": "insertionSort returns a sorted array (least to greatest).", + "testString": "assert(isSorted(insertionSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92])), 'insertionSort returns a sorted array (least to greatest).');" + }, + { + "text": "insertionSort returns an array that is unchanged except for order.", + "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], 'insertionSort returns an array that is unchanged except for order.');" + }, + { + "text": "insertionSort should not use the built-in .sort() method.", + "testString": "assert.strictEqual(code.search(/\\.sort\\(/), -1, 'insertionSort should not use the built-in .sort() method.');" + } + ], + "type": "waypoint", + "solutions": [], + "challengeType": 1, + "translations": {}, + "releasedOn": "February 17, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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]" + ], + "head": "", + "tail": "function isSorted(arr) {\n var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);\n return check(0);\n};" + } + } + }, + { + "id": "587d825a367417b2b2512c89", + "title": "Implement Quick Sort", + "description": [ + "Here we will move on to an intermediate sorting algorithm: quick sort. Quick sort is an efficient, recursive divide-and-conquer approach to sorting an array. In this method, a pivot value is chosen in the original array. The array is then partitioned into two subarrays of values less than and greater than the pivot value. We then combine the result of recursively calling the quick sort algorithm on both sub-arrays. This continues until the base case of an empty or single-item array is reached, which we return. The unwinding of the recursive calls return us the sorted array.", + "Quick sort is a very efficient sorting method, providing O(nlog(n)) performance on average. It is also relatively easy to implement. These attributes make it a popular and useful sorting method.", + "Instructions: Write a function quickSort which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest. While the choice of the pivot value is important, any pivot will do for our purposes here. For simplicity, the first or last element could be used.", + "Note:
We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging array to see your sorting alogrithm in action!" + ], + "tests": [ + { + "text": "quickSort is a function.", + "testString": "assert(typeof quickSort == 'function', 'quickSort is a function.');" + }, + { + "text": "quickSort returns a sorted array (least to greatest).", + "testString": "assert(isSorted(quickSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92])), 'quickSort returns a sorted array (least to greatest).');" + }, + { + "text": "quickSort returns an array that is unchanged except for order.", + "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], 'quickSort returns an array that is unchanged except for order.');" + }, + { + "text": "quickSort should not use the built-in .sort() method.", + "testString": "assert.strictEqual(code.search(/\\.sort\\(/), -1, 'quickSort should not use the built-in .sort() method.');" + } + ], + "type": "waypoint", + "solutions": [], + "challengeType": 1, + "translations": {}, + "releasedOn": "February 17, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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]" + ], + "head": "", + "tail": "function isSorted(arr) {\n var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);\n return check(0);\n};" + } + } + }, + { + "id": "587d825c367417b2b2512c8f", + "title": "Implement Merge Sort", + "description": [ + "Another intermediate sorting algorithm that is very common is merge sort. Like quick sort, merge sort also uses a divide-and-conquer, recursive methodology to sort an array. It takes advantage of the fact that it is relatively easy to sort two arrays as long as each is sorted in the first place. But we'll start with only one array as input, so how do we get to two sorted arrays from that? Well, we can recursively divide the original input in two until we reach the base case of an array with one item. A single-item array is naturally sorted, so then we can start combining. This combination will unwind the recursive calls that split the original array, eventually producing a final sorted array of all the elements. The steps of merge sort, then, are:", + "1) Recursively split the input array in half until a sub-array with only one element is produced.", + "2) Merge each sorted sub-array together to produce the final sorted array.", + "Merge sort is an efficient sorting method, with time complexity of O(nlog(n)). This algorithm is popular because it is performant and relatively easy to implement.", + "As an aside, this will be the last sorting algorithm we cover here. However, later in the section on tree data structures we will describe heap sort, another efficient sorting method that requires a binary heap in its implementation.", + "Instructions: Write a function mergeSort which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest. A good way to implement this is to write one function, for instance merge, which is responsible for merging two sorted arrays, and another function, for instance mergeSort, which is responsible for the recursion that produces single-item arrays to feed into merge. Good luck!", + "Note:
We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging array to see your sorting alogrithm in action!" + ], + "tests": [ + { + "text": "mergeSort is a function.", + "testString": "assert(typeof mergeSort == 'function', 'mergeSort is a function.');" + }, + { + "text": "mergeSort returns a sorted array (least to greatest).", + "testString": "assert(isSorted(mergeSort([1,4,2,8,345,123,43,32,5643,63,123,43,2,55,1,234,92])), 'mergeSort returns a sorted array (least to greatest).');" + }, + { + "text": "mergeSort returns an array that is unchanged except for order.", + "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], 'mergeSort returns an array that is unchanged except for order.');" + }, + { + "text": "mergeSort should not use the built-in .sort() method.", + "testString": "assert.strictEqual(code.search(/\\.sort\\(/), -1, 'mergeSort should not use the built-in .sort() method.');" + } + ], + "type": "waypoint", + "solutions": [], + "challengeType": 1, + "translations": {}, + "releasedOn": "February 17, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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]" + ], + "head": "", + "tail": "function isSorted(arr) {\n var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);\n return check(0);\n};" + } + } + } + ], + "fileName": "08-coding-interview-questions-and-take-home-assignments/coding-interview-algorithm-questions.json", + "superBlock": "coding-interview-questions-and-take-home-assignments", + "superOrder": 8 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/08-coding-interview-prep/data-structures.json b/packages/learn/seed/challenges/08-coding-interview-prep/data-structures.json new file mode 100644 index 0000000000..c61a5221af --- /dev/null +++ b/packages/learn/seed/challenges/08-coding-interview-prep/data-structures.json @@ -0,0 +1,3308 @@ +{ + "name": "Data Structures", + "order": 2, + "time": "", + "helpRoom": "HelpJavaScript", + "challenges": [ + { + "id": "587d8253367417b2b2512c6a", + "title": "Typed Arrays", + "description": [ + "Arrays are JavaScript objects that can hold a lot of different elements.", + "var complexArr = [1, 5, \"2\", \"Word\", {\"name\": \"James\"}];", + "Basically what happens in the background is that your browser will automatically give the right amount of memory space for that array. It will also change as needed if you add or remove data.", + "However, in the world of high performance and different element types, sometimes you need to be more specific on how much memory is given to an array.", + "Typed arrays are the answer to this problem. You are now able to say how much memory you want to give an array. Below is a basic overview of the different types of arrays available and the size in bytes for each element in that array.", + "
TypeEach element size in bytes
Int8Array1
Uint8Array1
Uint8ClampedArray1
Int16Array2
Uint16Array2
Int32Array4
Uint32Array4
Float32Array4
Float64Array8
", + "There are two ways in creating these kind of arrays. One way is to create it directly. Below is how to create a 3 length Int16Array.", + "
var i8 = new Int16Array(3);
console.log(i8);
// Returns [0, 0, 0]
", + "You can also create a buffer to assign how much data (in bytes) you want the array to take up.", + "Note
To create typed arrays using buffers, you need to assign the number of bytes to be a multiple of the bytes listed above.", + "
// Create same Int16Array array differently
var byteSize = 6; // Needs to be multiple of 2
var buffer = new ArrayBuffer(byteSize);
var i8View = new Int16Array(buffer);
buffer.byteLength; // Returns 6
i8View.byteLength; // Returns 6
console.log(i8View); // Returns [0, 0, 0]
", + "Buffers are general purpose objects that just carry data. You cannot access them normally. To access them, you need to first create a view.", + "
i8View[0] = 42;
console.log(i8View); // Returns [42, 0, 0]
", + "Note
Typed arrays do not have some of the methods traditional arrays have such as .pop() or .push(). Typed arrays also fail Array.isArray() that checks if something is an array. Although simpler, this can be an advantage for less-sophisticated JavaScript engines to implement them.", + "
", + "First create a buffer that is 64-bytes. Then create a Int32Array typed array with a view of it called i32View." + ], + "tests": [ + { + "text": "Your buffer should be 64 bytes large.", + "testString": "assert(buffer.byteLength === 64, 'Your buffer should be 64 bytes large.');" + }, + { + "text": "Your i32View view of your buffer should be 64 bytes large.", + "testString": "assert(i32View.byteLength === 64, 'Your i32View view of your buffer should be 64 bytes large.');" + }, + { + "text": "Your i32View view of your buffer should be 16 elements long.", + "testString": "assert(i32View.length === 16, 'Your i32View view of your buffer should be 16 elements long.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "var buffer = new ArrayBuffer(64);\nvar i32View = new Int32Array(buffer);" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "var buffer;", + "var i32View;" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8250367417b2b2512c5e", + "title": "Learn how a Stack Works", + "description": [ + "You are probably familiar with stack of books on your table. You have likely used the undo feature of a text editor. You are also probably used to hitting the back button on your phone to go back to the previous view in your app.", + "You know what they all have in common? They all store the data in a way so that you can traverse backwards.", + "The topmost book in the stack was the one that was put there last. If you remove that book from your stack's top, you would expose the book that was put there before the last book and so on.", + "If you think about it, in all the above examples, you are getting Last-In-First-Out type of service. We will try to mimic this with our code.", + "This data storage scheme is called a Stack. In particular, we would have to implement the push() method that pushes JavaScript objects at the top of the stack; and pop() method, that removes the JavaScript object that's at the top of the stack at the current moment.", + "
", + "Here we have a stack of homework assignments represented as an array: \"BIO12\" is at the base, and \"PSY44\" is at the top of the stack.", + "Modify the given array and treat it like a stack using the JavaScript methods mentioned above. Remove the top element \"PSY44\" from the stack. Then add \"CS50\" to be the new top element of the stack." + ], + "tests": [ + { + "text": "homeworkStack should only contain 4 elements.", + "testString": "assert(homeworkStack.length === 4, 'homeworkStack should only contain 4 elements.');" + }, + { + "text": "The last element in homeworkStack should be \"CS50\".", + "testString": "assert(homeworkStack[3] === 'CS50', 'The last element in homeworkStack should be \"CS50\".');" + }, + { + "text": "homeworkStack should not contain \"PSY44\".", + "testString": "assert(homeworkStack.indexOf('PSY44') === -1, 'homeworkStack should not contain \"PSY44\".');" + }, + { + "text": "The initial declaration of the homeworkStack should not be changed.", + "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 homeworkStack should not be changed.');" + } + ], + "solutions": [], + "hints": [], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "var homeworkStack = [\"BIO12\",\"HIS80\",\"MAT122\",\"PSY44\"];", + "// Only change code below this line", + "" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8250367417b2b2512c5f", + "title": "Create a Stack Class", + "description": [ + "In the last section, we talked about what a stack is and how we can use an array to represent a stack. In this section, we will be creating our own stack class.", + "Although you can use arrays to create stacks, sometimes it is best to limit the amount of control we have with our stacks.", + "Apart from the push and pop method, stacks have other useful methods. Let's add a peek, isEmpty, and clear method to our stack class.", + "Instructions", + "Write a push method that pushes an element to the top of the stack, a pop method that removes the element on the top of the stack, a peek method that looks at the first element in the stack, an isEmpty method that checks if the stack is empty, and a clear method that removes all elements from the stack.", + "Normally stacks don't have this, but we've added a print helper method that console logs the collection." + ], + "tests": [ + { + "text": "Your Stack class should have a push method.", + "testString": "assert((function(){var test = new Stack(); return (typeof test.push === 'function')}()), 'Your Stack class should have a push method.');" + }, + { + "text": "Your Stack class should have a pop method.", + "testString": "assert((function(){var test = new Stack(); return (typeof test.pop === 'function')}()), 'Your Stack class should have a pop method.');" + }, + { + "text": "Your Stack class should have a peek method.", + "testString": "assert((function(){var test = new Stack(); return (typeof test.peek === 'function')}()), 'Your Stack class should have a peek method.');" + }, + { + "text": "Your Stack class should have a isEmpty method.", + "testString": "assert((function(){var test = new Stack(); return (typeof test.isEmpty === 'function')}()), 'Your Stack class should have a isEmpty method.');" + }, + { + "text": "Your Stack class should have a clear method.", + "testString": "assert((function(){var test = new Stack(); return (typeof test.clear === 'function')}()), 'Your Stack class should have a clear method.');" + }, + { + "text": "The peek method should return the top element of the stack", + "testString": "assert((function(){var test = new Stack(); test.push('CS50'); return (test.peek() === 'CS50')}()), 'The peek method should return the top element of the stack');" + }, + { + "text": "The pop method should remove and return the top element of the stack", + "testString": "assert((function(){var test = new Stack(); test.push('CS50'); return (test.pop() === 'CS50');}()), 'The pop method should remove and return the top element of the stack');" + }, + { + "text": "The isEmpty method should return true if a stack does not contain any elements", + "testString": "assert((function(){var test = new Stack(); return test.isEmpty()}()), 'The isEmpty method should return true if a stack does not contain any elements');" + }, + { + "text": "The clear method should remove all element from the stack", + "testString": "assert((function(){var test = new Stack(); test.push('CS50'); test.clear(); return (test.isEmpty())}()), 'The clear method should remove all element from the stack');" + } + ], + "solutions": [], + "hints": [], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function Stack() { ", + " collection = [];", + " this.print = function() {", + " console.log(collection);", + " };", + " // Only change code below this line", + "", + " // Only change code above this line", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8250367417b2b2512c60", + "title": "Create a Queue Class", + "description": [ + "Like stacks, queues are a collection of elements. But unlike stacks, queues follow the FIFO (First-In First-Out) principle. Elements added to a queue are pushed to the tail, or the end, of the queue, and only the element at the front of the queue is allowed to be removed.", + "We could use an array to represent a queue, but just like stacks, we want to limit the amount of control we have over our queues.", + "The two main methods of a queue class is the enqueue and the dequeue method. The enqueue method pushes an element to the tail of the queue, and the dequeue method removes and returns the element at the front of the queue. Other useful methods are the front, size, and isEmpty methods.", + "Instructions", + "Write an enqueue method that pushes an element to the tail of the queue, a dequeue method that removes and returns the front element, a front method that lets us see the front element, a size method that shows the length, and an isEmpty method to check if the queue is empty." + ], + "tests": [ + { + "text": "Your Queue class should have a enqueue method.", + "testString": "assert((function(){var test = new Queue(); return (typeof test.enqueue === 'function')}()), 'Your Queue class should have a enqueue method.');" + }, + { + "text": "Your Queue class should have a dequeue method.", + "testString": "assert((function(){var test = new Queue(); return (typeof test.dequeue === 'function')}()), 'Your Queue class should have a dequeue method.');" + }, + { + "text": "Your Queue class should have a front method.", + "testString": "assert((function(){var test = new Queue(); return (typeof test.front === 'function')}()), 'Your Queue class should have a front method.');" + }, + { + "text": "Your Queue class should have a size method.", + "testString": "assert((function(){var test = new Queue(); return (typeof test.size === 'function')}()), 'Your Queue class should have a size method.');" + }, + { + "text": "Your Queue class should have an isEmpty method.", + "testString": "assert((function(){var test = new Queue(); return (typeof test.isEmpty === 'function')}()), 'Your Queue class should have an isEmpty method.');" + }, + { + "text": "The dequeue method should remove and return the front element of the queue", + "testString": "assert((function(){var test = new Queue(); test.enqueue('Smith'); return (test.dequeue() === 'Smith')}()), 'The dequeue method should remove and return the front element of the queue');" + }, + { + "text": "The front method should return value of the front element of the queue", + "testString": "assert((function(){var test = new Queue(); test.enqueue('Smith'); test.enqueue('John'); return (test.front() === 'Smith')}()), 'The front method should return value of the front element of the queue');" + }, + { + "text": "The size method should return the length of the queue", + "testString": "assert((function(){var test = new Queue(); test.enqueue('Smith'); return (test.size() === 1)}()), 'The size method should return the length of the queue');" + }, + { + "text": "The isEmpty method should return false if there are elements in the queue", + "testString": "assert((function(){var test = new Queue(); test.enqueue('Smith'); return !(test.isEmpty())}()), 'The isEmpty method should return false if there are elements in the queue');" + } + ], + "solutions": [], + "hints": [], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function Queue () { ", + " collection = [];", + " this.print = function() {", + " console.log(collection);", + " };", + " // Only change code below this line", + "", + " // Only change code above this line", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8255367417b2b2512c74", + "title": "Create a Priority Queue Class", + "description": [ + "In this challenge you will be creating a Priority Queue. A Priority Queue is a special type of Queue in which items may have additional information which specifies their priority. This could be simply represented with an integer. Item priority will override placement order in determining the sequence items are dequeued. If an item with a higher priority is enqueued after items with lower priority, the higher priority item will be dequeued before all the others.", + "For instance, let’s imagine we have a priority queue with three items:", + "[[’kitten’, 2], [‘dog’, 2], [‘rabbit’, 2]]", + "Here the second value (an integer) represents item priority. If we enqueue [‘human’, 1] with a priority of 1 (assuming lower priorities are given precedence) it would then be the first item to be dequeued. The collection would like this:", + "[[‘human’, 1], [’kitten’, 2], [‘dog’, 2], [‘rabbit’, 2]].", + "We’ve started writing a PriorityQueue in the code editor. You will need to add an enqueue method for adding items with a priority, a dequeue method for removing items, a size method to return the number of items in the queue, a front method to return the element at the front of the queue, and finally an isEmpty method that will return true if the queue is empty or false if it is not.", + "The enqueue should accept items with the format shown above (['human', 1]) where 1 represents the priority. The dequeue should return only the current item, not its priority." + ], + "tests": [ + { + "text": "Your Queue class should have a enqueue method.", + "testString": "assert((function(){var test = new PriorityQueue(); return (typeof test.enqueue === 'function')}()), 'Your Queue class should have a enqueue method.');" + }, + { + "text": "Your Queue class should have a dequeue method.", + "testString": "assert((function(){var test = new PriorityQueue(); return (typeof test.dequeue === 'function')}()), 'Your Queue class should have a dequeue method.');" + }, + { + "text": "Your Queue class should have a size method.", + "testString": "assert((function(){var test = new PriorityQueue(); return (typeof test.size === 'function')}()), 'Your Queue class should have a size method.');" + }, + { + "text": "Your Queue class should have an isEmpty method.", + "testString": "assert((function(){var test = new PriorityQueue(); return (typeof test.isEmpty === 'function')}()), 'Your Queue class should have an isEmpty method.');" + }, + { + "text": "Your PriorityQueue should correctly keep track of the current number of items using the size method as items are enqueued and dequeued.", + "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 size method as items are enqueued and dequeued.');" + }, + { + "text": "The isEmpty method should return true when the queue is empty.", + "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 isEmpty method should return true when the queue is empty.');" + }, + { + "text": "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.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "function PriorityQueue () { \n this.collection = []; \n this.printCollection = function(){ \n console.log(this.collection); \n }; \n this.size = function() { \n return this.collection.length; \n }; \n this.isEmpty = function() { \n return this.size() > 0 ? false : true; \n }; \n this.enqueue = function (newitem) {\n if (this.isEmpty()) {\n return this.collection.push(newitem);\n }\n\n this.collection = this.collection.reverse();\n var found_index = this.collection.findIndex(function (item) {\n return newitem[1] >= item[1];\n });\n if (found_index === -1) {\n this.collection.push(newitem);\n } else {\n this.collection.splice(found_index, 0, newitem);\n }\n this.collection = this.collection.reverse();\n}; \n this.dequeue = function() { \n if (!this.isEmpty()) { \n return this.collection.shift()[0]; \n } else { \n return 'The queue is empty.' \n } \n }; \n }" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function PriorityQueue () {", + " this.collection = [];", + " this.printCollection = function() {", + " console.log(this.collection);", + " };", + " // Only change code below this line", + "", + " // Only change code above this line", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8255367417b2b2512c75", + "title": "Create a Circular Queue", + "description": [ + "In this challenge you will be creating a Circular Queue. A circular queue is basically a queue that writes to the end of a collection then begins over writing itself at the beginning of the collection. This is type of data structure has some useful applications in certain situations. For example, a circular queue can be used for streaming media. Once the queue is full, new media data simply begins to overwrite old data.", + "A good way to illustrate this concept is with an array:", + "
[1, 2, 3, 4, 5]
^Read @ 0
^Write @ 0
", + "Here the read and write are both at position 0. Now the queue gets 3 new records a, b, and c. Our queue now looks like:", + "
[a, b, c, 4, 5]
^Read @ 0
^Write @ 3
", + "As the read head reads, it can remove values or keep them:", + "
[null, null, null, 4, 5]
^Read @ 3
^Write @ 3
", + "Once the write reaches the end of the array it loops back to the beginning:", + "
[f, null, null, d, e]
^Read @ 3
^Write @ 1
", + "This approach requires a constant amount of memory but allows files of a much larger size to be processed.", + "Instructions:", + "In this challenge we will implement a circular queue. The circular queue should provide enqueue and dequeue methods which allow you to read from and write to the queue. The class itself should also accept an integer which you can use to specify the size of the queue when you create it. We've written the starting version of this class for you in the code editor. When you enqueue items to the queue, the write pointer should advance forward and loop back to the beginning once it reaches the end of the queue. Likewise, the read pointer should advance forward as you dequeue items. The write pointer should not be allowed to move past the read pointer (our class won't let you overwrite data you haven't read yet) and the read pointer should not be able to advance past data you have written.", + "In addition, the enqueue method should return the item you enqueued if it is successfully and otherwise return null. Similarly, when you dequeue an item it should be returned and if you cannot dequeue you should return null." + ], + "tests": [ + { + "text": "The enqueue method adds items to the circular queue.", + "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 enqueue method adds items to the circular queue.');" + }, + { + "text": "You cannot enqueue items past the read pointer.", + "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": "The dequeue method dequeues items from the queue.", + "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 dequeue method dequeues items from the queue.');" + }, + { + "text": "After an item is dequeued its position in the queue should be reset to null.", + "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 null.');" + }, + { + "text": "Trying to dequeue past the write pointer returns null and does not advance the write pointer.", + "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 null and does not advance the write pointer.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "class CircularQueue { \n constructor(size) { \n this.queue = []; \n this.read = 0; \n this.write = 0; \n this.max = size - 1; \n while (size > 0) { \n this.queue.push(null); \n size--; \n } \n } \n print() { \n return this.queue; \n } \n enqueue(item) { \n if (this.queue[this.write] === null) { \n this.queue[this.write] = item; \n if (this.write === this.max) { \n this.write = 0; \n } else { \n this.write++; \n } \n return item; \n } \n return null; \n } \n dequeue() { \n if (this.queue[this.read] !== null) { \n var item = this.queue[this.read]; \n this.queue[this.read] = null; \n if (this.read === this.max) { \n this.read = 0; \n } else { \n this.read++; \n } \n return item; \n } else { \n return null; \n } \n } \n }" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + " }", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "8d1323c8c441eddfaeb5bdef", + "title": "Create a Set Class", + "description": [ + "In the next few exercises we are going to create a function to emulate a data structure called a \"Set\". A Set is like an array, but it cannot contain duplicate values. The typical use for a Set is to simply check for the presence of an item. This can be implemented with an object, for instance:", + "
var set = new Object();
set.foo = true;
// See if foo exists in our set:
console.log(set.foo) // true
", + "In the next few exercises, we will build a full featured Set from scratch.", + "For this exercise, create a function that will add a value to our set collection as long as the value does not already exist in the set. For example:", + "
this.add = function(element) {
//some code to add value to the set
}
", + "The function should return true if the value is successfully added and false otherwise." + ], + "tests": [ + { + "text": "Your Set class should have an add method.", + "testString": "assert((function(){var test = new Set(); return (typeof test.add === 'function')}()), 'Your Set class should have an add method.');" + }, + { + "text": "Your add method should not add duplicate values.", + "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 add method should not add duplicate values.');" + }, + { + "text": "Your add method should return true when a value has been successfully added.", + "testString": "assert((function(){var test = new Set(); var result = test.add('a'); return (result != undefined) && (result === true);}()), 'Your add method should return true when a value has been successfully added.');" + }, + { + "text": "Your add method should return false when a duplicate value is added.", + "testString": "assert((function(){var test = new Set(); test.add('a'); var result = test.add('a'); return (result != undefined) && (result === false);}()), 'Your add method should return false when a duplicate value is added.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "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;}};}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8253367417b2b2512c6b", + "title": "Remove from a Set", + "description": [ + "In this exercises we are going to create a delete function for our set. The function should be named this.remove. This function should accept a value and check if it exists in the set. If it does, remove that value from the set, and return true. Otherwise, return false." + ], + "tests": [ + { + "text": "Your Set class should have a remove method.", + "testString": "assert((function(){var test = new Set(); return (typeof test.remove === 'function')}()), 'Your Set class should have a remove method.');" + }, + { + "text": "Your remove method should only remove items that are present in the set.", + "testString": "assert.deepEqual((function(){var test = new Set(); test.add('a');test.add('b');test.remove('c'); return test.values(); })(), ['a', 'b'], 'Your remove method should only remove items that are present in the set.');" + }, + { + "text": "Your remove method should remove the given item from the set.", + "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 remove method should remove the given item from the set.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "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;};}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "8d1923c8c441eddfaeb5bdef", + "title": "Size of the Set", + "description": [ + "In this exercise we are going to create a size function for our Set. This function should be named this.size and it should return the size of the collection." + ], + "tests": [ + { + "text": "Your Set class should have a size method.", + "testString": "assert((function(){var test = new Set(); return (typeof test.size === 'function')}()), 'Your Set class should have a size method.');" + }, + { + "text": "The size method should return the number of elements in the collection.", + "testString": "assert((function(){var test = new Set(); test.add('a');test.add('b');test.remove('a');return (test.size() === 1)}()), 'The size method should return the number of elements in the collection.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "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;};}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8253367417b2b2512c6c", + "title": "Perform a Union on Two Sets", + "description": [ + "In this exercise we are going to perform a union on two sets of data. We will create a method on our Set data structure called union. This method should take another Set as an argument and return the union of the two sets, excluding any duplicate values.", + "For example, if setA = ['a','b','c'] and setB = ['a','b','d','e'], then the union of setA and setB is: setA.union(setB) = ['a', 'b', 'c', 'd', 'e']." + ], + "tests": [ + { + "text": "Your Set class should have a union method.", + "testString": "assert((function(){var test = new Set(); return (typeof test.union === 'function')})(), 'Your Set class should have a union method.');" + }, + { + "text": "The proper collection was returned", + "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');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "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;};}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8253367417b2b2512c6d", + "title": "Perform an Intersection on Two Sets of Data", + "description": [ + "In this exercise we are going to perform an intersection on 2 sets of data. We will create a method on our Set data structure called intersection. An intersection of sets represents all values that are common to two or more sets. This method should take another Set as an argument and return the intersection of the two sets.", + "For example, if setA = ['a','b','c'] and setB = ['a','b','d','e'], then the intersection of setA and setB is: setA.intersection(setB) = ['a', 'b']." + ], + "tests": [ + { + "text": "Your Set class should have a intersection method.", + "testString": "assert(function(){var test = new Set(); return (typeof test.intersection === 'function')}, 'Your Set class should have a intersection method.');" + }, + { + "text": "The proper collection was returned", + "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');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "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);});};}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8254367417b2b2512c6e", + "title": "Perform a Difference on Two Sets of Data", + "description": [ + "In this exercise we are going to perform a difference on 2 sets of data. We will create a method on our Set data structure called difference. A difference of sets should compare two sets and return the items present in the first set that are absent in the second. This method should take another Set as an argument and return the difference of the two sets.", + "For example, if setA = ['a','b','c'] and setB = ['a','b','d','e'], then the difference of setA and setB is: setA.difference(setB) = ['c']." + ], + "tests": [ + { + "text": "Your Set class should have a difference method.", + "testString": "assert(function(){var test = new Set(); return (typeof test.difference === 'function')}, 'Your Set class should have a difference method.');" + }, + { + "text": "The proper collection was returned", + "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');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "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);});};}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8254367417b2b2512c6f", + "title": "Perform a Subset Check on Two Sets of Data", + "description": [ + "In this exercise we are going to perform a subset test on 2 sets of data. We will create a method on our Set data structure called subset. This will compare the first set, against the second and if the first set is fully contained within the Second then it will return true.", + "For example, if setA = ['a','b'] and setB = ['a','b','c','d'], then the subset of setA and setB is: setA.subset(setB) should be true." + ], + "tests": [ + { + "text": "Your Set class should have a union method.", + "testString": "assert(function(){var test = new Set(); return (typeof test.subset === 'function')}, 'Your Set class should have a union method.');" + }, + { + "text": "The first Set() was contained in the second 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": "['a', 'b'].subset(['a', 'b', 'c', 'd']) should return true\")", + "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)}, \"['a', 'b'].subset(['a', 'b', 'c', 'd']) should return true\");" + }, + { + "text": "['a', 'b', 'c'].subset(['a', 'b']) should return false\")", + "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)}, \"['a', 'b', 'c'].subset(['a', 'b']) should return false\");" + }, + { + "text": "[].subset([]) should return true", + "testString": "assert(function(){var setA = new Set(); var setB = new Set(); var subsetSetAB = setA.subset(setB); return (subsetSetAB === true)}, '[].subset([]) should return true');" + }, + { + "text": "['a', 'b'].subset(['c', 'd']) should return false\")", + "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)}, \"['a', 'b'].subset(['c', 'd']) should return false\");" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "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;};}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8254367417b2b2512c70", + "title": "Create and Add to Sets in ES6", + "description": [ + "Now that you have worked through ES5, you are going to perform something similar in ES6. This will be considerably easier. ES6 contains a built-in data structure Set so many of the operations you wrote by hand are now included for you. Let's take a look:", + "To create a new empty set:", + "var set = new Set();", + "You can create a set with a value:", + "var set = new Set(1);", + "You can create a set with an array:", + "var set = new Set([1, 2, 3]);", + "Once you have created a set, you can add the values you wish using the add method:", + "
var set = new Set([1, 2, 3]);
set.add([4, 5, 6]);
", + "As a reminder, a set is a data structure that cannot contain duplicate values:", + "
var set = new Set([1, 2, 3, 1, 2, 3]);
// set contains [1, 2, 3] only
", + "
", + "For this exercise, return a set with the following values: 1, 2, 3, 'Taco', 'Cat', 'Awesome'" + ], + "tests": [ + { + "text": "Your Set should only contains the values 1, 2, 3, Taco, Cat, Awesome.", + "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 Set should only contains the values 1, 2, 3, Taco, Cat, Awesome.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "function checkSet(){var set = new Set([1,2,3,'Taco','Cat','Awesome']);\nreturn set;}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8254367417b2b2512c71", + "title": "Remove items from a set in ES6", + "description": [ + "Let's practice removimg items from an ES6 Set using the delete method.", + "First, create an ES6 Set", + "var set = new Set([1,2,3]);", + "Now remove an item from your Set with the delete method.", + "
set.delete(1);
console.log([...set]) // should return [ 2, 3 ]
", + "
", + "Now, create a set with the integers 1, 2, 3, 4, & 5. \n Remove the values 2 and 5, and then return the set." + ], + "tests": [ + { + "text": "Your Set should contain the values 1, 3, & 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');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "function checkSet(){\nvar set = new Set([1,2,3,4,5]);\nset.delete(2);\nset.delete(5);\nreturn set;}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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;", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8255367417b2b2512c72", + "title": "Use .has and .size on an ES6 Set", + "description": [ + "Let's look at the .has and .size methods available on the ES6 Set object.", + "First, create an ES6 Set", + "var set = new Set([1,2,3]);", + "The .has method will check if the value is contained within the set.", + "var hasTwo = set.has(2);", + "The .size method will return an integer representing the size of the Set", + "var howBig = set.size;", + "
", + "In this exercise we will pass an array and a value to the checkSet() function. Your function should create an ES6 set from the array argument. Find if the set contains the value argument. Find the size of the set. And return those two values in an array." + ], + "tests": [ + { + "text": "checkSet([4, 5, 6], 3) should return [ false, 3 ]", + "testString": "assert(function(){var test = checkSet([4,5,6], 3); test === [ false, 3 ]}, 'checkSet([4, 5, 6], 3) should return [ false, 3 ]');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "function checkSet(arrToBeSet, checkValue){\nvar set = new Set(arrToBeSet);\nvar result = [\nset.has(checkValue),\nset.size\n];\nreturn result;\n}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function checkSet(arrToBeSet, checkValue){", + "", + " // change code below this line", + "", + " // change code above this line", + "", + "}", + "", + "checkSet([ 1, 2, 3], 2); // Should return [ true, 3 ]" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8255367417b2b2512c73", + "title": "Use Spread and Notes for ES5 Set() Integration", + "description": [ + "Do you remember the ES6 spread operator ...?", + "... can take iterable objects in ES6 and turn them into arrays.", + "Let's create a Set, and check out the spread function.", + "
var set = new Set([1,2,3]);
var setToArr = [...set]
console.log(setToArr) // returns [ 1, 2, 3 ]
", + "
", + "In this exercise we will pass a set object to the checkSet function. It should return an array containing the values of the Set.", + "Now you've successfully learned how to use the ES6 Set() object, good job!" + ], + "tests": [ + { + "text": "Your Set was returned correctly!", + "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!');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "function checkSet(set){\nreturn [...set];}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function checkSet(set){", + " // change code below this line", + "", + " // change code above this line", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "8d5823c8c441eddfaeb5bdef", + "title": "Create a Map Data Structure", + "description": [ + "The next few challenges will cover maps and hash tables. Maps are data structurs that store key-value pairs. In JavaScript, these are available to us as objects. Maps provide rapid lookup of stored items based on key values and are very common and useful data structures.", + "Instructions: Let's get some practice creating our own map. Because JavaScript objects provide a much more efficient map structure than anything we could write here, this is intended primarily as a learning exercise. However, JavaScript objects only provide us with certain operations. What if we wanted to define custom operations?", + "Use the Map object provided here as a wrapper around a JavaScript object. Create the following methods and operations on the Map object:", + "add accepts a key, value pair to add to the map", + "remove accepts a key and removes the associated key, value pair", + "get accepts a key and returns the stored value", + "has returns a boolean for the presence or absence of an item", + "values returns an array of all the values in the map", + "size returns the number of items in the map", + "clear empties the map" + ], + "tests": [ + { + "text": "The Map data structure exists.", + "testString": "assert((function() { var test = false; if (typeof Map !== 'undefined') { test = new Map() }; return (typeof test == 'object')})(), 'The Map data structure exists.');" + }, + { + "text": "The Map object has the following methods: add, remove, get, has, values, clear, and size.", + "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": "The add method adds items to the map.", + "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() == 3)})(), 'The add method adds items to the map.');" + }, + { + "text": "The has method returns true for added items and false for absent items.", + "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": "The get method accepts keys as input and returns the associated values.", + "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": "The values method returns all the values stored in the map as strings in an array.", + "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": "The clear method empties the map and the size method returns the number of items present in the map.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "var Map = function() {", + " this.collection = {};", + " // change code below this line", + " // change code above this line", + "};" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d825b367417b2b2512c8d", + "title": "Create an ES6 JavaScript Map", + "description": [ + "The new version of JavaScript provides us with a built-in Map object which provides much of the functionality we wrote by hand in the last challenge. This Map object, although similar to regular JavaScript objects, provides some useful functionality that normal objects lack. For example, an ES6 Map tracks the insertion order of items that are added to it. Here is a more complete overview of its methods:", + ".has(key) returns true or false based on the presence of a key", + ".get(key) returns the value associated with a key", + ".set(key, value) sets a new key, value pair", + ".delete(key) removes a key, value pair", + ".clear() removes all key, value pairs", + ".entries() returns an array of all the keys in insertion order", + ".values() returns an array of all the values in insertion order", + "Instructions: Define a JavaScript Map object and assign to it a variable called myMap. Add the key, value pair freeCodeCamp, Awesome! to it." + ], + "tests": [ + { + "text": "The myMap object exists.", + "testString": "assert(typeof myMap === 'object', 'The myMap object exists.');" + }, + { + "text": "myMap contains the key value pair freeCodeCamp, Awesome!.", + "testString": "assert(myMap.get('freeCodeCamp') === 'Awesome!', 'myMap contains the key value pair freeCodeCamp, Awesome!.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "// change code below this line" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d825b367417b2b2512c8e", + "title": "Create a Hash Table", + "description": [ + "In this challenge we will learn about hash tables. A Hash table is used to implement associative arrays, or mappings of key-value pairs, like the objects and Maps we have just been studying. A JavaScript object could be implemented as a hash table, for instance (its actual implementation will depend on the environment it's running in). The way a hash table works is that it takes a key input and hashes this key in a deterministic way to some numerical value. This numerical value is then used as the actual key the associated value is stored by. Then, if you try to access the same key again, the hashing function will process the key, return the same numerical result, which will then be used to look up the associated value. This provides very efficient O(n) lookup time on average.", + "Hash tables can be implemented as arrays with hash functions producing array indices within a specified range. In this method, the choice of the array size is important, as is the hashing function. For instance, what if the hashing function produces the same value for two different keys? This is called a collision. One way to handle collisions is to just store both key-value pairs at that index. Then, upon lookup of either, you would have to iterate through the bucket of items to find the key you are looking for. A good hashing function will minimize collisions to maintain efficient search time.", + "Here, we won't be concerned with the details of hashing or hash table implementation, we will just try to get a general sense of how they work.", + "Instructions: Let's create the basic functionality of a hash table. We've created a naive hashing function for you to use. You can pass a string value to the function hash and it will return a hashed value you can use as a key for storage. Store items based on this hashed value in the this.collection object. Create these three methods: add, remove, and lookup. The first should accept a key value pair to add to the hash table. The second should remove a key-value pair when passed a key. The third should accept a key and return the associated value or null if the key is not present.", + "Be sure to write your code to account for collisions!" + ], + "tests": [ + { + "text": "The HashTable data structure exists.", + "testString": "assert((function() { var test = false; if (typeof HashTable !== 'undefined') { test = new HashTable() }; return (typeof test === 'object')})(), 'The HashTable data structure exists.');" + }, + { + "text": "The HashTable has an add method.", + "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": "The HashTable has an remove method.", + "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": "The HashTable has an lookup method.", + "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": "The add method adds key value pairs and the lookup method returns the values associated with a given key.", + "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": "The remove method accepts a key as input and removes the associated key value pair.", + "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": "Items are added using the hash function.", + "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": "The hash table handles collisions.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "};" + ], + "head": " var called = 0;\n var hash = (string) => {\n called++;\n var hash = 0;\n for (var i = 0; i < string.length; i++) { hash += string.charCodeAt(i); };\n return hash;\n };", + "tail": "" + } + } + }, + { + "id": "587d8251367417b2b2512c61", + "title": "Work with Nodes in a Linked List", + "description": [ + "Another common data structure you'll run into in computer science is the linked list. A linked list is a linear collection of data elements, called 'nodes', each of which points to the next. Each node in a linked list contains two key pieces of information: the element itself, and a reference to the next node.", + "Imagine that you are in a conga line. You have your hands on the next person in the line, and the person behind you has their hands on you. You can see the person straight ahead of you, but they are blocking the view of the other people ahead in line. A node is just like a person in a conga line: they know who they are and they can only see the next person in line, but they are not aware of the other people ahead or behind them.", + "
", + "In our code editor, we've created two nodes, Kitten and Puppy, and we've manually connected the Kitten node to the Puppy node.", + "Create a Cat and Dog node and manually add them to the line." + ], + "tests": [ + { + "text": "Your Puppy node should have a reference to a Cat node.", + "testString": "assert(Puppy.next.element === \"Cat\", 'Your Puppy node should have a reference to a Cat node.');" + }, + { + "text": "Your Cat node should have a reference to a Dog node.", + "testString": "assert(Cat.next.element === \"Dog\", 'Your Cat node should have a reference to a Dog node.');" + } + ], + "solutions": [], + "hints": [], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8251367417b2b2512c62", + "title": "Create a Linked List Class", + "description": [ + "Let's create a linked list class. Every linked list should start out with a few basic properties: a head (the first item in your list) and a length (number of items in your list). Sometimes you'll see implementations of linked lists that incorporate a tail for the last element of the list, but for now we'll just stick with these two. Whenever we add an element to the linked list, our length property should be incremented by one.", + "We'll want to have a way to add items to our linked list, so the first method we'll want to create is the add method.", + "If our list is empty, adding an element to our linked list is straightforward enough: we just wrap that element in a Node class, and we assign that node to the head of our linked list.", + "But what if our list already has one or more members? How do we add an element to the list? Recall that each node in a linked list has a next property. To add a node to the list, find the last node in the list, and point that last node's next property at our new node. (Hint: you know you've reached the end of a linked list when a node's next property is null.)", + "
", + "Write an add method that assigns the first node you push to the linked list to the head; after that, whenever adding a node, every node should be referenced by the previous node's next property.", + "Note", + "Your list's length should increase by one every time an element is added to the linked list." + ], + "tests": [ + { + "text": "Your LinkedList class should have a add method.", + "testString": "assert((function(){var test = new LinkedList(); return (typeof test.add === 'function')}()), 'Your LinkedList class should have a add method.');" + }, + { + "text": "Your LinkedList class should assign head to the first node added.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); return test.head().element === 'cat'}()), 'Your LinkedList class should assign head to the first node added.');" + }, + { + "text": "The previous node in your LinkedList class should have reference to the newest node created.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); return test.head().next.element === 'dog'}()), 'The previous node in your LinkedList class should have reference to the newest node created.');" + }, + { + "text": "The size of your LinkedList class should equal the amount of nodes in the linked list.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); return test.size() === 2}()), 'The size of your LinkedList class should equal the amount of nodes in the linked list.');" + } + ], + "solutions": [], + "hints": [], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + " };", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8251367417b2b2512c63", + "title": "Remove Elements from a Linked List", + "description": [ + "The next important method that any implementation of a linked list will need is a remove method. This method should take the element we want to remove as an argument, and then search the list to find and remove the node that contains that element.", + "Whenever we remove a node from a linked list, it's important that we don't accidentally orphan the rest of the list in doing so. Recall that every node's next property points to the node that follows it in the list. If we're removing the middle element, say, we'll want to make sure that we have a connection from that element's previous node's next property to the middle element's next property (which is the next node in the list!)", + "This might sound really confusing, so let's return to the conga line example so we have a good conceptual model. Picture yourself in a conga line, and the person directly in front of you leaves the line. The person who just left the line no longer has her hands on anyone in line--and you no longer have your hands on the person that left. You step forward and put your hands on next person you see.", + "If the element we wish to remove is the head element, we reassign the head to the second node of the linked list.", + "
", + "Write a remove method that takes an element and removes it from the linked list.", + "Note", + "The length of the list should decrease by one every time an element is removed from the linked list." + ], + "tests": [ + { + "text": "Your LinkedList class should have a remove method.", + "testString": "assert((function(){var test = new LinkedList(); return (typeof test.remove === 'function')}()), 'Your LinkedList class should have a remove method.');" + }, + { + "text": "Your remove method should reassign head to the second node when the first node is removed.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.remove('cat'); return test.head().element === 'dog'}()), 'Your remove method should reassign head to the second node when the first node is removed.');" + }, + { + "text": "Your remove method should decrease the length of the linked list by one for every node removed.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.remove('cat'); return test.size() === 1})(), 'Your remove method should decrease the length of the linked list by one for every node removed.');" + }, + { + "text": "Your remove method should reassign the reference of the previous node of the removed node to the removed node's next reference.", + "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 remove method should reassign the reference of the previous node of the removed node to the removed node's next reference.');" + } + ], + "solutions": [ + "class Node {\n constructor (element) {\n this.element = element;\n this.next = null;\n }\n}\n\nclass LinkedList {\n constructor () {\n this._length = 0;\n this._head = null;\n }\n\n head () {\n return this._head;\n }\n\n size () {\n return this._length;\n }\n\n add (element) {\n const node = new Node(element);\n\n if (this._head === null) {\n this._head = node;\n } else {\n let current = this._head;\n\n while (current.next !== null) {\n current = current.next;\n }\n\n current.next = node; \n }\n \n ++this._length;\n }\n \n remove (element) {\n if (this._head === null) return;\n \n let previous;\n let current = this._head;\n \n while (current.next !== null && current.element !== element) {\n previous = current;\n current = current.next;\n }\n \n if (previous) {\n previous.next = current.next;\n } else {\n this._head = current.next;\n }\n \n --this._length;\n }\n}" + ], + "hints": [], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + " };", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8251367417b2b2512c64", + "title": "Search within a Linked List", + "description": [ + "Let's add a few more useful methods to our linked list class. Wouldn't it be useful if we could tell if our list was empty or not, as with our Stack and Queue classes?", + "We should also be able to find specific elements in our linked list. Traversing through data structures is something you'll want to get a lot of practice with! Let's create an indexOf method that takes an element as an argument, and returns that element's index in the linked list. If the element is not found in the linked list, return -1.", + "Let's also implement a method that does the opposite: an elementAt method that takes an index as an argument and returns the element at the given index. If no element is found, return undefined.", + "
", + "Write an isEmpty method that checks if the linked list is empty, an indexOf method that returns the index of a given element, and an elementAt that returns an element at a given index." + ], + "tests": [ + { + "text": "Your LinkedList class should have a indexOf method.", + "testString": "assert((function(){var test = new LinkedList(); return (typeof test.indexOf === 'function')}()), 'Your LinkedList class should have a indexOf method.');" + }, + { + "text": "Your LinkedList class should have a elementAt method.", + "testString": "assert((function(){var test = new LinkedList(); return (typeof test.elementAt === 'function')}()), 'Your LinkedList class should have a elementAt method.');" + }, + { + "text": "Your size method should return the length of the linked list", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.add('kitten'); return test.size() === 3}()), 'Your size method should return the length of the linked list');" + }, + { + "text": "Your indexOf method should return the index of the given element.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.add('kitten'); return test.indexOf('kitten') === 2}()), 'Your indexOf method should return the index of the given element.');" + }, + { + "text": "Your elementAt method should return at element at a given index.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.add('kitten'); return test.elementAt(1) === 'dog'}()), 'Your elementAt method should return at element at a given index.');" + } + ], + "solutions": [], + "hints": [], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8251367417b2b2512c65", + "title": "Remove Elements from a Linked List by Index", + "description": [ + "Before we move on to another data structure, let's get a couple of last bits of practice with linked lists.", + "Let's write a removeAt method that removes the element at a given index. The method should be called removeAt(index). To remove an element at a certain index, we'll need to keep a running count of each node as we move along the linked list.", + "A common technique used to iterate through the elements of a linked list involves a 'runner', or sentinel, that 'points' at the nodes that your code is comparing. In our case, starting at the head of our list, we start with a currentIndex variable that starts at 0. The currentIndex should increment by one for each node we pass.", + "Just like our remove(element) method, we need to be careful not to orphan the rest of our list when we remove the node in our removeAt(index) method. We keep our nodes contiguous by making sure that the node that has reference to the removed node has a reference to the next node.", + "
", + "Write a removeAt(index) method that removes and returns a node at a given index. The method should return null if the given index is either negative, or greater than or equal to the length of the linked list.", + "Note", + "Remember to keep count of the currentIndex." + ], + "tests": [ + { + "text": "Your LinkedList class should have a removeAt method.", + "testString": "assert((function(){var test = new LinkedList(); return (typeof test.removeAt === 'function')}()), 'Your LinkedList class should have a removeAt method.');" + }, + { + "text": "Your removeAt method should reduce the length of the linked list", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.add('kitten'); test.removeAt(1); return test.size() === 2}()), 'Your removeAt method should reduce the length of the linked list');" + }, + { + "text": "Your removeAt method should also return the element of the removed node.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.add('kitten'); return test.removeAt(1) === 'dog'}()), 'Your removeAt method should also return the element of the removed node.');" + }, + { + "text": "Your removeAt method should also return null if the given index is less than 0", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.add('kitten'); return (test.removeAt(-1) === null)}()), 'Your removeAt method should also return null if the given index is less than 0');" + }, + { + "text": "Your removeAt method should also return null if the given index is equal or more than the length of the linked list.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.add('kitten'); return (test.removeAt(3) === null)}()), 'Your removeAt method should also return null if the given index is equal or more than the length of the linked list.');" + } + ], + "solutions": [], + "hints": [], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8252367417b2b2512c67", + "title": "Add Elements at a Specific Index in a Linked List", + "description": [ + "Let's create a addAt(index,element) method that adds an element at a given index.", + "Just like how we remove elements at a given index, we need to keep track of the currentIndex as we traverse the linked list. When the currentIndex matches the given index, we would need to reassign the previous node's next property to reference the new added node. And the new node should reference the next node in the currentIndex.", + "Returning to the conga line example, a new person wants to join the line, but he wants to join in the middle. You are in the middle of the line, so you take your hands off of the person ahead of you. The new person walks over and puts his hands on the person you once had hands on, and you now have your hands on the new person.", + "Instructions", + "Create an addAt(index,element) method that adds an element at a given index. Return false if an element was unable to be added.", + "Note", + "Remember to check if the given index is a negative or is longer than the length of the linked list." + ], + "tests": [ + { + "text": "Your addAt method should reassign head to the new node when the given index is 0.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.addAt(0,'cat'); return test.head().element === 'cat'}()), 'Your addAt method should reassign head to the new node when the given index is 0.');" + }, + { + "text": "Your addAt method should increase the length of the linked list by one for each new node added to the linked list.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); test.addAt(0,'cat'); return test.size() === 3}()), 'Your addAt method should increase the length of the linked list by one for each new node added to the linked list.');" + }, + { + "text": "Your addAt method should return false if a node was unable to be added.", + "testString": "assert((function(){var test = new LinkedList(); test.add('cat'); test.add('dog'); return (test.addAt(4,'cat') === false); }()), 'Your addAt method should return false if a node was unable to be added.');" + } + ], + "solutions": [], + "hints": [], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d825a367417b2b2512c87", + "title": "Create a Doubly Linked List", + "description": [ + "All of the linked lists we've created so far are singly linked lists. Here, we'll create a doubly linked list. As the name implies, nodes in a doubly linked list have references to the next and previous node in the list.", + "This allows us to traverse the list in both directions but it also requires more memory to be used because every node must contain an additional reference to the previous node in the list.", + "
", + "We've provided a Node object and started our DoublyLinkedList. Let's add two methods to our doubly linked list called add and remove. The add method should add the given element to the list while the remove method should remove all occurrences of a given element in the list.", + "Be careful to handle any possible edge cases when writing these methods, such as deletions for the first or last element. Also, removing any item on an empty list should return null." + ], + "tests": [ + { + "text": "The DoublyLinkedList data structure exists.", + "testString": "assert((function() { var test = false; if (typeof DoublyLinkedList !== 'undefined') { test = new DoublyLinkedList() }; return (typeof test == 'object')})(), 'The DoublyLinkedList data structure exists.');" + }, + { + "text": "The DoublyLinkedList has a method called add.", + "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": "The DoublyLinkedList has a method called remove.", + "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": "Removing an item from an empty list returns null.", + "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": "The add method adds items to the list.", + "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": "Each node keeps track of the previous node.", + "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": "The first item can be removed from the list.", + "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": "The last item can be removed from the list.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "};" + ], + "head": "", + "tail": "DoublyLinkedList.prototype = {\n print() {\n if (this.head == null) {\n return null;\n } else {\n var result = new Array();\n var node = this.head;\n while (node.next != null) {\n result.push(node.data);\n node = node.next;\n };\n result.push(node.data);\n return result;\n };\n },\n printReverse() {\n if (this.tail == null) {\n return null;\n } else {\n var result = new Array();\n var node = this.tail;\n while (node.prev != null) {\n result.push(node.data);\n node = node.prev;\n };\n result.push(node.data);\n return result;\n };\n } \n};" + } + } + }, + { + "id": "587d825a367417b2b2512c88", + "title": "Reverse a Doubly Linked List", + "description": [ + "Let's create one more method for our doubly linked list called reverse which reverses the list in place. Once the method is executed the head should point to the previous tail and the tail should point to the previous head. Now, if we traverse the list from head to tail we should meet the nodes in a reverse order compared to the original list. Trying to reverse an empty list should return null." + ], + "tests": [ + { + "text": "The DoublyLinkedList data structure exists.", + "testString": "assert((function() { var test = false; if (typeof DoublyLinkedList !== 'undefined') { test = new DoublyLinkedList() }; return (typeof test == 'object')})(), 'The DoublyLinkedList data structure exists.');" + }, + { + "text": "The DoublyLinkedList has a method called add.", + "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": "The DoublyLinkedList has a method called reverse.", + "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": "Reversing an empty list returns null.", + "testString": "assert((function() { var test = false; if (typeof DoublyLinkedList !== 'undefined') { test = new DoublyLinkedList() }; return (test.reverse() == null); })(), 'Reversing an empty list returns null.');" + }, + { + "text": "The reverse method reverses the list.", + "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": "The next and previous references are correctly maintained when a list is reversed.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "};" + ], + "head": "", + "tail": "DoublyLinkedList.prototype = {\n add(data) {\n if (this.head == null) {\n this.head = new Node(data, null);\n this.tail = this.head;\n } else {\n var node = this.head;\n var prev = null;\n while (node.next != null) {\n prev = node;\n node = node.next;\n };\n var newNode = new Node(data, node);\n node.next = newNode;\n this.tail = newNode;\n };\n },\n print() {\n if (this.head == null) {\n return null;\n } else {\n var result = new Array();\n var node = this.head;\n while (node.next != null) {\n result.push(node.data);\n node = node.next;\n };\n result.push(node.data);\n return result;\n };\n },\n printReverse() {\n if (this.tail == null) {\n return null;\n } else {\n var result = new Array();\n var node = this.tail;\n while (node.prev != null) {\n result.push(node.data);\n node = node.prev;\n };\n result.push(node.data);\n return result;\n };\n }\n};" + } + } + }, + { + "id": "587d8256367417b2b2512c7a", + "title": "Find the Minimum and Maximum Value in a Binary Search Tree", + "description": [ + "This series of challenges will introduce the tree data structure. Trees are an important and versatile data structure in computer science. Of course, their name comes from the fact that when visualized they look much like the trees we are familiar with in the natural world. A tree data structure begins with one node, typically referred to as the root, and from here branches out to additional nodes, each of which may have more child nodes, and so on and so forth. The data structure is usually visualized with the root node at the top; you can think of it as a natural tree flipped upside down.", + "First, let's describe some common terminology we will encounter with trees. The root node is the top of the tree. Data points in the tree are called nodes. Nodes with branches leading to other nodes are referred to as the parent of the node the branch leads to (the child). Other more complicated familial terms apply as you might expect. A subtree refers to all the descendants of a particular node, branches may be referred to as edges, and leaf nodes are nodes at the end of the tree that have no children. Finally, note that trees are inherently recursive data structures. That is, any children of a node are parents of their own subtree, and so on. The recursive nature of trees is important to understand when designing algorithms for common tree operations.", + "To begin, we will discuss a particular type of a tree, the binary tree. In fact, we will actually discuss a particular binary tree, a binary search tree. Let's describe what this means. While the tree data structure can have any number of branches at a single node, a binary tree can only have two branches for every node. Furthermore, a binary search tree is ordered with respect to the child subtrees, such that the value of each node in the left subtree is less than or equal to the value of the parent node, and the value of each node in the right subtree is greater than or equal to the value of the parent node. It's very helpful to visualize this relationship in order to understand it better:", + "
", + "Now this ordered relationship is very easy to see. Note that every value to the left of 8, the root node, is less than 8, and every value to the right is greater than 8. Also notice that this relationship applies to each of the subtrees as well. For example, the first left child is a subtree. 3 is the parent node, and it has exactly two child nodes — by the rules governing binary search trees, we know without even looking that the left child of this node (and any of its children) will be less than 3, and the right child (and any of its children) will be greater than 3 (but also less than the structure's root value), and so on.", + "Binary search trees are very common and useful data structures because they provide logarithmic time in the average case for several common operations such as lookup, insertion, and deletion.", + "Instructions: We'll start simple. We've defined the skeleton of a binary search tree structure here in addition to a function to create nodes for our tree. Observe that each node may have a left and right value. These will be assigned child subtrees if they exist. In our binary search tree, define two methods, findMin and findMax. These methods should return the minimum and maximum value held in the binary search tree (don't worry about adding values to the tree for now, we have added some in the background). If you get stuck, reflect on the invariant that must be true for binary search trees: each left subtree is less than or equal to its parent and each right subtree is greater than or equal to its parent. Let's also say that our tree can only store integer values. If the tree is empty, either method should return null." + ], + "tests": [ + { + "text": "The BinarySearchTree data structure exists.", + "testString": "assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() }; return (typeof test == 'object')})(), 'The BinarySearchTree data structure exists.');" + }, + { + "text": "The binary search tree has a method called findMin.", + "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 findMin.');" + }, + { + "text": "The binary search tree has a method called findMax.", + "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 findMax.');" + }, + { + "text": "The findMin method returns the minimum value in the binary search tree.", + "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 findMin method returns the minimum value in the binary search tree.');" + }, + { + "text": "The findMax method returns the maximum value in the binary search tree.", + "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 findMax method returns the maximum value in the binary search tree.');" + }, + { + "text": "The findMin and findMax methods return null for an empty tree.", + "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 findMin and findMax methods return null for an empty tree.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "BinarySearchTree.prototype = {\n add: function(value) {\n var node = this.root;\n if (node == null) {\n this.root = new Node(value);\n return;\n } else {\n function searchTree(node) {\n if (value < node.value) {\n if (node.left == null) {\n node.left = new Node(value);\n return;\n } else if (node.left != null) {\n return searchTree(node.left)\n };\n } else if (value > node.value) {\n if (node.right == null) {\n node.right = new Node(value);\n return;\n } else if (node.right != null) {\n return searchTree(node.right);\n };\n } else {\n return null;\n };\n };\n return searchTree(node);\n };\n }\n};" + } + } + }, + { + "id": "587d8257367417b2b2512c7b", + "title": "Add a New Element to a Binary Search Tree", + "description": [ + "Now that we have an idea of the basics lets write a more complex method.", + "In this challenge, we will create a method to add new values to our binary search tree. The method should be called add and it should accept an integer value to add to the tree. Take care to maintain the invariant of a binary search tree: the value in each left child should be less than or equal to the parent value, and the value in each right child should be greater than or equal to the parent value. Here, let's make it so our tree cannot hold duplicate values. If we try to add a value that already exists, the method should return null. Otherwise, if the addition is successful, undefined should be returned.", + "Hint: trees are naturally recursive data structures!" + ], + "tests": [ + { + "text": "The BinarySearchTree data structure exists.", + "testString": "assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() }; return (typeof test == 'object')})(), 'The BinarySearchTree data structure exists.');" + }, + { + "text": "The binary search tree has a method called add.", + "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 add.');" + }, + { + "text": "The add method adds elements according to the binary search tree rules.", + "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); return (test.isBinarySearchTree()); })(), 'The add method adds elements according to the binary search tree rules.');" + }, + { + "text": "Adding an element that already exists returns null", + "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 null');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "BinarySearchTree.prototype = {\n isBinarySearchTree() {\n if (this.root == null) {\n return null;\n } else {\n var check = true;\n function checkTree(node) {\n if (node.left != null) {\n var left = node.left;\n if (left.value > node.value) {\n check = false;\n } else {\n checkTree(left);\n }\n }\n if (node.right != null) {\n var right = node.right;\n if (right.value < node.value) {\n check = false;\n } else {\n checkTree(right);\n };\n };\n };\n checkTree(this.root);\n return check;\n };\n }\n};" + } + } + }, + { + "id": "587d8257367417b2b2512c7c", + "title": "Check if an Element is Present in a Binary Search Tree", + "description": [ + "Now that we have a general sense of what a binary search tree is let's talk about it in a little more detail. Binary search trees provide logarithmic time for the common operations of lookup, insertion, and deletion in the average case, and linear time in the worst case. Why is this? Each of those basic operations requires us to find an item in the tree (or in the case of insertion to find where it should go) and because of the tree structure at each parent node we are branching left or right and effectively excluding half the size of the remaining tree. This makes the search proportional to the logarithm of the number of nodes in the tree, which creates logarithmic time for these operations in the average case.", + "Ok, but what about the worst case? Well, consider constructing a tree from the following values, adding them left to right: 10, 12, 17, 25. Following our rules for a binary search tree, we will add 12 to the right of 10, 17 to the right of this, and 25 to the right of this. Now our tree resembles a linked list and traversing it to find 25 would require us to traverse all the items in linear fashion. Hence, linear time in the worst case. The problem here is that the tree is unbalanced. We'll look a little more into what this means in the following challenges.", + "Instructions: In this challenge, we will create a utility for our tree. Write a method isPresent which takes an integer value as input and returns a boolean value for the presence or absence of that value in the binary search tree." + ], + "tests": [ + { + "text": "The BinarySearchTree data structure exists.", + "testString": "assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() }; return (typeof test == 'object')})(), 'The BinarySearchTree data structure exists.');" + }, + { + "text": "The binary search tree has a method called isPresent.", + "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 isPresent.');" + }, + { + "text": "The isPresent method correctly checks for the presence or absence of elements added to the tree.", + "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 isPresent method correctly checks for the presence or absence of elements added to the tree.');" + }, + { + "text": "isPresent handles cases where the tree is empty.", + "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; })(), 'isPresent handles cases where the tree is empty.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "BinarySearchTree.prototype = {\n add: function(value) {\n var node = this.root;\n if (node == null) {\n this.root = new Node(value);\n return;\n } else {\n function searchTree(node) {\n if (value < node.value) {\n if (node.left == null) {\n node.left = new Node(value);\n return;\n } else if (node.left != null) {\n return searchTree(node.left)\n };\n } else if (value > node.value) {\n if (node.right == null) {\n node.right = new Node(value);\n return;\n } else if (node.right != null) {\n return searchTree(node.right);\n };\n } else {\n return null;\n };\n };\n return searchTree(node);\n };\n }\n};" + } + } + }, + { + "id": "587d8257367417b2b2512c7d", + "title": "Find the Minimum and Maximum Height of a Binary Search Tree", + "description": [ + "In the last challenge we described a scenario in which a tree could become unbalanced. To understand the concept of balance, let's take a look at another tree property: height. Height in a tree represents the distance from the root node to any given leaf node. Different paths in a highly branched tree structure may have different heights, but for a given tree there will be a minimum and maximum height. If the tree is balanced, these values will differ at most by one. This means that in a balanced tree, all the leaf nodes exist within the same level, or if they are not within the same level they are at most one level apart.", + "The property of balance is important for trees because it is what determines the efficiency of tree operations. As we explained in the last challenge, we face worst case time complexity for heavily unbalanced trees. Self-balancing trees are commonly used to account for this issue in trees with dynamic data sets. Common examples of these include AVL trees, red-black trees, and B-trees. These trees all contain additional internal logic which re-balance the tree when insertions or deletions create a state of imbalance.", + "Note: A similar property to height is depth, which refers to how far a given node is from the root node.", + "Instructions: Write two methods for our binary tree: findMinHeight and findMaxHeight. These methods should return an integer value for the minimum and maximum height within a given binary tree, respectively. If the node is empty let's assign it a height of -1 (that's the base case). Finally, add a third method isBalanced which returns true or false depending on whether the tree is balanced or not. You can use the first two methods you just wrote to determine this." + ], + "tests": [ + { + "text": "The BinarySearchTree data structure exists.", + "testString": "assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() }; return (typeof test == 'object')})(), 'The BinarySearchTree data structure exists.');" + }, + { + "text": "The binary search tree has a method called findMinHeight.", + "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 findMinHeight.');" + }, + { + "text": "The binary search tree has a method called findMaxHeight.", + "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 findMaxHeight.');" + }, + { + "text": "The binary search tree has a method called isBalanced.", + "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 isBalanced.');" + }, + { + "text": "The findMinHeight method returns the minimum height of the tree.", + "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 findMinHeight method returns the minimum height of the tree.');" + }, + { + "text": "The findMaxHeight method returns the maximum height of the tree.", + "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 findMaxHeight method returns the maximum height of the tree.');" + }, + { + "text": "An empty tree returns a height of -1.", + "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 -1.');" + }, + { + "text": "The isBalanced method returns true if the tree is a balanced binary search tree.", + "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 isBalanced method returns true if the tree is a balanced binary search tree.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "BinarySearchTree.prototype = {\n add: function(value) {\n var node = this.root;\n if (node == null) {\n this.root = new Node(value);\n return;\n } else {\n function searchTree(node) {\n if (value < node.value) {\n if (node.left == null) {\n node.left = new Node(value);\n return;\n } else if (node.left != null) {\n return searchTree(node.left)\n };\n } else if (value > node.value) {\n if (node.right == null) {\n node.right = new Node(value);\n return;\n } else if (node.right != null) {\n return searchTree(node.right);\n };\n } else {\n return null;\n };\n };\n return searchTree(node);\n };\n }\n};" + } + } + }, + { + "id": "587d8257367417b2b2512c7e", + "title": "Use Depth First Search in a Binary Search Tree", + "description": [ + "We know how to search a binary search tree for a specific value. But what if we just want to explore the entire tree? Or what if we don't have an ordered tree and we need to just search for a value? Here we will introduce some tree traversal methods which can be used to explore tree data structures. First up is depth-first search. In depth-first search, a given subtree is explored as deeply as possible before the search continues on to another subtree. There are three ways this can be done:", + "In-order: Begin the search at the left-most node and end at the right-most node.", + "Pre-order: Explore all the roots before the leaves.", + "Post-order: Explore all the leaves before the roots.", + "As you may guess, you may choose different search methods depending on what type of data your tree is storing and what you are looking for. For a binary search tree, an inorder traversal returns the nodes in sorted order.", + "Instructions: Here we will create these three search methods on our binary search tree. Depth-first search is an inherently recursive operation which continues to explore further subtrees so long as child nodes are present. Once you understand this basic concept, you can simply rearrange the order in which you explore the nodes and subtrees to produce any of the three searches above. For example, in post-order search we would want to recurse all the way to a leaf node before we begin to return any of the nodes themselves, whereas in pre-order search we would want to return the nodes first, and then continue recursing down the tree.", + "Define inorder, preorder, and postorder methods on our tree. Each of these methods should return an array of items which represent the tree traversal. Be sure to return the integer values at each node in the array, not the nodes themselves. Finally, return null if the tree is empty." + ], + "tests": [ + { + "text": "The BinarySearchTree data structure exists.", + "testString": "assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() }; return (typeof test == 'object')})(), 'The BinarySearchTree data structure exists.');" + }, + { + "text": "The binary search tree has a method called inorder.", + "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 inorder.');" + }, + { + "text": "The binary search tree has a method called preorder.", + "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 preorder.');" + }, + { + "text": "The binary search tree has a method called postorder.", + "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 postorder.');" + }, + { + "text": "The inorder method returns an array of the node values that result from an inorder traversal.", + "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 inorder method returns an array of the node values that result from an inorder traversal.');" + }, + { + "text": "The preorder method returns an array of the node values that result from a preorder traversal.", + "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 preorder method returns an array of the node values that result from a preorder traversal.');" + }, + { + "text": "The postorder method returns an array of the node values that result from a postorder traversal.", + "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 postorder method returns an array of the node values that result from a postorder traversal.');" + }, + { + "text": "The inorder method returns null for an empty tree.", + "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 inorder method returns null for an empty tree.');" + }, + { + "text": "The preorder method returns null for an empty tree.", + "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 preorder method returns null for an empty tree.');" + }, + { + "text": "The postorder method returns null for an empty tree.", + "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 postorder method returns null for an empty tree.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "BinarySearchTree.prototype = {\n add: function(value) {\n var node = this.root;\n if (node == null) {\n this.root = new Node(value);\n return;\n } else {\n function searchTree(node) {\n if (value < node.value) {\n if (node.left == null) {\n node.left = new Node(value);\n return;\n } else if (node.left != null) {\n return searchTree(node.left)\n };\n } else if (value > node.value) {\n if (node.right == null) {\n node.right = new Node(value);\n return;\n } else if (node.right != null) {\n return searchTree(node.right);\n };\n } else {\n return null;\n };\n };\n return searchTree(node);\n };\n }\n};" + } + } + }, + { + "id": "587d8258367417b2b2512c7f", + "title": "Use Breadth First Search in a Binary Search Tree", + "description": [ + "Here we will introduce another tree traversal method: breadth-first search. In contrast to the depth-first search methods from the last challenge, breadth-first search explores all the nodes in a given level within a tree before continuing on to the next level. Typically, queues are utilized as helper data structures in the design of breadth-first search algorithms.", + "In this method, we start by adding the root node to a queue. Then we begin a loop where we dequeue the first item in the queue, add it to a new array, and then inspect both its child subtrees. If its children are not null, they are each enqueued. This process continues until the queue is empty.", + "Instructions: Let's create a breadth-first search method in our tree called levelOrder. This method should return an array containing the values of all the tree nodes, explored in a breadth-first manner. Be sure to return the values in the array, not the nodes themselves. A level should be traversed from left to right. Next, let's write a similar method called reverseLevelOrder which performs the same search but in the reverse direction (right to left) at each level." + ], + "tests": [ + { + "text": "The BinarySearchTree data structure exists.", + "testString": "assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() }; return (typeof test == 'object')})(), 'The BinarySearchTree data structure exists.');" + }, + { + "text": "The binary search tree has a method called levelOrder.", + "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 levelOrder.');" + }, + { + "text": "The binary search tree has a method called reverseLevelOrder.", + "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 reverseLevelOrder.');" + }, + { + "text": "The levelOrder method returns an array of the tree node values explored in level order.", + "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 levelOrder method returns an array of the tree node values explored in level order.');" + }, + { + "text": "The reverseLevelOrder method returns an array of the tree node values explored in reverse level order.", + "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 reverseLevelOrder method returns an array of the tree node values explored in reverse level order.');" + }, + { + "text": "The levelOrder method returns null for an empty tree.", + "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 levelOrder method returns null for an empty tree.');" + }, + { + "text": "The reverseLevelOrder method returns null for an empty tree.", + "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 reverseLevelOrder method returns null for an empty tree.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "BinarySearchTree.prototype = {\n add: function(value) {\n var node = this.root;\n if (node == null) {\n this.root = new Node(value);\n return;\n } else {\n function searchTree(node) {\n if (value < node.value) {\n if (node.left == null) {\n node.left = new Node(value);\n return;\n } else if (node.left != null) {\n return searchTree(node.left)\n };\n } else if (value > node.value) {\n if (node.right == null) {\n node.right = new Node(value);\n return;\n } else if (node.right != null) {\n return searchTree(node.right);\n };\n } else {\n return null;\n };\n };\n return searchTree(node);\n };\n }\n};" + } + } + }, + { + "id": "587d8258367417b2b2512c80", + "title": "Delete a Leaf Node in a Binary Search Tree", + "description": [ + "This is the first of three challenges where we will implement a more difficult operation in binary search trees: deletion. Deletion is difficult because removing nodes breaks links in the tree. These links must be carefully reestablished to ensure the binary tree structure is maintained. For some deletions, this means the tree must be rearranged. In general, you will encounter one of three cases when trying to delete a node:", + "Leaf Node: The target to delete has zero children.", + "One Child: The target to delete only has one child.", + "Two Children: The target to delete has two child nodes.", + "Removing a leaf node is easy, we simply remove it. Deleting a node with one child is also relatively easy, we simply remove it and link its parent to child of the node we deleted. Removing a node with two children is more difficult, however, because this creates two child nodes that need to be reconnected to the parent tree. We'll see how to deal with this case in the third challenge. Additionally, you need to be mindful of some edge cases when handling deletion. What if the tree is empty? What if the node to delete is the root node? What if there are only two elements in the tree? For now, let's handle the first case where we delete a leaf node.", + "Instructions: Create a method on our binary tree called remove. We'll build the logic for our deletion operation in here. First, you'll want to create a function within remove that finds the node we are trying to delete in the current tree. If the node is not present in the tree, remove should return null. Now, if the target node is a leaf node with no children, then the parent reference to it should be set to null. This effectively deletes the node from the tree. To do this, you will have to keep track of the parent of the node we are trying to delete as well. It will also be useful to create a way to track the number of children the target node has, as this will determine which case our deletion falls under.", + "We will handle the second and third cases in the next challenges. Good luck!" + ], + "tests": [ + { + "text": "The BinarySearchTree data structure exists.", + "testString": "assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() }; return (typeof test == 'object')})(), 'The BinarySearchTree data structure exists.');" + }, + { + "text": "The binary search tree has a method called remove.", + "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 remove.');" + }, + { + "text": "Trying to remove an element that does not exist returns null.", + "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 null.');" + }, + { + "text": "If the root node has no children, deleting it sets the root to null.", + "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 null.');" + }, + { + "text": "The remove method removes leaf nodes from the tree", + "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 remove method removes leaf nodes from the tree');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "BinarySearchTree.prototype = {\n add: function(value) {\n var node = this.root;\n if (node == null) {\n this.root = new Node(value);\n return;\n } else {\n function searchTree(node) {\n if (value < node.value) {\n if (node.left == null) {\n node.left = new Node(value);\n return;\n } else if (node.left != null) {\n return searchTree(node.left)\n };\n } else if (value > node.value) {\n if (node.right == null) {\n node.right = new Node(value);\n return;\n } else if (node.right != null) {\n return searchTree(node.right);\n };\n } else {\n return null;\n };\n };\n return searchTree(node);\n };\n },\n inorder: function() {\n if (this.root == null) {\n return null;\n } else {\n var result = new Array();\n function traverseInOrder(node) {\n if (node.left != null) {\n traverseInOrder(node.left);\n };\n result.push(node.value);\n if (node.right != null) {\n traverseInOrder(node.right);\n };\n }\n traverseInOrder(this.root);\n return result;\n };\n }, \n isBinarySearchTree() {\n if (this.root == null) {\n return null;\n } else {\n var check = true;\n function checkTree(node) {\n if (node.left != null) {\n var left = node.left;\n if (left.value > node.value) {\n check = false;\n } else {\n checkTree(left);\n }\n }\n if (node.right != null) {\n var right = node.right;\n if (right.value < node.value) {\n check = false;\n } else {\n checkTree(right);\n };\n };\n };\n checkTree(this.root);\n return check;\n }\n }\n};" + } + } + }, + { + "id": "587d8258367417b2b2512c81", + "title": "Delete a Node with One Child in a Binary Search Tree", + "description": [ + "Now that we can delete leaf nodes let's move on to the second case: deleting a node with one child. For this case, say we have a tree with the following nodes 1 — 2 — 3 where 1 is the root. To delete 2, we simply need to make the right reference in 1 point to 3. More generally to delete a node with only one child, we make that node's parent reference the next node in the tree.", + "Instructions: We've provided some code in our remove method that accomplishes the tasks from the last challenge. We find the target to delete and its parent and define the number of children the target node has. Let's add the next case here for target nodes with only one child. Here, we'll have to determine if the single child is a left or right branch in the tree and then set the correct reference in the parent to point to this node. In addition, let's account for the case where the target is the root node (this means the parent node will be null). Feel free to replace all the starter code with your own as long as it passes the tests." + ], + "tests": [ + { + "text": "The BinarySearchTree data structure exists.", + "testString": "assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() }; return (typeof test == 'object')})(), 'The BinarySearchTree data structure exists.');" + }, + { + "text": "The binary search tree has a method called remove.", + "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 remove.');" + }, + { + "text": "Trying to remove an element that does not exist returns null.", + "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 null.');" + }, + { + "text": "If the root node has no children, deleting it sets the root to null.", + "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 null.');" + }, + { + "text": "The remove method removes leaf nodes from the tree", + "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 remove method removes leaf nodes from the tree');" + }, + { + "text": "The remove method removes nodes with one child.", + "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 remove method removes nodes with one child.');" + }, + { + "text": "Removing the root in a tree with two nodes sets the second to be the root.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + " };", + "}" + ], + "head": "", + "tail": "BinarySearchTree.prototype = {\n add: function(value) {\n var node = this.root;\n if (node == null) {\n this.root = new Node(value);\n return;\n } else {\n function searchTree(node) {\n if (value < node.value) {\n if (node.left == null) {\n node.left = new Node(value);\n return;\n } else if (node.left != null) {\n return searchTree(node.left)\n };\n } else if (value > node.value) {\n if (node.right == null) {\n node.right = new Node(value);\n return;\n } else if (node.right != null) {\n return searchTree(node.right);\n };\n } else {\n return null;\n };\n };\n return searchTree(node);\n };\n },\n inorder: function() {\n if (this.root == null) {\n return null;\n } else {\n var result = new Array();\n function traverseInOrder(node) {\n if (node.left != null) {\n traverseInOrder(node.left);\n };\n result.push(node.value);\n if (node.right != null) {\n traverseInOrder(node.right);\n };\n }\n traverseInOrder(this.root);\n return result;\n };\n }, \n isBinarySearchTree() {\n if (this.root == null) {\n return null;\n } else {\n var check = true;\n function checkTree(node) {\n if (node.left != null) {\n var left = node.left;\n if (left.value > node.value) {\n check = false;\n } else {\n checkTree(left);\n }\n }\n if (node.right != null) {\n var right = node.right;\n if (right.value < node.value) {\n check = false;\n } else {\n checkTree(right);\n };\n };\n };\n checkTree(this.root);\n return check;\n }\n }\n};" + } + } + }, + { + "id": "587d8258367417b2b2512c82", + "title": "Delete a Node with Two Children in a Binary Search Tree", + "description": [ + "Removing nodes that have two children is the hardest case to implement. Removing a node like this produces two subtrees that are no longer connected to the original tree structure. How can we reconnect them? One method is to find the smallest value in the right subtree of the target node and replace the target node with this value. Selecting the replacement in this way ensures that it is greater than every node in the left subtree it becomes the new parent of but also less than every node in the right subtree it becomes the new parent of.", + "Once this replacement is made the replacement node must be removed from the right subtree. Even this operation is tricky because the replacement may be a leaf or it may itself be the parent of a right subtree. If it is a leaf we must remove its parent's reference to it. Otherwise, it must be the right child of the target. In this case, we must replace the target value with the replacement value and make the target reference the replacement's right child.", + "Instructions: Let's finish our remove method by handling the third case. We've provided some code again for the first two cases. Add some code now to handle target nodes with two children. Any edge cases to be aware of? What if the tree has only three nodes? Once you are finished this will complete our deletion operation for binary search trees. Nice job, this is a pretty hard problem!" + ], + "tests": [ + { + "text": "The BinarySearchTree data structure exists.", + "testString": "assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() }; return (typeof test == 'object')})(), 'The BinarySearchTree data structure exists.');" + }, + { + "text": "The binary search tree has a method called remove.", + "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 remove.');" + }, + { + "text": "Trying to remove an element that does not exist returns null.", + "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 null.');" + }, + { + "text": "If the root node has no children, deleting it sets the root to null.", + "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 null.');" + }, + { + "text": "The remove method removes leaf nodes from the tree", + "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 remove method removes leaf nodes from the tree');" + }, + { + "text": "The remove method removes nodes with one child.", + "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 remove method removes nodes with one child.');" + }, + { + "text": "Removing the root in a tree with two nodes sets the second to be the root.", + "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": "The remove method removes nodes with two children while maintaining the binary search tree structure.", + "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 remove method removes nodes with two children while maintaining the binary search tree structure.');" + }, + { + "text": "The root can be removed on a tree of three nodes.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + " };", + "}" + ], + "head": "", + "tail": "BinarySearchTree.prototype = {\n add: function(value) {\n var node = this.root;\n if (node == null) {\n this.root = new Node(value);\n return;\n } else {\n function searchTree(node) {\n if (value < node.value) {\n if (node.left == null) {\n node.left = new Node(value);\n return;\n } else if (node.left != null) {\n return searchTree(node.left)\n };\n } else if (value > node.value) {\n if (node.right == null) {\n node.right = new Node(value);\n return;\n } else if (node.right != null) {\n return searchTree(node.right);\n };\n } else {\n return null;\n };\n };\n return searchTree(node);\n };\n },\n inorder: function() {\n if (this.root == null) {\n return null;\n } else {\n var result = new Array();\n function traverseInOrder(node) {\n if (node.left != null) {\n traverseInOrder(node.left);\n };\n result.push(node.value);\n if (node.right != null) {\n traverseInOrder(node.right);\n };\n }\n traverseInOrder(this.root);\n return result;\n };\n }, \n isBinarySearchTree() {\n if (this.root == null) {\n return null;\n } else {\n var check = true;\n function checkTree(node) {\n if (node.left != null) {\n var left = node.left;\n if (left.value > node.value) {\n check = false;\n } else {\n checkTree(left);\n }\n }\n if (node.right != null) {\n var right = node.right;\n if (right.value < node.value) {\n check = false;\n } else {\n checkTree(right);\n };\n };\n };\n checkTree(this.root);\n return check;\n }\n }\n};" + } + } + }, + { + "id": "587d8259367417b2b2512c83", + "title": "Invert a Binary Tree", + "description": [ + "Here will we create a function to invert a binary tree. Given a binary tree, we want to produce a new tree that is equivalently the mirror image of this tree. Running an inorder traversal on an inverted tree will explore the nodes in reverse order when compared to the inorder traversal of the original tree. Write a method to do this called invert on our binary tree. Calling this method should invert the current tree structure. Ideally, we would like to do this in-place in linear time. That is, we only visit each node once and we modify the existing tree structure as we go, without using any additional memory. Good luck!" + ], + "tests": [ + { + "text": "The BinarySearchTree data structure exists.", + "testString": "assert((function() { var test = false; if (typeof BinarySearchTree !== 'undefined') { test = new BinarySearchTree() }; return (typeof test == 'object')})(), 'The BinarySearchTree data structure exists.');" + }, + { + "text": "The binary search tree has a method called invert.", + "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 invert.');" + }, + { + "text": "The invert method correctly inverts the tree structure.", + "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 invert method correctly inverts the tree structure.');" + }, + { + "text": "Inverting an empty tree returns null.", + "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 null.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "}" + ], + "head": "", + "tail": "BinarySearchTree.prototype = {\n add: function(value) {\n var node = this.root;\n if (node == null) {\n this.root = new Node(value);\n return;\n } else {\n function searchTree(node) {\n if (value < node.value) {\n if (node.left == null) {\n node.left = new Node(value);\n return;\n } else if (node.left != null) {\n return searchTree(node.left)\n };\n } else if (value > node.value) {\n if (node.right == null) {\n node.right = new Node(value);\n return;\n } else if (node.right != null) {\n return searchTree(node.right);\n };\n } else {\n return null;\n };\n };\n return searchTree(node);\n };\n },\n inorder: function() {\n if (this.root == null) {\n return null;\n } else {\n var result = new Array();\n function traverseInOrder(node) {\n if (node.left != null) {\n traverseInOrder(node.left);\n };\n result.push(node.value);\n if (node.right != null) {\n traverseInOrder(node.right);\n };\n }\n traverseInOrder(this.root);\n return result;\n };\n }\n};" + } + } + }, + { + "id": "587d8259367417b2b2512c84", + "title": "Create a Trie Search Tree", + "description": [ + "Here we will move on from binary search trees and take a look at another type of tree structure called a trie. A trie is an ordered search tree commonly used to hold strings, or more generically associative arrays or dynamic datasets in which the keys are strings. They are very good at storing sets of data when many keys will have overlapping prefixes, for example, all the words in a dictionary.", + "Unlike a binary tree, nodes are not associated with actual values. Instead, the path to a node represents a specific key. For instance, if we wanted to store the string code in a trie, we would have four nodes, one for each letter: c — o — d — e. Following that path through all these nodes will then create code as a string — that path is the key we stored. Then, if we wanted to add the string coding, it would share the first three nodes of code before branching away after the d. In this way, large datasets can be stored very compactly. In addition, search can be very quick because it is effectively limited to the length of the string you are storing. Furthermore, unlike binary trees a node can store any number of child nodes.", + "As you might have guessed from the above example, some metadata is commonly stored at nodes that hold the end of a key so that on later traversals that key can still be retrieved. For instance, if we added codes in our example above we would need some way to know that the e in code represents the end of a key that was previously entered. Otherwise, this information would effectively be lost when we add codes.", + "Instructions: Let's create a trie to store words. It will accept words through an add method and store these in a trie data structure. It will also allow us to query if a given string is a word with an isWord method, and retrieve all the words entered into the trie with a print method. isWord should return a boolean value and print should return an array of all these words as string values.", + "In order for us to verify that this data structure is implemented correctly, we've provided a Node structure for each node in the tree. Each node will be an object with a keys property which is a JavaScript Map object. This will hold the individual letters that are valid keys of each node. We've also created an end property on the nodes that can be set to true if the node represents the termination of a word." + ], + "tests": [ + { + "text": "The Trie has an add method.", + "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": "The Trie has a print method.", + "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": "The Trie has an isWord method.", + "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": "The print method returns all items added to the trie as strings in an array.", + "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": "The isWord method returns true only for words added to the trie and false for all other words.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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", + "};" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d825a367417b2b2512c8a", + "title": "Insert an Element into a Max Heap", + "description": [ + "Now we will move on to another tree data structure, the binary heap. A binary heap is a partially ordered binary tree which satisfies the heap property. The heap property specifies a relationship between parent and child nodes. You may have a max heap, in which all parent nodes are greater than or equal to their child nodes, or a min heap, in which the reverse is true. Binary heaps are also complete binary trees. This means that all levels of the tree are fully filled and if the last level is partially filled it is filled from left to right.", + "While binary heaps may be implemented as tree structures with nodes that contain left and right references, the partial ordering according to the heap property allows us to represent the heap with an array. The parent-children relationship is what we're interested in and with simple arithmetic we can compute the children of any parent and the parent of any child node.", + "For instance, consider this array representation of a binary min heap:", + "[ 6, 22, 30, 37, 63, 48, 42, 76 ]", + "The root node is the first element, 6. Its children are 22 and 30. If we look at the relationship between the array indices of these values, for index i the children are 2 * i + 1 and 2 * i + 2. Similarly, the element at index 0 is the parent of these two children at indices 1 and 2. More generally, we can find the parent of a node at any index with the following: (i - 1) / 2. These patterns will hold true as the binary tree grows to any size. Finally, we can make a slight adjustment to make this arithmetic even easier by skipping the first element in the array. Doing this creates the following relationship for any element at a given index i:", + "Example Array representation:", + "[ null, 6, 22, 30, 37, 63, 48, 42, 76 ]", + "An element's left child: i * 2", + "An element's right child: i * 2 + 1", + "An element's parent: i / 2", + "Once you wrap your head around the math, using an array representation is very useful because node locations can be quickly determined with this arithmetic and memory usage is diminished because you don't need to maintain references to child nodes.", + "Instructions: Here we will create a max heap. Start by just creating an insert method which adds elements to our heap. During insertion, it is important to always maintain the heap property. For a max heap this means the root element should always have the greatest value in the tree and all parent nodes should be greater than their children. For an array implementation of a heap, this is typically accomplished in three steps:", + "Add the new element to the end of the array.", + "If the element is larger than its parents, switch them.", + "Continue switching until the new element is either smaller than its parent or you reach the root of the tree.", + "Finally, add a print method which returns an array of all the items that have been added to the heap." + ], + "tests": [ + { + "text": "The MaxHeap data structure exists.", + "testString": "assert((function() { var test = false; if (typeof MaxHeap !== 'undefined') { test = new MaxHeap() }; return (typeof test == 'object')})(), 'The MaxHeap data structure exists.');" + }, + { + "text": "MaxHeap has a method called insert.", + "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 has a method called print.", + "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": "The insert method adds elements according to the max heap property.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "var MaxHeap = function() {", + " // change code below this line", + " // change code above this line", + "};" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d825b367417b2b2512c8b", + "title": "Remove an Element from a Max Heap", + "description": [ + "Now that we can add elements to our heap let's see how we can remove elements. Removing and inserting elements both require similar logic. In a max heap you will usually want to remove the greatest value, so this involves simply extracting it from the root of our tree. This will break the heap property of our tree, so we must reestablish it in some way. Typically, for a max heap this is done in the following way:", + "Move the last element in the heap into the root position.", + "If either child of the root is greater than it, swap the root with the child of greater value.", + "Continue swapping until the parent is greater than both children, or you reach the last level in the tree.", + "Instructions: Add a method to our max heap called remove. This method should return the greatest value that has been added to our max heap and remove it from the heap. It should also reorder the heap so the heap property is maintained. After removing an element, the next greatest element remaining in the heap should become the root. Add your insert method again here as well." + ], + "tests": [ + { + "text": "The MaxHeap data structure exists.", + "testString": "assert((function() { var test = false; if (typeof MaxHeap !== 'undefined') { test = new MaxHeap() }; return (typeof test == 'object')})(), 'The MaxHeap data structure exists.');" + }, + { + "text": "MaxHeap has a method called print.", + "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 has a method called insert.", + "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 has a method called remove.", + "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": "The remove method removes the greatest element from the max heap while maintaining the max heap property.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "var MaxHeap = function() {", + " // change code below this line", + " // change code above this line", + "};" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d825b367417b2b2512c8c", + "title": "Implement Heap Sort with a Min Heap", + "description": [ + "Now that we can add and remove elements let's see some of the applications heaps can be used for. Heaps are commonly used to implement priority queues because they always store an item of greatest or least value in first position. In addition, they are used to implement a sorting algorithm called heap sort. We'll see how to do this here. Heap sort uses a min heap, the reverse of a max heap. A min heap always stores the element of least value in the root position.", + "Heap sort works by taking an unsorted array, adding each item in the array into a min heap, and then extracting every item out of the min heap into a new array. The min heap structure ensures that the new array will contain the original items in least to greatest order. This is one of the most efficient sorting algorithms with average and worst case performance of O(nlog(n)).", + "Instructions: Let's implement heap sort with a min heap. Feel free to adapt your max heap code here. Create an object MinHeap with insert, remove, and sort methods. The sort method should return an array of all the elements in the min heap sorted from smallest to largest." + ], + "tests": [ + { + "text": "The MinHeap data structure exists.", + "testString": "assert((function() { var test = false; if (typeof MinHeap !== 'undefined') { test = new MinHeap() }; return (typeof test == 'object')})(), 'The MinHeap data structure exists.');" + }, + { + "text": "MinHeap has a method called insert.", + "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 has a method called remove.", + "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 has a method called sort.", + "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": "The sort method returns an array containing all items added to the min heap in sorted order.", + "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.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "// 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", + "};" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8256367417b2b2512c77", + "title": "Adjacency List", + "description": [ + "Graphs can be represented in different ways. Here we describe one way, which is called an adjacency list.", + "An adjacency list is essentially a bulleted list where the left side is the node and the right side lists all the other nodes it's connected to. Below is a representation of an adjacency list.", + "
Node1: Node2, Node3
Node2: Node1
Node3: Node1
", + "Above is an undirected graph because Node1 is connected to Node2 and Node3, and that information is consistent with the connections Node2 and Node3 show. An adjacency list for a directed graph would mean each row of the list shows direction. If the above was directed, then Node2: Node1 would mean there the directed edge is pointing from Node2 towards Node1.", + "We can represent the undirected graph above as an adjacency list by putting it within a JavaScript object.", + "
var undirectedG = {
Node1: [\"Node2\", \"Node3\"],
Node2: [\"Node1\"],
Node3: [\"Node1\"]
};
", + "This can also be more simply represented as an array where the nodes just have numbers rather than string labels.", + "
var undirectedGArr = [
[1, 2], # Node1
[0], # Node2
[0] # Node3
];
", + "
", + "Create a social network as an undirected graph with 4 nodes/people named James, Jill, Jenny, and Jeff. There are edges/relationships between James and Jeff, Jill and Jenny, and Jeff and Jenny." + ], + "tests": [ + { + "text": "undirectedAdjList should only contain four nodes.", + "testString": "assert(Object.keys(undirectedAdjList).length === 4, 'undirectedAdjList should only contain four nodes.');" + }, + { + "text": "There should be an edge between Jeff and James.", + "testString": "assert(undirectedAdjList.James.indexOf(\"Jeff\") !== -1 && undirectedAdjList.Jeff.indexOf(\"James\") !== -1, 'There should be an edge between Jeff and James.');" + }, + { + "text": "There should be an edge between Jill and Jenny.", + "testString": "assert(undirectedAdjList.Jill.indexOf(\"Jenny\") !== -1 && undirectedAdjList.Jill.indexOf(\"Jenny\") !== -1, 'There should be an edge between Jill and Jenny.');" + }, + { + "text": "There should be an edge between Jeff and Jenny.", + "testString": "assert(undirectedAdjList.Jeff.indexOf(\"Jenny\") !== -1 && undirectedAdjList.Jenny.indexOf(\"Jeff\") !== -1, 'There should be an edge between Jeff and Jenny.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "var undirectedAdjList = {\n\"James\": [\"Jeff\"],\"Jill\": [\"Jenny\"],\"Jenny\": [\"Jill\", \"Jeff\"],\n\"Jeff\": [\"James\", \"Jenny\"]\n};" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "var undirectedAdjList = {", + "};" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8256367417b2b2512c78", + "title": "Adjacency Matrix", + "description": [ + "Another way to represent a graph is to put it in an adjacency matrix.", + "An adjacency matrix is a two-dimensional (2D) array where each nested array has the same number of elements as the outer array. In other words, it is a matrix or grid of numbers, where the numbers represent the edges. Zeros mean there is no edge or relationship.", + "
1 2 3
------
1 | 0 1 1
2 | 1 0 0
3 | 1 0 0
", + "Above is a very simple, undirected graph where you have three nodes, where the first node is connected to the second and third node. Note: The numbers to the top and left of the matrix are just labels for the nodes.", + "Below is a JavaScript implementation of the same thing.", + "
var adjMat = [
[0, 1, 1],
[1, 0, 0],
[1, 0, 0]
];
", + "Unlike an adjacency list, each \"row\" of the matrix has to have the same number of elements as nodes in the graph. Here we have a three by three matrix, which means we have three nodes in our graph.", + "A directed graph would look similar. Below is a graph where the first node has an edge pointing toward the second node, and then the second node has an edge pointing to the third node.", + "
var adjMatDirected = [
[0, 1, 0],
[0, 0, 1],
[0, 0, 0]
];
", + "Graphs can also have weights on their edges. So far, we have unweighted edges where just the presence and lack of edge is binary (0 or 1). You can have different weights depending on your application.", + "
", + "Create an adjacency matrix of an undirected graph with five nodes. This matrix should be in a multi-dimensional array. These five nodes have relationships between the first and fourth node, the first and third node, the third and fifth node, and the fourth and fifth node. All edge weights are one." + ], + "tests": [ + { + "text": "undirectedAdjList should only contain five nodes.", + "testString": "assert((adjMatUndirected.length === 5) && adjMatUndirected.map(function(x) { return x.length === 5 }).reduce(function(a, b) { return a && b }) , 'undirectedAdjList should only contain five nodes.');" + }, + { + "text": "There should be an edge between the first and fourth node.", + "testString": "assert((adjMatUndirected[0][3] === 1) && (adjMatUndirected[3][0] === 1), 'There should be an edge between the first and fourth node.');" + }, + { + "text": "There should be an edge between the first and third node.", + "testString": "assert((adjMatUndirected[0][2] === 1) && (adjMatUndirected[2][0] === 1), 'There should be an edge between the first and third node.');" + }, + { + "text": "There should be an edge between the third and fifth node.", + "testString": "assert((adjMatUndirected[2][4] === 1) && (adjMatUndirected[4][2] === 1), 'There should be an edge between the third and fifth node.');" + }, + { + "text": "There should be an edge between the fourth and fifth node.", + "testString": "assert((adjMatUndirected[3][4] === 1) && (adjMatUndirected[4][3] === 1), 'There should be an edge between the fourth and fifth node.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "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]];" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "var adjMatUndirected = [", + "];" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d8256367417b2b2512c79", + "title": "Incidence Matrix", + "description": [ + "Yet another way to represent a graph is to put it in an incidence matrix.", + "An incidence matrix is a two-dimensional (2D) array. Generally speaking, an incidence matrix relates two different classes of objects between its two dimensions. This kind of matrix is similar to an adjacency matrix. However, the rows and columns mean something else here.", + "In graphs, we have edges and nodes. These will be our \"two different classes of objects\". This matrix will have the rows be the nodes and columns be the edges. This means that we can have an uneven number of rows and columns.", + "Each column will represent a unique edge. Also, each edge connects two nodes. To show that there is an edge between two nodes, you will put a 1 in the two rows of a particular column. Below is a 3 node graph with one edge between node 1 and node 3.", + "
1
---
1 | 1
2 | 0
3 | 1
", + "Here is an example of an incidence matrix with 4 edges and 4 nodes. Remember, the columns are the edges and rows are the nodes themselves.", + "
1 2 3 4
--------
1 | 0 1 1 1
2 | 1 1 0 0
3 | 1 0 0 1
4 | 0 0 1 0
", + "Below is a JavaScript implementation of the same thing.", + "
var incMat = [
[0, 1, 1, 1],
[1, 1, 0, 0],
[1, 0, 0, 1],
[0, 0, 1, 0]
];
", + "To make a directed graph, use -1 for an edge leaving a particular node and 1 for an edge entering a node.", + "
var incMatDirected = [
[ 0, -1, 1, -1],
[-1, 1, 0, 0],
[ 1, 0, 0, 1],
[ 0, 0, -1, 0]
];
", + "Graphs can also have weights on their edges. So far, we have unweighted edges where just the presence and lack of edge is binary (0 or 1). You can have different weights depending on your application. A different weight is represented as numbers greater than 1.", + "
", + "Create an incidence matrix of an undirected graph with five nodes and four edges. This matrix should be in a multi-dimensional array.", + "These five nodes have relationships following relationships. The first edge is between the first and second node. The second edge is between the second and third node. The third edge is between the third and fifth node. And four edge is between the fourth and second node. All edge weights are one and the edge order matters." + ], + "tests": [ + { + "text": "incMatUndirected should only contain five nodes.", + "testString": "assert((incMatUndirected.length === 5) && incMatUndirected.map(function(x) { return x.length === 4 }).reduce(function(a, b) { return a && b }) , 'incMatUndirected should only contain five nodes.');" + }, + { + "text": "There should be a first edge between the first and second node.", + "testString": "assert((incMatUndirected[0][0] === 1) && (incMatUndirected[1][0] === 1), 'There should be a first edge between the first and second node.');" + }, + { + "text": "There should be a second edge between the second and third node.", + "testString": "assert((incMatUndirected[1][1] === 1) && (incMatUndirected[2][1] === 1), 'There should be a second edge between the second and third node.');" + }, + { + "text": "There should be a third edge between the third and fifth node.", + "testString": "assert((incMatUndirected[2][2] === 1) && (incMatUndirected[4][2] === 1), 'There should be a third edge between the third and fifth node.');" + }, + { + "text": "There should be a fourth edge between the second and fourth node.", + "testString": "assert((incMatUndirected[1][3] === 1) && (incMatUndirected[3][3] === 1), 'There should be a fourth edge between the second and fourth node.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "var incMatUndirected = [[1, 0, 0, 0],[1, 1, 0, 1],[0, 1, 1, 0],[0, 0, 0, 1],[0, 0, 1, 0]];" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "var incMatUndirected = [", + " ", + "];" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "587d825c367417b2b2512c90", + "title": "Breadth-First Search", + "description": [ + "So far, we've learned different ways of creating representations of graphs. What now? One natural question to have is what are the distances between any two nodes in the graph? Enter graph traversal algorithms.", + "Traversal algorithms are algorithms to traverse or visit nodes in a graph. One type of traversal algorithm is the breadth-first search algorithm.", + "This algorithm starts at one node, first visits all its neighbors that are one edge away, then goes on to visiting each of their neighbors.", + "Visually, this is what the algorithm is doing.", + "", + "To implement this algorithm, you'll need to input a graph structure and a node you want to start at.", + "First, you'll want to be aware of the distances from the start node. This you'll want to start all your distances initially some large number, like Infinity. This gives a reference for the case where a node may not be reachable from your start node.", + "Next, you'll want to go from the start node to its neighbors. These neighbors are one edge away and at this point you should add one unit of distance to the distances you're keeping track of.", + "Last, an important data structure that will help implement the breadth-first search algorithm is the queue. This is an array where you can add elements to one end and remove elements from the other end. This is also known as a FIFO or First-In-First-Out data structure.", + "
", + "Write a function bfs() that takes an adjacency matrix graph (a two-dimensional array) and a node label root as parameters. The node label will just be the integer value of the node between 0 and n - 1, where n is the total number of nodes in the graph.", + "Your function will output a JavaScript object key-value pairs with the node and its distance from the root. If the node could not be reached, it should have a distance of Infinity." + ], + "tests": [ + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]] with a start node of 1 should return {0: 1, 1: 0, 2: 1, 3: 2}", + "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 [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]] with a start node of 1 should return {0: 1, 1: 0, 2: 1, 3: 2}');" + }, + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]] with a start node of 1 should return {0: 1, 1: 0, 2: 1, 3: Infinity}", + "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 [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]] with a start node of 1 should return {0: 1, 1: 0, 2: 1, 3: Infinity}');" + }, + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]] with a start node of 0 should return {0: 0, 1: 1, 2: 2, 3: 3}", + "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 [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]] with a start node of 0 should return {0: 0, 1: 1, 2: 2, 3: 3}');" + }, + { + "text": "The input graph [[0, 1], [1, 0]] with a start node of 0 should return {0: 0, 1: 1}", + "testString": "assert((function() { var graph = [[0, 1], [1, 0]]; var results = bfs(graph, 0); return isEquivalent(results, {0: 0, 1: 1})})(), 'The input graph [[0, 1], [1, 0]] with a start node of 0 should return {0: 0, 1: 1}');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "function bfs(graph, root) {\n// Distance object returned\nvar nodesLen = {};\n// Set all distances to infinity\nfor (var i = 0; i < graph.length; i++) {\nnodesLen[i] = Infinity;\n}\nnodesLen[root] = 0; // ...except root node\nvar queue = [root]; // Keep track of nodes to visit\nvar current; // Current node traversing\n// Keep on going until no more nodes to traverse\nwhile (queue.length !== 0) {\ncurrent = queue.shift();\n// Get adjacent nodes from current node\nvar curConnected = graph[current]; // Get layer of edges from current\nvar neighborIdx = []; // List of nodes with edges\nvar idx = curConnected.indexOf(1); // Get first edge connection\nwhile (idx !== -1) {\nneighborIdx.push(idx); // Add to list of neighbors\nidx = curConnected.indexOf(1, idx + 1); // Keep on searching\n}\n// Loop through neighbors and get lengths\nfor (var j = 0; j < neighborIdx.length; j++) {\n// Increment distance for nodes traversed\nif (nodesLen[neighborIdx[j]] === Infinity) {\nnodesLen[neighborIdx[j]] = nodesLen[current] + 1;\nqueue.push(neighborIdx[j]); // Add new neighbors to queue\n}\n}\n}\nreturn nodesLen;}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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));" + ], + "head": "", + "tail": "// Source: http://adripofjavascript.com/blog/drips/object-equality-in-javascript.html\nfunction isEquivalent(a, b) {\n // Create arrays of property names\n var aProps = Object.getOwnPropertyNames(a);\n var bProps = Object.getOwnPropertyNames(b);\n // If number of properties is different,\n // objects are not equivalent\n if (aProps.length != bProps.length) {\n return false;\n }\n for (var i = 0; i < aProps.length; i++) {\n var propName = aProps[i];\n // If values of same property are not equal,\n // objects are not equivalent\n if (a[propName] !== b[propName]) {\n return false;\n }\n }\n // If we made it this far, objects\n // are considered equivalent\n return true;\n}" + } + } + }, + { + "id": "587d825d367417b2b2512c96", + "title": "Depth-First Search", + "description": [ + "Similar to breadth-first search, here we will learn about another graph traversal algorithm called depth-first search.", + "Whereas the breadth-first search searches incremental edge lengths away from the source node, depth-first search first goes down a path of edges as far as it can.", + "Once it reaches one end of a path, the search will backtrack to the last node with an un-visited edge path and continue searching.", + "Visually, this is what the algorithm is doing where the top node is the starting point of the search.", + "", + "A simple output of this algorithm is a list of nodes which are reachable from a given node. So when implementing this algorithm, you'll need to keep track of the nodes you visit.", + "
", + "Write a function dfs() that takes an undirected, adjacency matrix graph and a node label root as parameters. The node label will just be the numeric value of the node between 0 and n - 1, where n is the total number of nodes in the graph.", + "Your function should output an array of all nodes reachable from root." + ], + "tests": [ + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]] with a start node of 1 should return an array with 0, 1, 2, and 3.", + "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 [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]] with a start node of 1 should return an array with 0, 1, 2, and 3.');" + }, + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]] with a start node of 1 should return an array with four elements.", + "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 [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0]] with a start node of 1 should return an array with four elements.');" + }, + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]] with a start node of 3 should return an array with 3.", + "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 [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]] with a start node of 3 should return an array with 3.');" + }, + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]] with a start node of 3 should return an array with one element.", + "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 [[0, 1, 0, 0], [1, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 0]] with a start node of 3 should return an array with one element.');" + }, + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]] with a start node of 3 should return an array with 2 and 3.", + "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 [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]] with a start node of 3 should return an array with 2 and 3.');" + }, + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]] with a start node of 3 should return an array with two elements.", + "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 [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]] with a start node of 3 should return an array with two elements.');" + }, + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]] with a start node of 0 should return an array with 0 and 1.", + "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 [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]] with a start node of 0 should return an array with 0 and 1.');" + }, + { + "text": "The input graph [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]] with a start node of 0 should return an array with two elements.", + "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 [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]] with a start node of 0 should return an array with two elements.');" + } + ], + "type": "waypoint", + "releasedOn": "Feb 17, 2017", + "solutions": [ + "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;}" + ], + "challengeType": 1, + "translations": {}, + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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));" + ], + "head": "", + "tail": "" + } + } + } + ], + "fileName": "08-coding-interview-questions-and-take-home-assignments/coding-interview-data-structure-questions.json", + "superBlock": "coding-interview-questions-and-take-home-assignments", + "superOrder": 8 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/08-coding-interview-prep/project-euler.json b/packages/learn/seed/challenges/08-coding-interview-prep/project-euler.json new file mode 100644 index 0000000000..03d9484e8a --- /dev/null +++ b/packages/learn/seed/challenges/08-coding-interview-prep/project-euler.json @@ -0,0 +1,28221 @@ +{ + "name": "Project Euler", + "order": 6, + "time": "", + "helpRoom": "HelpJavaScript", + "challenges": [ + { + "id": "5900f36e1000cf542c50fe80", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 1: Multiples of 3 and 5", + "tests": [ + { + "text": "multiplesOf3and5(1000) should return 233168.", + "testString": "assert.strictEqual(multiplesOf3and5(1000), 233168, 'multiplesOf3and5(1000) should return 233168.');" + }, + { + "text": "multiplesOf3and5(49) should return 543.", + "testString": "assert.strictEqual(multiplesOf3and5(49), 543, 'multiplesOf3and5(49) should return 543.');" + }, + { + "text": "multiplesOf3and5(19564) should return 89301183.", + "testString": "assert.strictEqual(multiplesOf3and5(19564), 89301183, 'multiplesOf3and5(19564) should return 89301183.');" + }, + { + "text": "Your function is not returning the correct result using our tests values.", + "testString": "assert.strictEqual(multiplesOf3and5(8456), 16687353, 'Your function is not returning the correct result using our tests values.');" + } + ], + "solutions": [ + "const multiplesOf3and5 = (number) => {\n var total = 0;\n\n for(var i = 0; i < number; i++) {\n if(i % 3 == 0 || i % 5 == 0) {\n total += i;\n }\n }\n return total;\n};" + ], + "translations": {}, + "description": [ + "If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.", + "Find the sum of all the multiples of 3 or 5 below the provided parameter value number." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function multiplesOf3and5(number) {", + " // Good luck!", + " return true;", + "}", + "", + "multiplesOf3and5(1000);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f36e1000cf542c50fe81", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 2: Even Fibonacci Numbers", + "tests": [ + { + "text": "fiboEvenSum(10) should return 188.", + "testString": "assert.strictEqual(fiboEvenSum(10), 188, 'fiboEvenSum(10) should return 188.');" + }, + { + "text": "fiboEvenSum(23) should return 60696.", + "testString": "assert.strictEqual(fiboEvenSum(23), 60696, 'fiboEvenSum(23) should return 60696.');" + }, + { + "text": "fiboEvenSum(43) should return 1485607536.", + "testString": "assert.strictEqual(fiboEvenSum(43), 1485607536, 'fiboEvenSum(43) should return 1485607536.');" + }, + { + "text": "Your function is not returning the correct result using our tests values.", + "testString": "assert.strictEqual(fiboEvenSum(18), 3382, 'Your function is not returning the correct result using our tests values.');" + }, + { + "text": "Your function should return an even value.", + "testString": "assert.equal(fiboEvenSum(31) % 2 === 0, true, 'Your function should return an even value.');" + } + ], + "solutions": [ + "const fiboEvenSum = (number) => {\n let temp, sum = 0, a = 0, b = 1;\n while (number >= 0) {\n temp = a;\n a = b;\n b += temp;\n number --;\n if ((b % 2) === 0) {\n sum += b;\n }\n }\n\n return sum;\n}" + ], + "translations": {}, + "description": [ + "Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:", + "1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...", + "By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function fiboEvenSum(number) {", + " // You can do it!", + " return true;", + "}", + "", + "fiboEvenSum(10);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f36f1000cf542c50fe82", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 3: Largest prime factor", + "tests": [ + { + "text": "largestPrimeFactor(2) should return 2.", + "testString": "assert.strictEqual(largestPrimeFactor(2), 2, 'largestPrimeFactor(2) should return 2.');" + }, + { + "text": "largestPrimeFactor(3) should return 3.", + "testString": "assert.strictEqual(largestPrimeFactor(3), 3, 'largestPrimeFactor(3) should return 3.');" + }, + { + "text": "largestPrimeFactor(5) should return 5.", + "testString": "assert.strictEqual(largestPrimeFactor(5), 5, 'largestPrimeFactor(5) should return 5.');" + }, + { + "text": "largestPrimeFactor(7) should return 7.", + "testString": "assert.strictEqual(largestPrimeFactor(7), 7, 'largestPrimeFactor(7) should return 7.');" + }, + { + "text": "largestPrimeFactor(13195) should return 29.", + "testString": "assert.strictEqual(largestPrimeFactor(13195), 29, 'largestPrimeFactor(13195) should return 29.');" + }, + { + "text": "largestPrimeFactor(600851475143) should return 6857.", + "testString": "assert.strictEqual(largestPrimeFactor(600851475143), 6857, 'largestPrimeFactor(600851475143) should return 6857.');" + } + ], + "solutions": [ + "const largestPrimeFactor = (number)=>{\n let largestFactor = number;\n for(let i = 2;ilargestPalindromeProduct(2)
should return 9009.", + "testString": "assert.strictEqual(largestPalindromeProduct(2), 9009, 'largestPalindromeProduct(2) should return 9009.');" + }, + { + "text": "largestPalindromeProduct(3) should return 906609.", + "testString": "assert.strictEqual(largestPalindromeProduct(3), 906609, 'largestPalindromeProduct(3) should return 906609.');" + } + ], + "solutions": [ + "const largestPalindromeProduct = (digit)=>{\n let start = 1;\n let end = Number(`1e${digit}`) - 1;\n let palindrome = [];\n for(let i=start;i<=end;i++){\n for(let j=start;j<=end;j++){\n let product = i*j;\n let palindromeRegex = /\\b(\\d)(\\d?)(\\d?).?\\3\\2\\1\\b/gi;\n palindromeRegex.test(product) && palindrome.push(product);\n }\n }\n return Math.max(...palindrome);\n}" + ], + "translations": {}, + "description": [ + "A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.", + "Find the largest palindrome made from the product of two 3-digit numbers." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function largestPalindromeProduct(digit) {", + " // Good luck!", + " return true;", + "}", + "", + "largestPalindromeProduct(3);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3711000cf542c50fe84", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 5: Smallest multiple", + "tests": [ + { + "text": "smallestMult(5) should return 60.", + "testString": "assert.strictEqual(smallestMult(5), 60, 'smallestMult(5) should return 60.');" + }, + { + "text": "smallestMult(10) should return 2520.", + "testString": "assert.strictEqual(smallestMult(10), 2520, 'smallestMult(10) should return 2520.');" + }, + { + "text": "smallestMult(20) should return 232792560.", + "testString": "assert.strictEqual(smallestMult(20), 232792560, 'smallestMult(20) should return 232792560.');" + } + ], + "solutions": [ + "function smallestMult(n){\n function gcd(a, b) {\n return b === 0 ? a : gcd(b, a%b); // Euclidean algorithm\n }\n\n function lcm(a, b) {\n return a * b / gcd(a, b);\n }\n var result = 1;\n for(var i = 2; i <= n; i++) {\n result = lcm(result, i);\n }\n return result;\n}" + ], + "translations": {}, + "description": [ + "2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.", + "What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function smallestMult(n) {", + " // Good luck!", + " return true;", + "}", + "", + "smallestMult(20);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3721000cf542c50fe85", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 6: Sum square difference", + "tests": [ + { + "text": "sumSquareDifference(10) should return 2640.", + "testString": "assert.strictEqual(sumSquareDifference(10), 2640, 'sumSquareDifference(10) should return 2640.');" + }, + { + "text": "sumSquareDifference(20) should return 41230.", + "testString": "assert.strictEqual(sumSquareDifference(20), 41230, 'sumSquareDifference(20) should return 41230.');" + }, + { + "text": "sumSquareDifference(100) should return 25164150.", + "testString": "assert.strictEqual(sumSquareDifference(100), 25164150, 'sumSquareDifference(100) should return 25164150.');" + } + ], + "solutions": [ + "const sumSquareDifference = (number)=>{\n let squareOfSum = Math.pow(sumOfArithmeticSeries(1,1,number),2);\n let sumOfSquare = sumOfSquareOfNumbers(number);\n return squareOfSum - sumOfSquare;\n}\n\nfunction sumOfArithmeticSeries(a,d,n){\n return (n/2)*(2*a+(n-1)*d);\n}\n\nfunction sumOfSquareOfNumbers(n){\n return (n*(n+1)*(2*n+1))/6;\n}" + ], + "translations": {}, + "description": [ + "The sum of the squares of the first ten natural numbers is,", + "1² + 2² + ... + 10² = 385", + "The square of the sum of the first ten natural numbers is,", + "(1 + 2 + ... + 10)² = 55² = 3025", + "Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640.", + "Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function sumSquareDifference(number) {", + " // Good luck!", + " return true;", + "}", + "", + "sumSquareDifference(100);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3731000cf542c50fe86", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 7: 10001st prime", + "tests": [ + { + "text": "nthPrime(6) should return 13.", + "testString": "assert.strictEqual(nthPrime(6), 13, 'nthPrime(6) should return 13.');" + }, + { + "text": "nthPrime(10) should return 29.", + "testString": "assert.strictEqual(nthPrime(10), 29, 'nthPrime(10) should return 29.');" + }, + { + "text": "nthPrime(100) should return 541.", + "testString": "assert.strictEqual(nthPrime(100), 541, 'nthPrime(100) should return 541.');" + }, + { + "text": "nthPrime(1000) should return 7919.", + "testString": "assert.strictEqual(nthPrime(1000), 7919, 'nthPrime(1000) should return 7919.');" + }, + { + "text": "nthPrime(10001) should return 104743.", + "testString": "assert.strictEqual(nthPrime(10001), 104743, 'nthPrime(10001) should return 104743.');" + } + ], + "solutions": [ + "const nthPrime = (number)=>{\n let pN = 2;\n let step = 0;\n while (steplargestProductinaSeries(4)
should return 5832.", + "testString": "assert.strictEqual(largestProductinaSeries(4), 5832, 'largestProductinaSeries(4) should return 5832.');" + }, + { + "text": "largestProductinaSeries(13) should return 23514624000.", + "testString": "assert.strictEqual(largestProductinaSeries(13), 23514624000, 'largestProductinaSeries(13) should return 23514624000.');" + } + ], + "solutions": [ + "const largestProductinaSeries = (number)=>{\n let thousandDigits = [7,3,1,6,7,1,7,6,5,3,1,3,3,0,6,2,4,9,1,9,2,2,5,1,1,9,6,7,4,4,2,6,5,7,4,7,4,2,3,5,5,3,4,9,1,9,4,9,3,4,9,6,9,8,3,5,2,0,3,1,2,7,7,4,5,0,6,3,2,6,2,3,9,5,7,8,3,1,8,0,1,6,9,8,4,8,0,1,8,6,9,4,7,8,8,5,1,8,4,3,8,5,8,6,1,5,6,0,7,8,9,1,1,2,9,4,9,4,9,5,4,5,9,5,0,1,7,3,7,9,5,8,3,3,1,9,5,2,8,5,3,2,0,8,8,0,5,5,1,1,1,2,5,4,0,6,9,8,7,4,7,1,5,8,5,2,3,8,6,3,0,5,0,7,1,5,6,9,3,2,9,0,9,6,3,2,9,5,2,2,7,4,4,3,0,4,3,5,5,7,6,6,8,9,6,6,4,8,9,5,0,4,4,5,2,4,4,5,2,3,1,6,1,7,3,1,8,5,6,4,0,3,0,9,8,7,1,1,1,2,1,7,2,2,3,8,3,1,1,3,6,2,2,2,9,8,9,3,4,2,3,3,8,0,3,0,8,1,3,5,3,3,6,2,7,6,6,1,4,2,8,2,8,0,6,4,4,4,4,8,6,6,4,5,2,3,8,7,4,9,3,0,3,5,8,9,0,7,2,9,6,2,9,0,4,9,1,5,6,0,4,4,0,7,7,2,3,9,0,7,1,3,8,1,0,5,1,5,8,5,9,3,0,7,9,6,0,8,6,6,7,0,1,7,2,4,2,7,1,2,1,8,8,3,9,9,8,7,9,7,9,0,8,7,9,2,2,7,4,9,2,1,9,0,1,6,9,9,7,2,0,8,8,8,0,9,3,7,7,6,6,5,7,2,7,3,3,3,0,0,1,0,5,3,3,6,7,8,8,1,2,2,0,2,3,5,4,2,1,8,0,9,7,5,1,2,5,4,5,4,0,5,9,4,7,5,2,2,4,3,5,2,5,8,4,9,0,7,7,1,1,6,7,0,5,5,6,0,1,3,6,0,4,8,3,9,5,8,6,4,4,6,7,0,6,3,2,4,4,1,5,7,2,2,1,5,5,3,9,7,5,3,6,9,7,8,1,7,9,7,7,8,4,6,1,7,4,0,6,4,9,5,5,1,4,9,2,9,0,8,6,2,5,6,9,3,2,1,9,7,8,4,6,8,6,2,2,4,8,2,8,3,9,7,2,2,4,1,3,7,5,6,5,7,0,5,6,0,5,7,4,9,0,2,6,1,4,0,7,9,7,2,9,6,8,6,5,2,4,1,4,5,3,5,1,0,0,4,7,4,8,2,1,6,6,3,7,0,4,8,4,4,0,3,1,9,9,8,9,0,0,0,8,8,9,5,2,4,3,4,5,0,6,5,8,5,4,1,2,2,7,5,8,8,6,6,6,8,8,1,1,6,4,2,7,1,7,1,4,7,9,9,2,4,4,4,2,9,2,8,2,3,0,8,6,3,4,6,5,6,7,4,8,1,3,9,1,9,1,2,3,1,6,2,8,2,4,5,8,6,1,7,8,6,6,4,5,8,3,5,9,1,2,4,5,6,6,5,2,9,4,7,6,5,4,5,6,8,2,8,4,8,9,1,2,8,8,3,1,4,2,6,0,7,6,9,0,0,4,2,2,4,2,1,9,0,2,2,6,7,1,0,5,5,6,2,6,3,2,1,1,1,1,1,0,9,3,7,0,5,4,4,2,1,7,5,0,6,9,4,1,6,5,8,9,6,0,4,0,8,0,7,1,9,8,4,0,3,8,5,0,9,6,2,4,5,5,4,4,4,3,6,2,9,8,1,2,3,0,9,8,7,8,7,9,9,2,7,2,4,4,2,8,4,9,0,9,1,8,8,8,4,5,8,0,1,5,6,1,6,6,0,9,7,9,1,9,1,3,3,8,7,5,4,9,9,2,0,0,5,2,4,0,6,3,6,8,9,9,1,2,5,6,0,7,1,7,6,0,6,0,5,8,8,6,1,1,6,4,6,7,1,0,9,4,0,5,0,7,7,5,4,1,0,0,2,2,5,6,9,8,3,1,5,5,2,0,0,0,5,5,9,3,5,7,2,9,7,2,5,7,1,6,3,6,2,6,9,5,6,1,8,8,2,6,7,0,4,2,8,2,5,2,4,8,3,6,0,0,8,2,3,2,5,7,5,3,0,4,2,0,7,5,2,9,6,3,4,5,0];\n let numberOfDigits = thousandDigits.length;\n let currentIndex = 0;\n let productOfAdjDigits = [];\n\n while(currentIndex<=(numberOfDigits-number)){\n let currentAdj = thousandDigits.slice(currentIndex,currentIndex+number);\n let isAdjDigits = false;\n\n productOfAdjDigits.push(currentAdj.reduce((prev,cur)=>{\n return prev*cur;\n }));\n\n currentIndex++;\n }\n\n return Math.max(...productOfAdjDigits);\n}" + ], + "translations": {}, + "description": [ + "The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832.", + "", + "73167176531330624919225119674426574742355349194934", + "96983520312774506326239578318016984801869478851843", + "85861560789112949495459501737958331952853208805511", + "12540698747158523863050715693290963295227443043557", + "66896648950445244523161731856403098711121722383113", + "62229893423380308135336276614282806444486645238749", + "30358907296290491560440772390713810515859307960866", + "70172427121883998797908792274921901699720888093776", + "65727333001053367881220235421809751254540594752243", + "52584907711670556013604839586446706324415722155397", + "53697817977846174064955149290862569321978468622482", + "83972241375657056057490261407972968652414535100474", + "82166370484403199890008895243450658541227588666881", + "16427171479924442928230863465674813919123162824586", + "17866458359124566529476545682848912883142607690042", + "24219022671055626321111109370544217506941658960408", + "07198403850962455444362981230987879927244284909188", + "84580156166097919133875499200524063689912560717606", + "05886116467109405077541002256983155200055935729725", + "71636269561882670428252483600823257530420752963450", + "Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function largestProductinaSeries(number) {", + " // Good luck!", + " let thousandDigits = [7,3,1,6,7,1,7,6,5,3,1,3,3,0,6,2,4,9,1,9,2,2,5,1,1,9,6,7,4,4,2,6,5,7,4,7,4,2,3,5,5,3,4,9,1,9,4,9,3,4,9,6,9,8,3,5,2,0,3,1,2,7,7,4,5,0,6,3,2,6,2,3,9,5,7,8,3,1,8,0,1,6,9,8,4,8,0,1,8,6,9,4,7,8,8,5,1,8,4,3,8,5,8,6,1,5,6,0,7,8,9,1,1,2,9,4,9,4,9,5,4,5,9,5,0,1,7,3,7,9,5,8,3,3,1,9,5,2,8,5,3,2,0,8,8,0,5,5,1,1,1,2,5,4,0,6,9,8,7,4,7,1,5,8,5,2,3,8,6,3,0,5,0,7,1,5,6,9,3,2,9,0,9,6,3,2,9,5,2,2,7,4,4,3,0,4,3,5,5,7,6,6,8,9,6,6,4,8,9,5,0,4,4,5,2,4,4,5,2,3,1,6,1,7,3,1,8,5,6,4,0,3,0,9,8,7,1,1,1,2,1,7,2,2,3,8,3,1,1,3,6,2,2,2,9,8,9,3,4,2,3,3,8,0,3,0,8,1,3,5,3,3,6,2,7,6,6,1,4,2,8,2,8,0,6,4,4,4,4,8,6,6,4,5,2,3,8,7,4,9,3,0,3,5,8,9,0,7,2,9,6,2,9,0,4,9,1,5,6,0,4,4,0,7,7,2,3,9,0,7,1,3,8,1,0,5,1,5,8,5,9,3,0,7,9,6,0,8,6,6,7,0,1,7,2,4,2,7,1,2,1,8,8,3,9,9,8,7,9,7,9,0,8,7,9,2,2,7,4,9,2,1,9,0,1,6,9,9,7,2,0,8,8,8,0,9,3,7,7,6,6,5,7,2,7,3,3,3,0,0,1,0,5,3,3,6,7,8,8,1,2,2,0,2,3,5,4,2,1,8,0,9,7,5,1,2,5,4,5,4,0,5,9,4,7,5,2,2,4,3,5,2,5,8,4,9,0,7,7,1,1,6,7,0,5,5,6,0,1,3,6,0,4,8,3,9,5,8,6,4,4,6,7,0,6,3,2,4,4,1,5,7,2,2,1,5,5,3,9,7,5,3,6,9,7,8,1,7,9,7,7,8,4,6,1,7,4,0,6,4,9,5,5,1,4,9,2,9,0,8,6,2,5,6,9,3,2,1,9,7,8,4,6,8,6,2,2,4,8,2,8,3,9,7,2,2,4,1,3,7,5,6,5,7,0,5,6,0,5,7,4,9,0,2,6,1,4,0,7,9,7,2,9,6,8,6,5,2,4,1,4,5,3,5,1,0,0,4,7,4,8,2,1,6,6,3,7,0,4,8,4,4,0,3,1,9,9,8,9,0,0,0,8,8,9,5,2,4,3,4,5,0,6,5,8,5,4,1,2,2,7,5,8,8,6,6,6,8,8,1,1,6,4,2,7,1,7,1,4,7,9,9,2,4,4,4,2,9,2,8,2,3,0,8,6,3,4,6,5,6,7,4,8,1,3,9,1,9,1,2,3,1,6,2,8,2,4,5,8,6,1,7,8,6,6,4,5,8,3,5,9,1,2,4,5,6,6,5,2,9,4,7,6,5,4,5,6,8,2,8,4,8,9,1,2,8,8,3,1,4,2,6,0,7,6,9,0,0,4,2,2,4,2,1,9,0,2,2,6,7,1,0,5,5,6,2,6,3,2,1,1,1,1,1,0,9,3,7,0,5,4,4,2,1,7,5,0,6,9,4,1,6,5,8,9,6,0,4,0,8,0,7,1,9,8,4,0,3,8,5,0,9,6,2,4,5,5,4,4,4,3,6,2,9,8,1,2,3,0,9,8,7,8,7,9,9,2,7,2,4,4,2,8,4,9,0,9,1,8,8,8,4,5,8,0,1,5,6,1,6,6,0,9,7,9,1,9,1,3,3,8,7,5,4,9,9,2,0,0,5,2,4,0,6,3,6,8,9,9,1,2,5,6,0,7,1,7,6,0,6,0,5,8,8,6,1,1,6,4,6,7,1,0,9,4,0,5,0,7,7,5,4,1,0,0,2,2,5,6,9,8,3,1,5,5,2,0,0,0,5,5,9,3,5,7,2,9,7,2,5,7,1,6,3,6,2,6,9,5,6,1,8,8,2,6,7,0,4,2,8,2,5,2,4,8,3,6,0,0,8,2,3,2,5,7,5,3,0,4,2,0,7,5,2,9,6,3,4,5,0];", + " return true;", + "}", + "", + "largestProductinaSeries(13);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3761000cf542c50fe88", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 9: Special Pythagorean triplet", + "tests": [ + { + "text": "specialPythagoreanTriplet(1000) should return 31875000.", + "testString": "assert.strictEqual(specialPythagoreanTriplet(1000), 31875000, 'specialPythagoreanTriplet(1000) should return 31875000.');" + }, + { + "text": "specialPythagoreanTriplet(24) should return 480.", + "testString": "assert.strictEqual(specialPythagoreanTriplet(24), 480, 'specialPythagoreanTriplet(24) should return 480.');" + }, + { + "text": "specialPythagoreanTriplet(120) should return 49920.", + "testString": "assert.strictEqual(specialPythagoreanTriplet(120), 49920, 'specialPythagoreanTriplet(120) should return 49920.');" + } + ], + "solutions": [ + "const specialPythagoreanTriplet = (n)=>{\n let sumOfabc = n;\n let a,b,c;\n for(a = 1; a<=sumOfabc/3; a++){\n for(b = a+1; b<=sumOfabc/2; b++){\n c = Math.sqrt(a*a+b*b);\n if((a+b+c) == sumOfabc){\n return a*b*c;\n }\n }\n }\n}" + ], + "translations": {}, + "description": [ + "A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,", + " a² + b² = c²", + "For example, 3² + 4² = 9 + 16 = 25 = 5².", + "There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product abc." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function specialPythagoreanTriplet(n) {", + " let sumOfabc = n;", + " // Good luck!", + " return true;", + "}", + "", + "specialPythagoreanTriplet(1000);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3761000cf542c50fe89", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 10: Summation of primes", + "tests": [ + { + "text": "primeSummation(17) should return 41.", + "testString": "assert.strictEqual(primeSummation(17), 41, 'primeSummation(17) should return 41.');" + }, + { + "text": "primeSummation(2001) should return 277050.", + "testString": "assert.strictEqual(primeSummation(2001), 277050, 'primeSummation(2001) should return 277050.');" + }, + { + "text": "primeSummation(140759) should return 873608362.", + "testString": "assert.strictEqual(primeSummation(140759), 873608362, 'primeSummation(140759) should return 873608362.');" + }, + { + "text": "primeSummation(2000000) should return 142913828922.", + "testString": "assert.strictEqual(primeSummation(2000000), 142913828922, 'primeSummation(2000000) should return 142913828922.');" + } + ], + "solutions": [ + "//noprotect\nfunction primeSummation(n) {\n // Initialise an array containing only prime numbers\n let primes = [2];\n let result = 2;\n\n function isPrime(y, primes) {\n // Find sqrt(y)\n const sqrt = Math.floor(Math.sqrt(y));\n\n // Divide y by each applicable prime, return false if any of them divide y\n for (let i = 0; i < primes.length && primes[i] <= sqrt; i++) {\n if (y % primes[i] === 0) {\n return false;\n }\n }\n\n // At this point x must be prime\n return true;\n }\n\n // For every odd integer, add it to the array if it is prime\n for (let x = 3; x < n; x += 2) {\n if (isPrime(x, primes)) {\n if (x > n) {\n return result;\n } else {\n result += x;\n primes.push(x);\n }\n }\n }\n\n return result;\n}" + ], + "translations": {}, + "description": [ + "The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.", + "Find the sum of all the primes below n." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function primeSummation(n) {", + " // Good luck!", + " return true;", + "}", + "", + "primeSummation(2000000);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3781000cf542c50fe8a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 11: Largest product in a grid", + "tests": [ + { + "text": "largestGridProduct(grid) should return 70600674.", + "testString": "assert.strictEqual(largestGridProduct(grid), 70600674, 'largestGridProduct(grid) should return 70600674.');" + }, + { + "text": "largestGridProduct(testGrid) should return 14169081.", + "testString": "assert.strictEqual(largestGridProduct(testGrid), 14169081, 'largestGridProduct(testGrid) should return 14169081.');" + } + ], + "solutions": [ + "function largestGridProduct(arr) {\n let maxProduct = 0;\n let currProduct = 0;\n\n function maxProductChecker(n) {\n if (n > maxProduct) {\n return maxProduct = n;\n }\n }\n\n // loop rows\n for (let r = 0; r < arr.length; r++) {\n // loop columns\n for (let c = 0; c < arr[r].length; c++) {\n const limit = arr[r].length - 3;\n\n // check horizontal\n if (c < limit) {\n currProduct = arr[r][c] * arr[r][c + 1] * arr[r][c + 2] * arr[r][c + 3];\n maxProductChecker(currProduct);\n }\n\n // check vertical\n if (r < limit) {\n currProduct = arr[r][c] * arr[r + 1][c] * arr[r + 2][c] * arr[r + 3][c];\n maxProductChecker(currProduct);\n }\n\n // check diagonal [\\]\n if (c < limit && r < limit) {\n currProduct = arr[r][c] * arr[r + 1][c + 1] * arr[r + 2][c + 2] * arr[r + 3][c + 3];\n maxProductChecker(currProduct);\n }\n\n // check diagonal [/]\n if (c > 3 && r < limit) {\n currProduct = arr[r][c] * arr[r + 1][c - 1] * arr[r + 2][c - 2] * arr[r + 3][c - 3];\n maxProductChecker(currProduct);\n }\n }\n }\n\n return maxProduct;\n}\n\n const grid = [ [8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8],\n [49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0],\n [81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65],\n [52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 36, 91],\n [22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80],\n [24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50],\n [32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70],\n [67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21],\n [24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72],\n [21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95],\n [78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92],\n [16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57],\n [86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58],\n [19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40],\n [4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66],\n [88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69],\n [4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36],\n [20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16],\n [20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54],\n [1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48]\n];\n\nconst testGrid = [\n [40, 17, 81, 18, 57],\n [74, 4, 36, 16, 29],\n [36, 42, 69, 73, 45],\n [51, 54, 69, 16, 92],\n [7, 97, 57, 32, 16]\n];" + ], + "translations": {}, + "description": [ + "In the 20×20 grid below, four numbers along a diagonal line have been marked in red.", + "", + "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08", + "49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00", + "81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65", + "52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91", + "22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80", + "24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50", + "32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70", + "67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21", + "24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72", + "21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95", + "78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92", + "16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57", + "86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58", + "19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40", + "04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66", + "88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69", + "04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36", + "20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16", + "20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54", + "01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48", + "The product of these numbers is 26 × 63 × 78 × 14 = 1788696.", + "What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function largestGridProduct(arr) {", + " // Good luck!", + " return arr;", + "}", + "", + "// Only change code above this line", + "const grid = [", + " [8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8],", + " [49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0],", + " [81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65],", + " [52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 36, 91],", + " [22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80],", + " [24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50],", + " [32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70],", + " [67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21],", + " [24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72],", + " [21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95],", + " [78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92],", + " [16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57],", + " [86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58],", + " [19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40],", + " [4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66],", + " [88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69],", + " [4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36],", + " [20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16],", + " [20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54],", + " [1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48]", + "];", + "", + "const testGrid = [", + " [40, 17, 81, 18, 57],", + " [74, 4, 36, 16, 29],", + " [36, 42, 69, 73, 45],", + " [51, 54, 69, 16, 92],", + " [7, 97, 57, 32, 16]", + "];", + "", + "largestGridProduct(testGrid);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3781000cf542c50fe8b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 12: Highly divisible triangular number", + "tests": [ + { + "text": "divisibleTriangleNumber(5) should return 28.", + "testString": "assert.strictEqual(divisibleTriangleNumber(5), 28, 'divisibleTriangleNumber(5) should return 28.');" + }, + { + "text": "divisibleTriangleNumber(23) should return 630.", + "testString": "assert.strictEqual(divisibleTriangleNumber(23), 630, 'divisibleTriangleNumber(23) should return 630.');" + }, + { + "text": "divisibleTriangleNumber() should return 76576500.", + "testString": "assert.strictEqual(divisibleTriangleNumber(500), 76576500, 'divisibleTriangleNumber() should return 76576500.');" + } + ], + "solutions": [ + "function divisibleTriangleNumber(n) {\n let counter = 1;\n let triangleNumber = counter++;\n\n function getFactors(num) {\n let factors = [];\n\n let possibleFactor = 1;\n let sqrt = Math.sqrt(num);\n\n while (possibleFactor <= sqrt) {\n if (num % possibleFactor == 0) {\n factors.push(possibleFactor);\n var otherPossibleFactor = num / possibleFactor;\n if (otherPossibleFactor > possibleFactor) {\n factors.push(otherPossibleFactor);\n }\n }\n possibleFactor++;\n }\n\n return factors;\n }\n\n while (getFactors(triangleNumber).length < n) {\n triangleNumber += counter++;\n }\n console.log(triangleNumber)\n return triangleNumber;\n}" + ], + "translations": {}, + "description": [ + "The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:", + "1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...", + "Let us list the factors of the first seven triangle numbers:", + "1: 1", + "3: 1, 3", + "6: 1, 2, 3, 6", + "10: 1, 2, 5, 10", + "15: 1, 3, 5, 15", + "21: 1, 3, 7, 21", + "28: 1, 2, 4, 7, 14, 28", + "We can see that 28 is the first triangle number to have over five divisors.", + "What is the value of the first triangle number to have over five hundred divisors?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function divisibleTriangleNumber(n) {", + " // Good luck!", + " return true;", + "}", + "", + "divisibleTriangleNumber(500);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f37a1000cf542c50fe8c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 13: Large sum", + "tests": [ + { + "text": "largeSum(testNums) should return 8348422521.", + "testString": "assert.strictEqual(largeSum(testNums), 8348422521, 'largeSum(testNums) should return 8348422521.');" + }, + { + "text": "largeSum(fiftyDigitNums) should return 5537376230.", + "testString": "assert.strictEqual(largeSum(fiftyDigitNums), 5537376230, 'largeSum(fiftyDigitNums) should return 5537376230.');" + } + ], + "solutions": [ + "function largeSum(arr) {\n\n let sum = 0;\n\n arr.forEach(function(num) {\n sum += parseInt(num, 10);\n });\n\n sum = sum.toString(10);\n\n sum = sum.substr(0, 1) + sum.substr(2);\n\n let firstTen = sum.slice(0, 10);\n return parseInt(firstTen, 10);\n}" + ], + "translations": {}, + "description": [ + "Work out the first ten digits of the sum of the following one-hundred 50-digit numbers.", + "", + "37107287533902102798797998220837590246510135740250", + "46376937677490009712648124896970078050417018260538", + "74324986199524741059474233309513058123726617309629", + "91942213363574161572522430563301811072406154908250", + "23067588207539346171171980310421047513778063246676", + "89261670696623633820136378418383684178734361726757", + "28112879812849979408065481931592621691275889832738", + "44274228917432520321923589422876796487670272189318", + "47451445736001306439091167216856844588711603153276", + "70386486105843025439939619828917593665686757934951", + "62176457141856560629502157223196586755079324193331", + "64906352462741904929101432445813822663347944758178", + "92575867718337217661963751590579239728245598838407", + "58203565325359399008402633568948830189458628227828", + "80181199384826282014278194139940567587151170094390", + "35398664372827112653829987240784473053190104293586", + "86515506006295864861532075273371959191420517255829", + "71693888707715466499115593487603532921714970056938", + "54370070576826684624621495650076471787294438377604", + "53282654108756828443191190634694037855217779295145", + "36123272525000296071075082563815656710885258350721", + "45876576172410976447339110607218265236877223636045", + "17423706905851860660448207621209813287860733969412", + "81142660418086830619328460811191061556940512689692", + "51934325451728388641918047049293215058642563049483", + "62467221648435076201727918039944693004732956340691", + "15732444386908125794514089057706229429197107928209", + "55037687525678773091862540744969844508330393682126", + "18336384825330154686196124348767681297534375946515", + "80386287592878490201521685554828717201219257766954", + "78182833757993103614740356856449095527097864797581", + "16726320100436897842553539920931837441497806860984", + "48403098129077791799088218795327364475675590848030", + "87086987551392711854517078544161852424320693150332", + "59959406895756536782107074926966537676326235447210", + "69793950679652694742597709739166693763042633987085", + "41052684708299085211399427365734116182760315001271", + "65378607361501080857009149939512557028198746004375", + "35829035317434717326932123578154982629742552737307", + "94953759765105305946966067683156574377167401875275", + "88902802571733229619176668713819931811048770190271", + "25267680276078003013678680992525463401061632866526", + "36270218540497705585629946580636237993140746255962", + "24074486908231174977792365466257246923322810917141", + "91430288197103288597806669760892938638285025333403", + "34413065578016127815921815005561868836468420090470", + "23053081172816430487623791969842487255036638784583", + "11487696932154902810424020138335124462181441773470", + "63783299490636259666498587618221225225512486764533", + "67720186971698544312419572409913959008952310058822", + "95548255300263520781532296796249481641953868218774", + "76085327132285723110424803456124867697064507995236", + "37774242535411291684276865538926205024910326572967", + "23701913275725675285653248258265463092207058596522", + "29798860272258331913126375147341994889534765745501", + "18495701454879288984856827726077713721403798879715", + "38298203783031473527721580348144513491373226651381", + "34829543829199918180278916522431027392251122869539", + "40957953066405232632538044100059654939159879593635", + "29746152185502371307642255121183693803580388584903", + "41698116222072977186158236678424689157993532961922", + "62467957194401269043877107275048102390895523597457", + "23189706772547915061505504953922979530901129967519", + "86188088225875314529584099251203829009407770775672", + "11306739708304724483816533873502340845647058077308", + "82959174767140363198008187129011875491310547126581", + "97623331044818386269515456334926366572897563400500", + "42846280183517070527831839425882145521227251250327", + "55121603546981200581762165212827652751691296897789", + "32238195734329339946437501907836945765883352399886", + "75506164965184775180738168837861091527357929701337", + "62177842752192623401942399639168044983993173312731", + "32924185707147349566916674687634660915035914677504", + "99518671430235219628894890102423325116913619626622", + "73267460800591547471830798392868535206946944540724", + "76841822524674417161514036427982273348055556214818", + "97142617910342598647204516893989422179826088076852", + "87783646182799346313767754307809363333018982642090", + "10848802521674670883215120185883543223812876952786", + "71329612474782464538636993009049310363619763878039", + "62184073572399794223406235393808339651327408011116", + "66627891981488087797941876876144230030984490851411", + "60661826293682836764744779239180335110989069790714", + "85786944089552990653640447425576083659976645795096", + "66024396409905389607120198219976047599490197230297", + "64913982680032973156037120041377903785566085089252", + "16730939319872750275468906903707539413042652315011", + "94809377245048795150954100921645863754710598436791", + "78639167021187492431995700641917969777599028300699", + "15368713711936614952811305876380278410754449733078", + "40789923115535562561142322423255033685442488917353", + "44889911501440648020369068063960672322193204149535", + "41503128880339536053299340368006977710650566631954", + "81234880673210146739058568557934581403627822703280", + "82616570773948327592232845941706525094512325230608", + "22918802058777319719839450180888072429661980811197", + "77158542502016545090413245809786882778948721859617", + "72107838435069186155435662884062257473692284509516", + "20849603980134001723930671666823555245252804609722", + "53503534226472524250874054075591789781264330331690" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function largeSum(arr) {", + " // Good luck!", + " return true;", + "}", + "", + "// only change code above this line", + "", + "const testNums = [", + " '37107287533902102798797998220837590246510135740250',", + " '46376937677490009712648124896970078050417018260538'", + "];", + "", + "largeSum(testNums);" + ], + "head": "const fiftyDigitNums = [\n '37107287533902102798797998220837590246510135740250',\n '46376937677490009712648124896970078050417018260538',\n '74324986199524741059474233309513058123726617309629',\n '91942213363574161572522430563301811072406154908250',\n '23067588207539346171171980310421047513778063246676',\n '89261670696623633820136378418383684178734361726757',\n '28112879812849979408065481931592621691275889832738',\n '44274228917432520321923589422876796487670272189318',\n '47451445736001306439091167216856844588711603153276',\n '70386486105843025439939619828917593665686757934951',\n '62176457141856560629502157223196586755079324193331',\n '64906352462741904929101432445813822663347944758178',\n '92575867718337217661963751590579239728245598838407',\n '58203565325359399008402633568948830189458628227828',\n '80181199384826282014278194139940567587151170094390',\n '35398664372827112653829987240784473053190104293586',\n '86515506006295864861532075273371959191420517255829',\n '71693888707715466499115593487603532921714970056938',\n '54370070576826684624621495650076471787294438377604',\n '53282654108756828443191190634694037855217779295145',\n '36123272525000296071075082563815656710885258350721',\n '45876576172410976447339110607218265236877223636045',\n '17423706905851860660448207621209813287860733969412',\n '81142660418086830619328460811191061556940512689692',\n '51934325451728388641918047049293215058642563049483',\n '62467221648435076201727918039944693004732956340691',\n '15732444386908125794514089057706229429197107928209',\n '55037687525678773091862540744969844508330393682126',\n '18336384825330154686196124348767681297534375946515',\n '80386287592878490201521685554828717201219257766954',\n '78182833757993103614740356856449095527097864797581',\n '16726320100436897842553539920931837441497806860984',\n '48403098129077791799088218795327364475675590848030',\n '87086987551392711854517078544161852424320693150332',\n '59959406895756536782107074926966537676326235447210',\n '69793950679652694742597709739166693763042633987085',\n '41052684708299085211399427365734116182760315001271',\n '65378607361501080857009149939512557028198746004375',\n '35829035317434717326932123578154982629742552737307',\n '94953759765105305946966067683156574377167401875275',\n '88902802571733229619176668713819931811048770190271',\n '25267680276078003013678680992525463401061632866526',\n '36270218540497705585629946580636237993140746255962',\n '24074486908231174977792365466257246923322810917141',\n '91430288197103288597806669760892938638285025333403',\n '34413065578016127815921815005561868836468420090470',\n '23053081172816430487623791969842487255036638784583',\n '11487696932154902810424020138335124462181441773470',\n '63783299490636259666498587618221225225512486764533',\n '67720186971698544312419572409913959008952310058822',\n '95548255300263520781532296796249481641953868218774',\n '76085327132285723110424803456124867697064507995236',\n '37774242535411291684276865538926205024910326572967',\n '23701913275725675285653248258265463092207058596522',\n '29798860272258331913126375147341994889534765745501',\n '18495701454879288984856827726077713721403798879715',\n '38298203783031473527721580348144513491373226651381',\n '34829543829199918180278916522431027392251122869539',\n '40957953066405232632538044100059654939159879593635',\n '29746152185502371307642255121183693803580388584903',\n '41698116222072977186158236678424689157993532961922',\n '62467957194401269043877107275048102390895523597457',\n '23189706772547915061505504953922979530901129967519',\n '86188088225875314529584099251203829009407770775672',\n '11306739708304724483816533873502340845647058077308',\n '82959174767140363198008187129011875491310547126581',\n '97623331044818386269515456334926366572897563400500',\n '42846280183517070527831839425882145521227251250327',\n '55121603546981200581762165212827652751691296897789',\n '32238195734329339946437501907836945765883352399886',\n '75506164965184775180738168837861091527357929701337',\n '62177842752192623401942399639168044983993173312731',\n '32924185707147349566916674687634660915035914677504',\n '99518671430235219628894890102423325116913619626622',\n '73267460800591547471830798392868535206946944540724',\n '76841822524674417161514036427982273348055556214818',\n '97142617910342598647204516893989422179826088076852',\n '87783646182799346313767754307809363333018982642090',\n '10848802521674670883215120185883543223812876952786',\n '71329612474782464538636993009049310363619763878039',\n '62184073572399794223406235393808339651327408011116',\n '66627891981488087797941876876144230030984490851411',\n '60661826293682836764744779239180335110989069790714',\n '85786944089552990653640447425576083659976645795096',\n '66024396409905389607120198219976047599490197230297',\n '64913982680032973156037120041377903785566085089252',\n '16730939319872750275468906903707539413042652315011',\n '94809377245048795150954100921645863754710598436791',\n '78639167021187492431995700641917969777599028300699',\n '15368713711936614952811305876380278410754449733078',\n '40789923115535562561142322423255033685442488917353',\n '44889911501440648020369068063960672322193204149535',\n '41503128880339536053299340368006977710650566631954',\n '81234880673210146739058568557934581403627822703280',\n '82616570773948327592232845941706525094512325230608',\n '22918802058777319719839450180888072429661980811197',\n '77158542502016545090413245809786882778948721859617',\n '72107838435069186155435662884062257473692284509516',\n '20849603980134001723930671666823555245252804609722',\n '53503534226472524250874054075591789781264330331690'\n];\n\nconst testNums = [\n '37107287533902102798797998220837590246510135740250',\n '46376937677490009712648124896970078050417018260538'\n];", + "tail": "" + } + } + }, + { + "id": "5900f37a1000cf542c50fe8d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 14: Longest Collatz sequence", + "tests": [ + { + "text": "longestCollatzSequence(14) should return 9.", + "testString": "assert.strictEqual(longestCollatzSequence(14), 9, 'longestCollatzSequence(14) should return 9.');" + }, + { + "text": "longestCollatzSequence(5847) should return 3711.", + "testString": "assert.strictEqual(longestCollatzSequence(5847), 3711, 'longestCollatzSequence(5847) should return 3711.');" + }, + { + "text": "longestCollatzSequence(1000000) should return 837799.", + "testString": "assert.strictEqual(longestCollatzSequence(1000000), 837799, 'longestCollatzSequence(1000000) should return 837799.');" + } + ], + "solutions": [ + "function longestCollatzSequence(limit) {\n let longestSequenceLength = 0;\n let startingNum = 0;\n\n function sequenceLength(num) {\n let length = 1;\n\n while (num >= 1) {\n if (num === 1) { break;\n } else if (num % 2 === 0) {\n num = num / 2;\n length++;\n } else {\n num = num * 3 + 1;\n length++;\n }\n }\n return length;\n }\n\n for (let i = 2; i < limit; i++) {\n let currSequenceLength = sequenceLength(i);\n if (currSequenceLength > longestSequenceLength) {\n longestSequenceLength = currSequenceLength;\n startingNum = i;\n }\n }\n return startingNum;\n}" + ], + "translations": {}, + "description": [ + "The following iterative sequence is defined for the set of positive integers:", + "n → n/2 (n is even)n → 3n + 1 (n is odd)", + "Using the rule above and starting with 13, we generate the following sequence:", + "13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1", + "It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.", + "Which starting number, under one million, produces the longest chain?", + "NOTE: Once the chain starts the terms are allowed to go above one million." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function longestCollatzSequence(limit) {", + " // Good luck!", + " return true;", + "}", + "", + "longestCollatzSequence(14);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f37b1000cf542c50fe8e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 15: Lattice paths", + "tests": [ + { + "text": "latticePaths(4) should return 70.", + "testString": "assert.strictEqual(latticePaths(4), 70, 'latticePaths(4) should return 70.');" + }, + { + "text": "latticePaths(9) should return 48620.", + "testString": "assert.strictEqual(latticePaths(9), 48620, 'latticePaths(9) should return 48620.');" + }, + { + "text": "latticePaths(20) should return 137846528820.", + "testString": "assert.strictEqual(latticePaths(20), 137846528820, 'latticePaths(20) should return 137846528820.');" + } + ], + "solutions": [ + "function latticePaths(gridSize) {\n let paths = 1;\n\n for (let i = 0; i < gridSize; i++) {\n paths *= (2 * gridSize) - i;\n paths /= i + 1;\n }\n return paths;\n}" + ], + "translations": {}, + "description": [ + "Starting in the top left corner of a 2×2 grid, and only being able to move to the right and down, there are exactly 6 routes to the bottom right corner.", + "", + "\"a", + "", + "How many such routes are there through a 20×20 grid?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function latticePaths(gridSize) {", + " // Good luck!", + " return true;", + "}", + "", + "latticePaths(4);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f37d1000cf542c50fe8f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 16: Power digit sum", + "tests": [ + { + "text": "powerDigitSum(15) should return 26.", + "testString": "assert.strictEqual(powerDigitSum(15), 26, 'powerDigitSum(15) should return 26.');" + }, + { + "text": "powerDigitSum(128) should return 166.", + "testString": "assert.strictEqual(powerDigitSum(128), 166, 'powerDigitSum(128) should return 166.');" + }, + { + "text": "powerDigitSum(1000) should return 1366.", + "testString": "assert.strictEqual(powerDigitSum(1000), 1366, 'powerDigitSum(1000) should return 1366.');" + } + ], + "solutions": [ + "function powerDigitSum(exponent) {\n const bigNum = [1];\n let sum = 0;\n\n for (let i = 1; i <= exponent; i++) {\n let count = bigNum.length + 1;\n let overflow = 0;\n for (let j = 0; j < count; j++) {\n let digit = bigNum[j] || 0;\n digit = 2 * digit + overflow;\n\n if (digit > 9) {\n digit -= 10;\n overflow = 1;\n } else {\n overflow = 0;\n }\n\n bigNum[j] = digit;\n }\n }\n\n bigNum.forEach(function(num) {\n return sum += num;\n });\n\n return sum;\n}" + ], + "translations": {}, + "description": [ + "2¹⁵ = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.", + "What is the sum of the digits of the number 2¹⁰⁰⁰?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function powerDigitSum(exponent) {", + " // Good luck!", + " return true;", + "}", + "", + "powerDigitSum(15);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f37d1000cf542c50fe90", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 17: Number letter counts", + "tests": [ + { + "text": "numberLetterCounts(5) should return 19.", + "testString": "assert.strictEqual(numberLetterCounts(5), 19, 'numberLetterCounts(5) should return 19.');" + }, + { + "text": "numberLetterCounts(150) should return 1903.", + "testString": "assert.strictEqual(numberLetterCounts(150), 1903, 'numberLetterCounts(150) should return 1903.');" + }, + { + "text": "numberLetterCounts(1000) should return 21124.", + "testString": "assert.strictEqual(numberLetterCounts(1000), 21124, 'numberLetterCounts(1000) should return 21124.');" + } + ], + "solutions": [ + "function numberLetterCounts(limit) {\n const dictionary = {\n 0: '',\n 1: 'one',\n 2: 'two',\n 3: 'three',\n 4: 'four',\n 5: 'five',\n 6: 'six',\n 7: 'seven',\n 8: 'eight',\n 9: 'nine',\n 10: 'ten',\n 11: 'eleven',\n 12: 'twelve',\n 13: 'thirteen',\n 14: 'fourteen',\n 15: 'fifteen',\n 16: 'sixteen',\n 17: 'seventeen',\n 18: 'eighteen',\n 19: 'nineteen',\n 20: 'twenty',\n 30: 'thirty',\n 40: 'forty',\n 50: 'fifty',\n 60: 'sixty',\n 70: 'seventy',\n 80: 'eighty',\n 90: 'ninety',\n 1000: 'onethousand'\n };\n\n let numString = '';\n\n function convertToString(num) {\n // check dictionary for number\n if (dictionary[num]) {\n return dictionary[num];\n } else {\n const hundreds = Math.floor(num / 100);\n const tens = Math.floor((num / 10) % 10) * 10;\n const remainder = num % 10;\n\n let tempStr = '';\n\n if (hundreds === 0) {\n tempStr += dictionary[tens] + dictionary[remainder];\n } else {\n tempStr += dictionary[hundreds] + 'hundred';\n\n if (tens !== 0 || remainder !== 0) {\n tempStr += 'and';\n }\n\n if (tens < 20) {\n const lessThanTwenty = tens + remainder;\n tempStr += dictionary[lessThanTwenty];\n } else {\n tempStr += dictionary[tens] + dictionary[remainder];\n }\n }\n // console.log(num, hundreds, tens, remainder);\n return tempStr;\n }\n }\n\n for (let i = 1; i <= limit; i++) {\n numString += convertToString(i);\n }\n return numString.length;\n}" + ], + "translations": {}, + "description": [ + "If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.", + "If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used? ", + "NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of \"and\" when writing out numbers is in compliance with British usage." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function numberLetterCounts(limit) {", + " // Good luck!", + " return true;", + "}", + "", + "numberLetterCounts(5);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f37e1000cf542c50fe91", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 18: Maximum path sum I", + "tests": [ + { + "text": "maximumPathSumI(testTriangle) should return 23.", + "testString": "assert.strictEqual(maximumPathSumI(testTriangle), 23, 'maximumPathSumI(testTriangle) should return 23.');" + }, + { + "text": "maximumPathSumI(numTriangle) should return 1074.", + "testString": "assert.strictEqual(maximumPathSumI(numTriangle), 1074, 'maximumPathSumI(numTriangle) should return 1074.');" + } + ], + "solutions": [ + "const testTriangle = [[3, 0, 0, 0],\n [7, 4, 0, 0],\n [2, 4, 6, 0],\n [8, 5, 9, 3]];\n\nfunction maximumPathSumI(triangle) {\n let maxSum = triangle.slice();\n\n for (let i = triangle.length - 1; i > 0; i--) {\n let currentRow = maxSum[i];\n let previousRow = maxSum[i - 1];\n const temp = [];\n for (let j = 0; j < i; j++) {\n temp.push(Math.max((currentRow[j] + previousRow[j]), (currentRow[j + 1] + previousRow[j])));\n }\n maxSum[i - 1] = temp;\n maxSum.pop();\n }\n return maxSum[0][0];\n}" + ], + "translations": {}, + "description": [ + "By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.", + "3
7 4
2 4 6
8 5 9 3
", + "That is, 3 + 7 + 4 + 9 = 23.", + "Find the maximum total from top to bottom of the triangle below:", + "75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
", + "NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function maximumPathSumI(triangle) {", + " // Good luck!", + " return true;", + "}", + "", + "const testTriangle = [[3, 0, 0, 0],", + " [7, 4, 0, 0],", + " [2, 4, 6, 0],", + " [8, 5, 9, 3]];", + "", + "maximumPathSumI(testTriangle);" + ], + "head": "const numTriangle = [[75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [95, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [17, 47, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [18, 35, 87, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [20, 4, 82, 47, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [19, 1, 23, 75, 3, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0], [88, 2, 77, 73, 7, 63, 67, 0, 0, 0, 0, 0, 0, 0, 0], [99, 65, 4, 28, 6, 16, 70, 92, 0, 0, 0, 0, 0, 0, 0], [41, 41, 26, 56, 83, 40, 80, 70, 33, 0, 0, 0, 0, 0, 0], [41, 48, 72, 33, 47, 32, 37, 16, 94, 29, 0, 0, 0, 0, 0], [53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14, 0, 0, 0, 0], [70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57, 0, 0, 0], [91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48, 0, 0], [63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31, 0], [4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23]];", + "tail": "" + } + } + }, + { + "id": "5900f37f1000cf542c50fe92", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 19: Counting Sundays", + "tests": [ + { + "text": "countingSundays(1943, 1946) should return 6.", + "testString": "assert.strictEqual(countingSundays(1943, 1946), 6, 'countingSundays(1943, 1946) should return 6.');" + }, + { + "text": "countingSundays(1995, 2000) should return 9.", + "testString": "assert.strictEqual(countingSundays(1995, 2000), 9, 'countingSundays(1995, 2000) should return 9.');" + }, + { + "text": "countingSundays(1901, 2000) should return 171.", + "testString": "assert.strictEqual(countingSundays(1901, 2000), 171, 'countingSundays(1901, 2000) should return 171.');" + } + ], + "solutions": [ + "function countingSundays(firstYear, lastYear) {\n let sundays = 0;\n\n for (let year = firstYear; year <= lastYear; year++) {\n for (let month = 1; month <= 12; month++) {\n const thisDate = new Date(year, month, 1);\n if (thisDate.getDay() === 0) {\n sundays++;\n }\n }\n }\n return sundays;\n}" + ], + "translations": {}, + "description": [ + "You are given the following information, but you may prefer to do some research for yourself.", + "1 Jan 1900 was a Monday.", + "Thirty days has September,", + "April, June and November.", + "All the rest have thirty-one,", + "Saving February alone,", + "Which has twenty-eight, rain or shine.", + "And on leap years, twenty-nine.", + "A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.", + "How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function countingSundays(firstYear, lastYear) {", + " // Good luck!", + " return true;", + "}", + "", + "countingSundays(1943, 1946);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3801000cf542c50fe93", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 20: Factorial digit sum", + "tests": [ + { + "text": "sumFactorialDigits(10) should return 27.", + "testString": "assert.strictEqual(sumFactorialDigits(10), 27, 'sumFactorialDigits(10) should return 27.');" + }, + { + "text": "sumFactorialDigits(25) should return 72.", + "testString": "assert.strictEqual(sumFactorialDigits(25), 72, 'sumFactorialDigits(25) should return 72.');" + }, + { + "text": "sumFactorialDigits(50) should return 216.", + "testString": "assert.strictEqual(sumFactorialDigits(50), 216, 'sumFactorialDigits(50) should return 216.');" + }, + { + "text": "sumFactorialDigits(75) should return 432.", + "testString": "assert.strictEqual(sumFactorialDigits(75), 432, 'sumFactorialDigits(75) should return 432.');" + }, + { + "text": "sumFactorialDigits(100) should return 648.", + "testString": "assert.strictEqual(sumFactorialDigits(100), 648, 'sumFactorialDigits(100) should return 648.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "n! means n × (n − 1) × ... × 3 × 2 × 1", + "For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800,and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.", + "Find the sum of the digits n!" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function sumFactorialDigits(n) {", + " // Good luck!", + " return n;", + "}", + "", + "sumFactorialDigits(100);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3811000cf542c50fe94", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 21: Amicable numbers", + "tests": [ + { + "text": "sumAmicableNum(1000) should return 504.", + "testString": "assert.strictEqual(sumAmicableNum(1000), 504, 'sumAmicableNum(1000) should return 504.');" + }, + { + "text": "sumAmicableNum(2000) should return 2898.", + "testString": "assert.strictEqual(sumAmicableNum(2000), 2898, 'sumAmicableNum(2000) should return 2898.');" + }, + { + "text": "sumAmicableNum(5000) should return 8442.", + "testString": "assert.strictEqual(sumAmicableNum(5000), 8442, 'sumAmicableNum(5000) should return 8442.');" + }, + { + "text": "sumAmicableNum(10000) should return 31626.", + "testString": "assert.strictEqual(sumAmicableNum(10000), 31626, 'sumAmicableNum(10000) should return 31626.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).", + "If d(a) = b and d(b) = a, where a ≠ b, then a and b are an amicable pair and each of a and b are called amicable numbers.", + "For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.", + "Evaluate the sum of all the amicable numbers under n." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function sumAmicableNum(n) {", + " // Good luck!", + " return n;", + "}", + "", + "sumAmicableNum(10000);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5a51eabcad78bf416f316e2a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 22: Names scores", + "tests": [ + { + "text": "namesScores(test1) should return 791.", + "testString": "assert.strictEqual(namesScores(test1), 791, 'namesScores(test1) should return 791.');" + }, + { + "text": "namesScores(test2) should return 1468.", + "testString": "assert.strictEqual(namesScores(test2), 1468, 'namesScores(test2) should return 1468.');" + }, + { + "text": "namesScores(names) should return 871198282.", + "testString": "assert.strictEqual(namesScores(names), 871198282, 'namesScores(names) should return 871198282.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Using names, an array containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.", + "For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 × 53 = 49714.", + "What is the total of all the name scores in the file?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function namesScores(arr) {", + " // Good luck!", + " return arr;", + "}", + "", + "// Only change code above this line", + "const test1 = ['THIS', 'IS', 'ONLY', 'A', 'TEST'];", + "const test2 = ['I', 'REPEAT', 'THIS', 'IS', 'ONLY', 'A', 'TEST'];", + "", + "namesScores(test1);" + ], + "head": "const names = ['MARY','PATRICIA','LINDA','BARBARA','ELIZABETH','JENNIFER','MARIA','SUSAN','MARGARET','DOROTHY','LISA','NANCY','KAREN','BETTY','HELEN','SANDRA','DONNA','CAROL','RUTH','SHARON','MICHELLE','LAURA','SARAH','KIMBERLY','DEBORAH','JESSICA','SHIRLEY','CYNTHIA','ANGELA','MELISSA','BRENDA','AMY','ANNA','REBECCA','VIRGINIA','KATHLEEN','PAMELA','MARTHA','DEBRA','AMANDA','STEPHANIE','CAROLYN','CHRISTINE','MARIE','JANET','CATHERINE','FRANCES','ANN','JOYCE','DIANE','ALICE','JULIE','HEATHER','TERESA','DORIS','GLORIA','EVELYN','JEAN','CHERYL','MILDRED','KATHERINE','JOAN','ASHLEY','JUDITH','ROSE','JANICE','KELLY','NICOLE','JUDY','CHRISTINA','KATHY','THERESA','BEVERLY','DENISE','TAMMY','IRENE','JANE','LORI','RACHEL','MARILYN','ANDREA','KATHRYN','LOUISE','SARA','ANNE','JACQUELINE','WANDA','BONNIE','JULIA','RUBY','LOIS','TINA','PHYLLIS','NORMA','PAULA','DIANA','ANNIE','LILLIAN','EMILY','ROBIN','PEGGY','CRYSTAL','GLADYS','RITA','DAWN','CONNIE','FLORENCE','TRACY','EDNA','TIFFANY','CARMEN','ROSA','CINDY','GRACE','WENDY','VICTORIA','EDITH','KIM','SHERRY','SYLVIA','JOSEPHINE','THELMA','SHANNON','SHEILA','ETHEL','ELLEN','ELAINE','MARJORIE','CARRIE','CHARLOTTE','MONICA','ESTHER','PAULINE','EMMA','JUANITA','ANITA','RHONDA','HAZEL','AMBER','EVA','DEBBIE','APRIL','LESLIE','CLARA','LUCILLE','JAMIE','JOANNE','ELEANOR','VALERIE','DANIELLE','MEGAN','ALICIA','SUZANNE','MICHELE','GAIL','BERTHA','DARLENE','VERONICA','JILL','ERIN','GERALDINE','LAUREN','CATHY','JOANN','LORRAINE','LYNN','SALLY','REGINA','ERICA','BEATRICE','DOLORES','BERNICE','AUDREY','YVONNE','ANNETTE','JUNE','SAMANTHA','MARION','DANA','STACY','ANA','RENEE','IDA','VIVIAN','ROBERTA','HOLLY','BRITTANY','MELANIE','LORETTA','YOLANDA','JEANETTE','LAURIE','KATIE','KRISTEN','VANESSA','ALMA','SUE','ELSIE','BETH','JEANNE','VICKI','CARLA','TARA','ROSEMARY','EILEEN','TERRI','GERTRUDE','LUCY','TONYA','ELLA','STACEY','WILMA','GINA','KRISTIN','JESSIE','NATALIE','AGNES','VERA','WILLIE','CHARLENE','BESSIE','DELORES','MELINDA','PEARL','ARLENE','MAUREEN','COLLEEN','ALLISON','TAMARA','JOY','GEORGIA','CONSTANCE','LILLIE','CLAUDIA','JACKIE','MARCIA','TANYA','NELLIE','MINNIE','MARLENE','HEIDI','GLENDA','LYDIA','VIOLA','COURTNEY','MARIAN','STELLA','CAROLINE','DORA','JO','VICKIE','MATTIE','TERRY','MAXINE','IRMA','MABEL','MARSHA','MYRTLE','LENA','CHRISTY','DEANNA','PATSY','HILDA','GWENDOLYN','JENNIE','NORA','MARGIE','NINA','CASSANDRA','LEAH','PENNY','KAY','PRISCILLA','NAOMI','CAROLE','BRANDY','OLGA','BILLIE','DIANNE','TRACEY','LEONA','JENNY','FELICIA','SONIA','MIRIAM','VELMA','BECKY','BOBBIE','VIOLET','KRISTINA','TONI','MISTY','MAE','SHELLY','DAISY','RAMONA','SHERRI','ERIKA','KATRINA','CLAIRE','LINDSEY','LINDSAY','GENEVA','GUADALUPE','BELINDA','MARGARITA','SHERYL','CORA','FAYE','ADA','NATASHA','SABRINA','ISABEL','MARGUERITE','HATTIE','HARRIET','MOLLY','CECILIA','KRISTI','BRANDI','BLANCHE','SANDY','ROSIE','JOANNA','IRIS','EUNICE','ANGIE','INEZ','LYNDA','MADELINE','AMELIA','ALBERTA','GENEVIEVE','MONIQUE','JODI','JANIE','MAGGIE','KAYLA','SONYA','JAN','LEE','KRISTINE','CANDACE','FANNIE','MARYANN','OPAL','ALISON','YVETTE','MELODY','LUZ','SUSIE','OLIVIA','FLORA','SHELLEY','KRISTY','MAMIE','LULA','LOLA','VERNA','BEULAH','ANTOINETTE','CANDICE','JUANA','JEANNETTE','PAM','KELLI','HANNAH','WHITNEY','BRIDGET','KARLA','CELIA','LATOYA','PATTY','SHELIA','GAYLE','DELLA','VICKY','LYNNE','SHERI','MARIANNE','KARA','JACQUELYN','ERMA','BLANCA','MYRA','LETICIA','PAT','KRISTA','ROXANNE','ANGELICA','JOHNNIE','ROBYN','FRANCIS','ADRIENNE','ROSALIE','ALEXANDRA','BROOKE','BETHANY','SADIE','BERNADETTE','TRACI','JODY','KENDRA','JASMINE','NICHOLE','RACHAEL','CHELSEA','MABLE','ERNESTINE','MURIEL','MARCELLA','ELENA','KRYSTAL','ANGELINA','NADINE','KARI','ESTELLE','DIANNA','PAULETTE','LORA','MONA','DOREEN','ROSEMARIE','ANGEL','DESIREE','ANTONIA','HOPE','GINGER','JANIS','BETSY','CHRISTIE','FREDA','MERCEDES','MEREDITH','LYNETTE','TERI','CRISTINA','EULA','LEIGH','MEGHAN','SOPHIA','ELOISE','ROCHELLE','GRETCHEN','CECELIA','RAQUEL','HENRIETTA','ALYSSA','JANA','KELLEY','GWEN','KERRY','JENNA','TRICIA','LAVERNE','OLIVE','ALEXIS','TASHA','SILVIA','ELVIRA','CASEY','DELIA','SOPHIE','KATE','PATTI','LORENA','KELLIE','SONJA','LILA','LANA','DARLA','MAY','MINDY','ESSIE','MANDY','LORENE','ELSA','JOSEFINA','JEANNIE','MIRANDA','DIXIE','LUCIA','MARTA','FAITH','LELA','JOHANNA','SHARI','CAMILLE','TAMI','SHAWNA','ELISA','EBONY','MELBA','ORA','NETTIE','TABITHA','OLLIE','JAIME','WINIFRED','KRISTIE','MARINA','ALISHA','AIMEE','RENA','MYRNA','MARLA','TAMMIE','LATASHA','BONITA','PATRICE','RONDA','SHERRIE','ADDIE','FRANCINE','DELORIS','STACIE','ADRIANA','CHERI','SHELBY','ABIGAIL','CELESTE','JEWEL','CARA','ADELE','REBEKAH','LUCINDA','DORTHY','CHRIS','EFFIE','TRINA','REBA','SHAWN','SALLIE','AURORA','LENORA','ETTA','LOTTIE','KERRI','TRISHA','NIKKI','ESTELLA','FRANCISCA','JOSIE','TRACIE','MARISSA','KARIN','BRITTNEY','JANELLE','LOURDES','LAUREL','HELENE','FERN','ELVA','CORINNE','KELSEY','INA','BETTIE','ELISABETH','AIDA','CAITLIN','INGRID','IVA','EUGENIA','CHRISTA','GOLDIE','CASSIE','MAUDE','JENIFER','THERESE','FRANKIE','DENA','LORNA','JANETTE','LATONYA','CANDY','MORGAN','CONSUELO','TAMIKA','ROSETTA','DEBORA','CHERIE','POLLY','DINA','JEWELL','FAY','JILLIAN','DOROTHEA','NELL','TRUDY','ESPERANZA','PATRICA','KIMBERLEY','SHANNA','HELENA','CAROLINA','CLEO','STEFANIE','ROSARIO','OLA','JANINE','MOLLIE','LUPE','ALISA','LOU','MARIBEL','SUSANNE','BETTE','SUSANA','ELISE','CECILE','ISABELLE','LESLEY','JOCELYN','PAIGE','JONI','RACHELLE','LEOLA','DAPHNE','ALTA','ESTER','PETRA','GRACIELA','IMOGENE','JOLENE','KEISHA','LACEY','GLENNA','GABRIELA','KERI','URSULA','LIZZIE','KIRSTEN','SHANA','ADELINE','MAYRA','JAYNE','JACLYN','GRACIE','SONDRA','CARMELA','MARISA','ROSALIND','CHARITY','TONIA','BEATRIZ','MARISOL','CLARICE','JEANINE','SHEENA','ANGELINE','FRIEDA','LILY','ROBBIE','SHAUNA','MILLIE','CLAUDETTE','CATHLEEN','ANGELIA','GABRIELLE','AUTUMN','KATHARINE','SUMMER','JODIE','STACI','LEA','CHRISTI','JIMMIE','JUSTINE','ELMA','LUELLA','MARGRET','DOMINIQUE','SOCORRO','RENE','MARTINA','MARGO','MAVIS','CALLIE','BOBBI','MARITZA','LUCILE','LEANNE','JEANNINE','DEANA','AILEEN','LORIE','LADONNA','WILLA','MANUELA','GALE','SELMA','DOLLY','SYBIL','ABBY','LARA','DALE','IVY','DEE','WINNIE','MARCY','LUISA','JERI','MAGDALENA','OFELIA','MEAGAN','AUDRA','MATILDA','LEILA','CORNELIA','BIANCA','SIMONE','BETTYE','RANDI','VIRGIE','LATISHA','BARBRA','GEORGINA','ELIZA','LEANN','BRIDGETTE','RHODA','HALEY','ADELA','NOLA','BERNADINE','FLOSSIE','ILA','GRETA','RUTHIE','NELDA','MINERVA','LILLY','TERRIE','LETHA','HILARY','ESTELA','VALARIE','BRIANNA','ROSALYN','EARLINE','CATALINA','AVA','MIA','CLARISSA','LIDIA','CORRINE','ALEXANDRIA','CONCEPCION','TIA','SHARRON','RAE','DONA','ERICKA','JAMI','ELNORA','CHANDRA','LENORE','NEVA','MARYLOU','MELISA','TABATHA','SERENA','AVIS','ALLIE','SOFIA','JEANIE','ODESSA','NANNIE','HARRIETT','LORAINE','PENELOPE','MILAGROS','EMILIA','BENITA','ALLYSON','ASHLEE','TANIA','TOMMIE','ESMERALDA','KARINA','EVE','PEARLIE','ZELMA','MALINDA','NOREEN','TAMEKA','SAUNDRA','HILLARY','AMIE','ALTHEA','ROSALINDA','JORDAN','LILIA','ALANA','GAY','CLARE','ALEJANDRA','ELINOR','MICHAEL','LORRIE','JERRI','DARCY','EARNESTINE','CARMELLA','TAYLOR','NOEMI','MARCIE','LIZA','ANNABELLE','LOUISA','EARLENE','MALLORY','CARLENE','NITA','SELENA','TANISHA','KATY','JULIANNE','JOHN','LAKISHA','EDWINA','MARICELA','MARGERY','KENYA','DOLLIE','ROXIE','ROSLYN','KATHRINE','NANETTE','CHARMAINE','LAVONNE','ILENE','KRIS','TAMMI','SUZETTE','CORINE','KAYE','JERRY','MERLE','CHRYSTAL','LINA','DEANNE','LILIAN','JULIANA','ALINE','LUANN','KASEY','MARYANNE','EVANGELINE','COLETTE','MELVA','LAWANDA','YESENIA','NADIA','MADGE','KATHIE','EDDIE','OPHELIA','VALERIA','NONA','MITZI','MARI','GEORGETTE','CLAUDINE','FRAN','ALISSA','ROSEANN','LAKEISHA','SUSANNA','REVA','DEIDRE','CHASITY','SHEREE','CARLY','JAMES','ELVIA','ALYCE','DEIRDRE','GENA','BRIANA','ARACELI','KATELYN','ROSANNE','WENDI','TESSA','BERTA','MARVA','IMELDA','MARIETTA','MARCI','LEONOR','ARLINE','SASHA','MADELYN','JANNA','JULIETTE','DEENA','AURELIA','JOSEFA','AUGUSTA','LILIANA','YOUNG','CHRISTIAN','LESSIE','AMALIA','SAVANNAH','ANASTASIA','VILMA','NATALIA','ROSELLA','LYNNETTE','CORINA','ALFREDA','LEANNA','CAREY','AMPARO','COLEEN','TAMRA','AISHA','WILDA','KARYN','CHERRY','QUEEN','MAURA','MAI','EVANGELINA','ROSANNA','HALLIE','ERNA','ENID','MARIANA','LACY','JULIET','JACKLYN','FREIDA','MADELEINE','MARA','HESTER','CATHRYN','LELIA','CASANDRA','BRIDGETT','ANGELITA','JANNIE','DIONNE','ANNMARIE','KATINA','BERYL','PHOEBE','MILLICENT','KATHERYN','DIANN','CARISSA','MARYELLEN','LIZ','LAURI','HELGA','GILDA','ADRIAN','RHEA','MARQUITA','HOLLIE','TISHA','TAMERA','ANGELIQUE','FRANCESCA','BRITNEY','KAITLIN','LOLITA','FLORINE','ROWENA','REYNA','TWILA','FANNY','JANELL','INES','CONCETTA','BERTIE','ALBA','BRIGITTE','ALYSON','VONDA','PANSY','ELBA','NOELLE','LETITIA','KITTY','DEANN','BRANDIE','LOUELLA','LETA','FELECIA','SHARLENE','LESA','BEVERLEY','ROBERT','ISABELLA','HERMINIA','TERRA','CELINA','TORI','OCTAVIA','JADE','DENICE','GERMAINE','SIERRA','MICHELL','CORTNEY','NELLY','DORETHA','SYDNEY','DEIDRA','MONIKA','LASHONDA','JUDI','CHELSEY','ANTIONETTE','MARGOT','BOBBY','ADELAIDE','NAN','LEEANN','ELISHA','DESSIE','LIBBY','KATHI','GAYLA','LATANYA','MINA','MELLISA','KIMBERLEE','JASMIN','RENAE','ZELDA','ELDA','MA','JUSTINA','GUSSIE','EMILIE','CAMILLA','ABBIE','ROCIO','KAITLYN','JESSE','EDYTHE','ASHLEIGH','SELINA','LAKESHA','GERI','ALLENE','PAMALA','MICHAELA','DAYNA','CARYN','ROSALIA','SUN','JACQULINE','REBECA','MARYBETH','KRYSTLE','IOLA','DOTTIE','BENNIE','BELLE','AUBREY','GRISELDA','ERNESTINA','ELIDA','ADRIANNE','DEMETRIA','DELMA','CHONG','JAQUELINE','DESTINY','ARLEEN','VIRGINA','RETHA','FATIMA','TILLIE','ELEANORE','CARI','TREVA','BIRDIE','WILHELMINA','ROSALEE','MAURINE','LATRICE','YONG','JENA','TARYN','ELIA','DEBBY','MAUDIE','JEANNA','DELILAH','CATRINA','SHONDA','HORTENCIA','THEODORA','TERESITA','ROBBIN','DANETTE','MARYJANE','FREDDIE','DELPHINE','BRIANNE','NILDA','DANNA','CINDI','BESS','IONA','HANNA','ARIEL','WINONA','VIDA','ROSITA','MARIANNA','WILLIAM','RACHEAL','GUILLERMINA','ELOISA','CELESTINE','CAREN','MALISSA','LONA','CHANTEL','SHELLIE','MARISELA','LEORA','AGATHA','SOLEDAD','MIGDALIA','IVETTE','CHRISTEN','ATHENA','JANEL','CHLOE','VEDA','PATTIE','TESSIE','TERA','MARILYNN','LUCRETIA','KARRIE','DINAH','DANIELA','ALECIA','ADELINA','VERNICE','SHIELA','PORTIA','MERRY','LASHAWN','DEVON','DARA','TAWANA','OMA','VERDA','CHRISTIN','ALENE','ZELLA','SANDI','RAFAELA','MAYA','KIRA','CANDIDA','ALVINA','SUZAN','SHAYLA','LYN','LETTIE','ALVA','SAMATHA','ORALIA','MATILDE','MADONNA','LARISSA','VESTA','RENITA','INDIA','DELOIS','SHANDA','PHILLIS','LORRI','ERLINDA','CRUZ','CATHRINE','BARB','ZOE','ISABELL','IONE','GISELA','CHARLIE','VALENCIA','ROXANNA','MAYME','KISHA','ELLIE','MELLISSA','DORRIS','DALIA','BELLA','ANNETTA','ZOILA','RETA','REINA','LAURETTA','KYLIE','CHRISTAL','PILAR','CHARLA','ELISSA','TIFFANI','TANA','PAULINA','LEOTA','BREANNA','JAYME','CARMEL','VERNELL','TOMASA','MANDI','DOMINGA','SANTA','MELODIE','LURA','ALEXA','TAMELA','RYAN','MIRNA','KERRIE','VENUS','NOEL','FELICITA','CRISTY','CARMELITA','BERNIECE','ANNEMARIE','TIARA','ROSEANNE','MISSY','CORI','ROXANA','PRICILLA','KRISTAL','JUNG','ELYSE','HAYDEE','ALETHA','BETTINA','MARGE','GILLIAN','FILOMENA','CHARLES','ZENAIDA','HARRIETTE','CARIDAD','VADA','UNA','ARETHA','PEARLINE','MARJORY','MARCELA','FLOR','EVETTE','ELOUISE','ALINA','TRINIDAD','DAVID','DAMARIS','CATHARINE','CARROLL','BELVA','NAKIA','MARLENA','LUANNE','LORINE','KARON','DORENE','DANITA','BRENNA','TATIANA','SAMMIE','LOUANN','LOREN','JULIANNA','ANDRIA','PHILOMENA','LUCILA','LEONORA','DOVIE','ROMONA','MIMI','JACQUELIN','GAYE','TONJA','MISTI','JOE','GENE','CHASTITY','STACIA','ROXANN','MICAELA','NIKITA','MEI','VELDA','MARLYS','JOHNNA','AURA','LAVERN','IVONNE','HAYLEY','NICKI','MAJORIE','HERLINDA','GEORGE','ALPHA','YADIRA','PERLA','GREGORIA','DANIEL','ANTONETTE','SHELLI','MOZELLE','MARIAH','JOELLE','CORDELIA','JOSETTE','CHIQUITA','TRISTA','LOUIS','LAQUITA','GEORGIANA','CANDI','SHANON','LONNIE','HILDEGARD','CECIL','VALENTINA','STEPHANY','MAGDA','KAROL','GERRY','GABRIELLA','TIANA','ROMA','RICHELLE','RAY','PRINCESS','OLETA','JACQUE','IDELLA','ALAINA','SUZANNA','JOVITA','BLAIR','TOSHA','RAVEN','NEREIDA','MARLYN','KYLA','JOSEPH','DELFINA','TENA','STEPHENIE','SABINA','NATHALIE','MARCELLE','GERTIE','DARLEEN','THEA','SHARONDA','SHANTEL','BELEN','VENESSA','ROSALINA','ONA','GENOVEVA','COREY','CLEMENTINE','ROSALBA','RENATE','RENATA','MI','IVORY','GEORGIANNA','FLOY','DORCAS','ARIANA','TYRA','THEDA','MARIAM','JULI','JESICA','DONNIE','VIKKI','VERLA','ROSELYN','MELVINA','JANNETTE','GINNY','DEBRAH','CORRIE','ASIA','VIOLETA','MYRTIS','LATRICIA','COLLETTE','CHARLEEN','ANISSA','VIVIANA','TWYLA','PRECIOUS','NEDRA','LATONIA','LAN','HELLEN','FABIOLA','ANNAMARIE','ADELL','SHARYN','CHANTAL','NIKI','MAUD','LIZETTE','LINDY','KIA','KESHA','JEANA','DANELLE','CHARLINE','CHANEL','CARROL','VALORIE','LIA','DORTHA','CRISTAL','SUNNY','LEONE','LEILANI','GERRI','DEBI','ANDRA','KESHIA','IMA','EULALIA','EASTER','DULCE','NATIVIDAD','LINNIE','KAMI','GEORGIE','CATINA','BROOK','ALDA','WINNIFRED','SHARLA','RUTHANN','MEAGHAN','MAGDALENE','LISSETTE','ADELAIDA','VENITA','TRENA','SHIRLENE','SHAMEKA','ELIZEBETH','DIAN','SHANTA','MICKEY','LATOSHA','CARLOTTA','WINDY','SOON','ROSINA','MARIANN','LEISA','JONNIE','DAWNA','CATHIE','BILLY','ASTRID','SIDNEY','LAUREEN','JANEEN','HOLLI','FAWN','VICKEY','TERESSA','SHANTE','RUBYE','MARCELINA','CHANDA','CARY','TERESE','SCARLETT','MARTY','MARNIE','LULU','LISETTE','JENIFFER','ELENOR','DORINDA','DONITA','CARMAN','BERNITA','ALTAGRACIA','ALETA','ADRIANNA','ZORAIDA','RONNIE','NICOLA','LYNDSEY','KENDALL','JANINA','CHRISSY','AMI','STARLA','PHYLIS','PHUONG','KYRA','CHARISSE','BLANCH','SANJUANITA','RONA','NANCI','MARILEE','MARANDA','CORY','BRIGETTE','SANJUANA','MARITA','KASSANDRA','JOYCELYN','IRA','FELIPA','CHELSIE','BONNY','MIREYA','LORENZA','KYONG','ILEANA','CANDELARIA','TONY','TOBY','SHERIE','OK','MARK','LUCIE','LEATRICE','LAKESHIA','GERDA','EDIE','BAMBI','MARYLIN','LAVON','HORTENSE','GARNET','EVIE','TRESSA','SHAYNA','LAVINA','KYUNG','JEANETTA','SHERRILL','SHARA','PHYLISS','MITTIE','ANABEL','ALESIA','THUY','TAWANDA','RICHARD','JOANIE','TIFFANIE','LASHANDA','KARISSA','ENRIQUETA','DARIA','DANIELLA','CORINNA','ALANNA','ABBEY','ROXANE','ROSEANNA','MAGNOLIA','LIDA','KYLE','JOELLEN','ERA','CORAL','CARLEEN','TRESA','PEGGIE','NOVELLA','NILA','MAYBELLE','JENELLE','CARINA','NOVA','MELINA','MARQUERITE','MARGARETTE','JOSEPHINA','EVONNE','DEVIN','CINTHIA','ALBINA','TOYA','TAWNYA','SHERITA','SANTOS','MYRIAM','LIZABETH','LISE','KEELY','JENNI','GISELLE','CHERYLE','ARDITH','ARDIS','ALESHA','ADRIANE','SHAINA','LINNEA','KAROLYN','HONG','FLORIDA','FELISHA','DORI','DARCI','ARTIE','ARMIDA','ZOLA','XIOMARA','VERGIE','SHAMIKA','NENA','NANNETTE','MAXIE','LOVIE','JEANE','JAIMIE','INGE','FARRAH','ELAINA','CAITLYN','STARR','FELICITAS','CHERLY','CARYL','YOLONDA','YASMIN','TEENA','PRUDENCE','PENNIE','NYDIA','MACKENZIE','ORPHA','MARVEL','LIZBETH','LAURETTE','JERRIE','HERMELINDA','CAROLEE','TIERRA','MIRIAN','META','MELONY','KORI','JENNETTE','JAMILA','ENA','ANH','YOSHIKO','SUSANNAH','SALINA','RHIANNON','JOLEEN','CRISTINE','ASHTON','ARACELY','TOMEKA','SHALONDA','MARTI','LACIE','KALA','JADA','ILSE','HAILEY','BRITTANI','ZONA','SYBLE','SHERRYL','RANDY','NIDIA','MARLO','KANDICE','KANDI','DEB','DEAN','AMERICA','ALYCIA','TOMMY','RONNA','NORENE','MERCY','JOSE','INGEBORG','GIOVANNA','GEMMA','CHRISTEL','AUDRY','ZORA','VITA','VAN','TRISH','STEPHAINE','SHIRLEE','SHANIKA','MELONIE','MAZIE','JAZMIN','INGA','HOA','HETTIE','GERALYN','FONDA','ESTRELLA','ADELLA','SU','SARITA','RINA','MILISSA','MARIBETH','GOLDA','EVON','ETHELYN','ENEDINA','CHERISE','CHANA','VELVA','TAWANNA','SADE','MIRTA','LI','KARIE','JACINTA','ELNA','DAVINA','CIERRA','ASHLIE','ALBERTHA','TANESHA','STEPHANI','NELLE','MINDI','LU','LORINDA','LARUE','FLORENE','DEMETRA','DEDRA','CIARA','CHANTELLE','ASHLY','SUZY','ROSALVA','NOELIA','LYDA','LEATHA','KRYSTYNA','KRISTAN','KARRI','DARLINE','DARCIE','CINDA','CHEYENNE','CHERRIE','AWILDA','ALMEDA','ROLANDA','LANETTE','JERILYN','GISELE','EVALYN','CYNDI','CLETA','CARIN','ZINA','ZENA','VELIA','TANIKA','PAUL','CHARISSA','THOMAS','TALIA','MARGARETE','LAVONDA','KAYLEE','KATHLENE','JONNA','IRENA','ILONA','IDALIA','CANDIS','CANDANCE','BRANDEE','ANITRA','ALIDA','SIGRID','NICOLETTE','MARYJO','LINETTE','HEDWIG','CHRISTIANA','CASSIDY','ALEXIA','TRESSIE','MODESTA','LUPITA','LITA','GLADIS','EVELIA','DAVIDA','CHERRI','CECILY','ASHELY','ANNABEL','AGUSTINA','WANITA','SHIRLY','ROSAURA','HULDA','EUN','BAILEY','YETTA','VERONA','THOMASINA','SIBYL','SHANNAN','MECHELLE','LUE','LEANDRA','LANI','KYLEE','KANDY','JOLYNN','FERNE','EBONI','CORENE','ALYSIA','ZULA','NADA','MOIRA','LYNDSAY','LORRETTA','JUAN','JAMMIE','HORTENSIA','GAYNELL','CAMERON','ADRIA','VINA','VICENTA','TANGELA','STEPHINE','NORINE','NELLA','LIANA','LESLEE','KIMBERELY','ILIANA','GLORY','FELICA','EMOGENE','ELFRIEDE','EDEN','EARTHA','CARMA','BEA','OCIE','MARRY','LENNIE','KIARA','JACALYN','CARLOTA','ARIELLE','YU','STAR','OTILIA','KIRSTIN','KACEY','JOHNETTA','JOEY','JOETTA','JERALDINE','JAUNITA','ELANA','DORTHEA','CAMI','AMADA','ADELIA','VERNITA','TAMAR','SIOBHAN','RENEA','RASHIDA','OUIDA','ODELL','NILSA','MERYL','KRISTYN','JULIETA','DANICA','BREANNE','AUREA','ANGLEA','SHERRON','ODETTE','MALIA','LORELEI','LIN','LEESA','KENNA','KATHLYN','FIONA','CHARLETTE','SUZIE','SHANTELL','SABRA','RACQUEL','MYONG','MIRA','MARTINE','LUCIENNE','LAVADA','JULIANN','JOHNIE','ELVERA','DELPHIA','CLAIR','CHRISTIANE','CHAROLETTE','CARRI','AUGUSTINE','ASHA','ANGELLA','PAOLA','NINFA','LEDA','LAI','EDA','SUNSHINE','STEFANI','SHANELL','PALMA','MACHELLE','LISSA','KECIA','KATHRYNE','KARLENE','JULISSA','JETTIE','JENNIFFER','HUI','CORRINA','CHRISTOPHER','CAROLANN','ALENA','TESS','ROSARIA','MYRTICE','MARYLEE','LIANE','KENYATTA','JUDIE','JANEY','IN','ELMIRA','ELDORA','DENNA','CRISTI','CATHI','ZAIDA','VONNIE','VIVA','VERNIE','ROSALINE','MARIELA','LUCIANA','LESLI','KARAN','FELICE','DENEEN','ADINA','WYNONA','TARSHA','SHERON','SHASTA','SHANITA','SHANI','SHANDRA','RANDA','PINKIE','PARIS','NELIDA','MARILOU','LYLA','LAURENE','LACI','JOI','JANENE','DOROTHA','DANIELE','DANI','CAROLYNN','CARLYN','BERENICE','AYESHA','ANNELIESE','ALETHEA','THERSA','TAMIKO','RUFINA','OLIVA','MOZELL','MARYLYN','MADISON','KRISTIAN','KATHYRN','KASANDRA','KANDACE','JANAE','GABRIEL','DOMENICA','DEBBRA','DANNIELLE','CHUN','BUFFY','BARBIE','ARCELIA','AJA','ZENOBIA','SHAREN','SHAREE','PATRICK','PAGE','MY','LAVINIA','KUM','KACIE','JACKELINE','HUONG','FELISA','EMELIA','ELEANORA','CYTHIA','CRISTIN','CLYDE','CLARIBEL','CARON','ANASTACIA','ZULMA','ZANDRA','YOKO','TENISHA','SUSANN','SHERILYN','SHAY','SHAWANDA','SABINE','ROMANA','MATHILDA','LINSEY','KEIKO','JOANA','ISELA','GRETTA','GEORGETTA','EUGENIE','DUSTY','DESIRAE','DELORA','CORAZON','ANTONINA','ANIKA','WILLENE','TRACEE','TAMATHA','REGAN','NICHELLE','MICKIE','MAEGAN','LUANA','LANITA','KELSIE','EDELMIRA','BREE','AFTON','TEODORA','TAMIE','SHENA','MEG','LINH','KELI','KACI','DANYELLE','BRITT','ARLETTE','ALBERTINE','ADELLE','TIFFINY','STORMY','SIMONA','NUMBERS','NICOLASA','NICHOL','NIA','NAKISHA','MEE','MAIRA','LOREEN','KIZZY','JOHNNY','JAY','FALLON','CHRISTENE','BOBBYE','ANTHONY','YING','VINCENZA','TANJA','RUBIE','RONI','QUEENIE','MARGARETT','KIMBERLI','IRMGARD','IDELL','HILMA','EVELINA','ESTA','EMILEE','DENNISE','DANIA','CARL','CARIE','ANTONIO','WAI','SANG','RISA','RIKKI','PARTICIA','MUI','MASAKO','MARIO','LUVENIA','LOREE','LONI','LIEN','KEVIN','GIGI','FLORENCIA','DORIAN','DENITA','DALLAS','CHI','BILLYE','ALEXANDER','TOMIKA','SHARITA','RANA','NIKOLE','NEOMA','MARGARITE','MADALYN','LUCINA','LAILA','KALI','JENETTE','GABRIELE','EVELYNE','ELENORA','CLEMENTINA','ALEJANDRINA','ZULEMA','VIOLETTE','VANNESSA','THRESA','RETTA','PIA','PATIENCE','NOELLA','NICKIE','JONELL','DELTA','CHUNG','CHAYA','CAMELIA','BETHEL','ANYA','ANDREW','THANH','SUZANN','SPRING','SHU','MILA','LILLA','LAVERNA','KEESHA','KATTIE','GIA','GEORGENE','EVELINE','ESTELL','ELIZBETH','VIVIENNE','VALLIE','TRUDIE','STEPHANE','MICHEL','MAGALY','MADIE','KENYETTA','KARREN','JANETTA','HERMINE','HARMONY','DRUCILLA','DEBBI','CELESTINA','CANDIE','BRITNI','BECKIE','AMINA','ZITA','YUN','YOLANDE','VIVIEN','VERNETTA','TRUDI','SOMMER','PEARLE','PATRINA','OSSIE','NICOLLE','LOYCE','LETTY','LARISA','KATHARINA','JOSELYN','JONELLE','JENELL','IESHA','HEIDE','FLORINDA','FLORENTINA','FLO','ELODIA','DORINE','BRUNILDA','BRIGID','ASHLI','ARDELLA','TWANA','THU','TARAH','SUNG','SHEA','SHAVON','SHANE','SERINA','RAYNA','RAMONITA','NGA','MARGURITE','LUCRECIA','KOURTNEY','KATI','JESUS','JESENIA','DIAMOND','CRISTA','AYANA','ALICA','ALIA','VINNIE','SUELLEN','ROMELIA','RACHELL','PIPER','OLYMPIA','MICHIKO','KATHALEEN','JOLIE','JESSI','JANESSA','HANA','HA','ELEASE','CARLETTA','BRITANY','SHONA','SALOME','ROSAMOND','REGENA','RAINA','NGOC','NELIA','LOUVENIA','LESIA','LATRINA','LATICIA','LARHONDA','JINA','JACKI','HOLLIS','HOLLEY','EMMY','DEEANN','CORETTA','ARNETTA','VELVET','THALIA','SHANICE','NETA','MIKKI','MICKI','LONNA','LEANA','LASHUNDA','KILEY','JOYE','JACQULYN','IGNACIA','HYUN','HIROKO','HENRY','HENRIETTE','ELAYNE','DELINDA','DARNELL','DAHLIA','COREEN','CONSUELA','CONCHITA','CELINE','BABETTE','AYANNA','ANETTE','ALBERTINA','SKYE','SHAWNEE','SHANEKA','QUIANA','PAMELIA','MIN','MERRI','MERLENE','MARGIT','KIESHA','KIERA','KAYLENE','JODEE','JENISE','ERLENE','EMMIE','ELSE','DARYL','DALILA','DAISEY','CODY','CASIE','BELIA','BABARA','VERSIE','VANESA','SHELBA','SHAWNDA','SAM','NORMAN','NIKIA','NAOMA','MARNA','MARGERET','MADALINE','LAWANA','KINDRA','JUTTA','JAZMINE','JANETT','HANNELORE','GLENDORA','GERTRUD','GARNETT','FREEDA','FREDERICA','FLORANCE','FLAVIA','DENNIS','CARLINE','BEVERLEE','ANJANETTE','VALDA','TRINITY','TAMALA','STEVIE','SHONNA','SHA','SARINA','ONEIDA','MICAH','MERILYN','MARLEEN','LURLINE','LENNA','KATHERIN','JIN','JENI','HAE','GRACIA','GLADY','FARAH','ERIC','ENOLA','EMA','DOMINQUE','DEVONA','DELANA','CECILA','CAPRICE','ALYSHA','ALI','ALETHIA','VENA','THERESIA','TAWNY','SONG','SHAKIRA','SAMARA','SACHIKO','RACHELE','PAMELLA','NICKY','MARNI','MARIEL','MAREN','MALISA','LIGIA','LERA','LATORIA','LARAE','KIMBER','KATHERN','KAREY','JENNEFER','JANETH','HALINA','FREDIA','DELISA','DEBROAH','CIERA','CHIN','ANGELIKA','ANDREE','ALTHA','YEN','VIVAN','TERRESA','TANNA','SUK','SUDIE','SOO','SIGNE','SALENA','RONNI','REBBECCA','MYRTIE','MCKENZIE','MALIKA','MAIDA','LOAN','LEONARDA','KAYLEIGH','FRANCE','ETHYL','ELLYN','DAYLE','CAMMIE','BRITTNI','BIRGIT','AVELINA','ASUNCION','ARIANNA','AKIKO','VENICE','TYESHA','TONIE','TIESHA','TAKISHA','STEFFANIE','SINDY','SANTANA','MEGHANN','MANDA','MACIE','LADY','KELLYE','KELLEE','JOSLYN','JASON','INGER','INDIRA','GLINDA','GLENNIS','FERNANDA','FAUSTINA','ENEIDA','ELICIA','DOT','DIGNA','DELL','ARLETTA','ANDRE','WILLIA','TAMMARA','TABETHA','SHERRELL','SARI','REFUGIO','REBBECA','PAULETTA','NIEVES','NATOSHA','NAKITA','MAMMIE','KENISHA','KAZUKO','KASSIE','GARY','EARLEAN','DAPHINE','CORLISS','CLOTILDE','CAROLYNE','BERNETTA','AUGUSTINA','AUDREA','ANNIS','ANNABELL','YAN','TENNILLE','TAMICA','SELENE','SEAN','ROSANA','REGENIA','QIANA','MARKITA','MACY','LEEANNE','LAURINE','KYM','JESSENIA','JANITA','GEORGINE','GENIE','EMIKO','ELVIE','DEANDRA','DAGMAR','CORIE','COLLEN','CHERISH','ROMAINE','PORSHA','PEARLENE','MICHELINE','MERNA','MARGORIE','MARGARETTA','LORE','KENNETH','JENINE','HERMINA','FREDERICKA','ELKE','DRUSILLA','DORATHY','DIONE','DESIRE','CELENA','BRIGIDA','ANGELES','ALLEGRA','THEO','TAMEKIA','SYNTHIA','STEPHEN','SOOK','SLYVIA','ROSANN','REATHA','RAYE','MARQUETTA','MARGART','LING','LAYLA','KYMBERLY','KIANA','KAYLEEN','KATLYN','KARMEN','JOELLA','IRINA','EMELDA','ELENI','DETRA','CLEMMIE','CHERYLL','CHANTELL','CATHEY','ARNITA','ARLA','ANGLE','ANGELIC','ALYSE','ZOFIA','THOMASINE','TENNIE','SON','SHERLY','SHERLEY','SHARYL','REMEDIOS','PETRINA','NICKOLE','MYUNG','MYRLE','MOZELLA','LOUANNE','LISHA','LATIA','LANE','KRYSTA','JULIENNE','JOEL','JEANENE','JACQUALINE','ISAURA','GWENDA','EARLEEN','DONALD','CLEOPATRA','CARLIE','AUDIE','ANTONIETTA','ALISE','ALEX','VERDELL','VAL','TYLER','TOMOKO','THAO','TALISHA','STEVEN','SO','SHEMIKA','SHAUN','SCARLET','SAVANNA','SANTINA','ROSIA','RAEANN','ODILIA','NANA','MINNA','MAGAN','LYNELLE','LE','KARMA','JOEANN','IVANA','INELL','ILANA','HYE','HONEY','HEE','GUDRUN','FRANK','DREAMA','CRISSY','CHANTE','CARMELINA','ARVILLA','ARTHUR','ANNAMAE','ALVERA','ALEIDA','AARON','YEE','YANIRA','VANDA','TIANNA','TAM','STEFANIA','SHIRA','PERRY','NICOL','NANCIE','MONSERRATE','MINH','MELYNDA','MELANY','MATTHEW','LOVELLA','LAURE','KIRBY','KACY','JACQUELYNN','HYON','GERTHA','FRANCISCO','ELIANA','CHRISTENA','CHRISTEEN','CHARISE','CATERINA','CARLEY','CANDYCE','ARLENA','AMMIE','YANG','WILLETTE','VANITA','TUYET','TINY','SYREETA','SILVA','SCOTT','RONALD','PENNEY','NYLA','MICHAL','MAURICE','MARYAM','MARYA','MAGEN','LUDIE','LOMA','LIVIA','LANELL','KIMBERLIE','JULEE','DONETTA','DIEDRA','DENISHA','DEANE','DAWNE','CLARINE','CHERRYL','BRONWYN','BRANDON','ALLA','VALERY','TONDA','SUEANN','SORAYA','SHOSHANA','SHELA','SHARLEEN','SHANELLE','NERISSA','MICHEAL','MERIDITH','MELLIE','MAYE','MAPLE','MAGARET','LUIS','LILI','LEONILA','LEONIE','LEEANNA','LAVONIA','LAVERA','KRISTEL','KATHEY','KATHE','JUSTIN','JULIAN','JIMMY','JANN','ILDA','HILDRED','HILDEGARDE','GENIA','FUMIKO','EVELIN','ERMELINDA','ELLY','DUNG','DOLORIS','DIONNA','DANAE','BERNEICE','ANNICE','ALIX','VERENA','VERDIE','TRISTAN','SHAWNNA','SHAWANA','SHAUNNA','ROZELLA','RANDEE','RANAE','MILAGRO','LYNELL','LUISE','LOUIE','LOIDA','LISBETH','KARLEEN','JUNITA','JONA','ISIS','HYACINTH','HEDY','GWENN','ETHELENE','ERLINE','EDWARD','DONYA','DOMONIQUE','DELICIA','DANNETTE','CICELY','BRANDA','BLYTHE','BETHANN','ASHLYN','ANNALEE','ALLINE','YUKO','VELLA','TRANG','TOWANDA','TESHA','SHERLYN','NARCISA','MIGUELINA','MERI','MAYBELL','MARLANA','MARGUERITA','MADLYN','LUNA','LORY','LORIANN','LIBERTY','LEONORE','LEIGHANN','LAURICE','LATESHA','LARONDA','KATRICE','KASIE','KARL','KALEY','JADWIGA','GLENNIE','GEARLDINE','FRANCINA','EPIFANIA','DYAN','DORIE','DIEDRE','DENESE','DEMETRICE','DELENA','DARBY','CRISTIE','CLEORA','CATARINA','CARISA','BERNIE','BARBERA','ALMETA','TRULA','TEREASA','SOLANGE','SHEILAH','SHAVONNE','SANORA','ROCHELL','MATHILDE','MARGARETA','MAIA','LYNSEY','LAWANNA','LAUNA','KENA','KEENA','KATIA','JAMEY','GLYNDA','GAYLENE','ELVINA','ELANOR','DANUTA','DANIKA','CRISTEN','CORDIE','COLETTA','CLARITA','CARMON','BRYNN','AZUCENA','AUNDREA','ANGELE','YI','WALTER','VERLIE','VERLENE','TAMESHA','SILVANA','SEBRINA','SAMIRA','REDA','RAYLENE','PENNI','PANDORA','NORAH','NOMA','MIREILLE','MELISSIA','MARYALICE','LARAINE','KIMBERY','KARYL','KARINE','KAM','JOLANDA','JOHANA','JESUSA','JALEESA','JAE','JACQUELYNE','IRISH','ILUMINADA','HILARIA','HANH','GENNIE','FRANCIE','FLORETTA','EXIE','EDDA','DREMA','DELPHA','BEV','BARBAR','ASSUNTA','ARDELL','ANNALISA','ALISIA','YUKIKO','YOLANDO','WONDA','WEI','WALTRAUD','VETA','TEQUILA','TEMEKA','TAMEIKA','SHIRLEEN','SHENITA','PIEDAD','OZELLA','MIRTHA','MARILU','KIMIKO','JULIANE','JENICE','JEN','JANAY','JACQUILINE','HILDE','FE','FAE','EVAN','EUGENE','ELOIS','ECHO','DEVORAH','CHAU','BRINDA','BETSEY','ARMINDA','ARACELIS','APRYL','ANNETT','ALISHIA','VEOLA','USHA','TOSHIKO','THEOLA','TASHIA','TALITHA','SHERY','RUDY','RENETTA','REIKO','RASHEEDA','OMEGA','OBDULIA','MIKA','MELAINE','MEGGAN','MARTIN','MARLEN','MARGET','MARCELINE','MANA','MAGDALEN','LIBRADA','LEZLIE','LEXIE','LATASHIA','LASANDRA','KELLE','ISIDRA','ISA','INOCENCIA','GWYN','FRANCOISE','ERMINIA','ERINN','DIMPLE','DEVORA','CRISELDA','ARMANDA','ARIE','ARIANE','ANGELO','ANGELENA','ALLEN','ALIZA','ADRIENE','ADALINE','XOCHITL','TWANNA','TRAN','TOMIKO','TAMISHA','TAISHA','SUSY','SIU','RUTHA','ROXY','RHONA','RAYMOND','OTHA','NORIKO','NATASHIA','MERRIE','MELVIN','MARINDA','MARIKO','MARGERT','LORIS','LIZZETTE','LEISHA','KAILA','KA','JOANNIE','JERRICA','JENE','JANNET','JANEE','JACINDA','HERTA','ELENORE','DORETTA','DELAINE','DANIELL','CLAUDIE','CHINA','BRITTA','APOLONIA','AMBERLY','ALEASE','YURI','YUK','WEN','WANETA','UTE','TOMI','SHARRI','SANDIE','ROSELLE','REYNALDA','RAGUEL','PHYLICIA','PATRIA','OLIMPIA','ODELIA','MITZIE','MITCHELL','MISS','MINDA','MIGNON','MICA','MENDY','MARIVEL','MAILE','LYNETTA','LAVETTE','LAURYN','LATRISHA','LAKIESHA','KIERSTEN','KARY','JOSPHINE','JOLYN','JETTA','JANISE','JACQUIE','IVELISSE','GLYNIS','GIANNA','GAYNELLE','EMERALD','DEMETRIUS','DANYELL','DANILLE','DACIA','CORALEE','CHER','CEOLA','BRETT','BELL','ARIANNE','ALESHIA','YUNG','WILLIEMAE','TROY','TRINH','THORA','TAI','SVETLANA','SHERIKA','SHEMEKA','SHAUNDA','ROSELINE','RICKI','MELDA','MALLIE','LAVONNA','LATINA','LARRY','LAQUANDA','LALA','LACHELLE','KLARA','KANDIS','JOHNA','JEANMARIE','JAYE','HANG','GRAYCE','GERTUDE','EMERITA','EBONIE','CLORINDA','CHING','CHERY','CAROLA','BREANN','BLOSSOM','BERNARDINE','BECKI','ARLETHA','ARGELIA','ARA','ALITA','YULANDA','YON','YESSENIA','TOBI','TASIA','SYLVIE','SHIRL','SHIRELY','SHERIDAN','SHELLA','SHANTELLE','SACHA','ROYCE','REBECKA','REAGAN','PROVIDENCIA','PAULENE','MISHA','MIKI','MARLINE','MARICA','LORITA','LATOYIA','LASONYA','KERSTIN','KENDA','KEITHA','KATHRIN','JAYMIE','JACK','GRICELDA','GINETTE','ERYN','ELINA','ELFRIEDA','DANYEL','CHEREE','CHANELLE','BARRIE','AVERY','AURORE','ANNAMARIA','ALLEEN','AILENE','AIDE','YASMINE','VASHTI','VALENTINE','TREASA','TORY','TIFFANEY','SHERYLL','SHARIE','SHANAE','SAU','RAISA','PA','NEDA','MITSUKO','MIRELLA','MILDA','MARYANNA','MARAGRET','MABELLE','LUETTA','LORINA','LETISHA','LATARSHA','LANELLE','LAJUANA','KRISSY','KARLY','KARENA','JON','JESSIKA','JERICA','JEANELLE','JANUARY','JALISA','JACELYN','IZOLA','IVEY','GREGORY','EUNA','ETHA','DREW','DOMITILA','DOMINICA','DAINA','CREOLA','CARLI','CAMIE','BUNNY','BRITTNY','ASHANTI','ANISHA','ALEEN','ADAH','YASUKO','WINTER','VIKI','VALRIE','TONA','TINISHA','THI','TERISA','TATUM','TANEKA','SIMONNE','SHALANDA','SERITA','RESSIE','REFUGIA','PAZ','OLENE','NA','MERRILL','MARGHERITA','MANDIE','MAN','MAIRE','LYNDIA','LUCI','LORRIANE','LORETA','LEONIA','LAVONA','LASHAWNDA','LAKIA','KYOKO','KRYSTINA','KRYSTEN','KENIA','KELSI','JUDE','JEANICE','ISOBEL','GEORGIANN','GENNY','FELICIDAD','EILENE','DEON','DELOISE','DEEDEE','DANNIE','CONCEPTION','CLORA','CHERILYN','CHANG','CALANDRA','BERRY','ARMANDINA','ANISA','ULA','TIMOTHY','TIERA','THERESSA','STEPHANIA','SIMA','SHYLA','SHONTA','SHERA','SHAQUITA','SHALA','SAMMY','ROSSANA','NOHEMI','NERY','MORIAH','MELITA','MELIDA','MELANI','MARYLYNN','MARISHA','MARIETTE','MALORIE','MADELENE','LUDIVINA','LORIA','LORETTE','LORALEE','LIANNE','LEON','LAVENIA','LAURINDA','LASHON','KIT','KIMI','KEILA','KATELYNN','KAI','JONE','JOANE','JI','JAYNA','JANELLA','JA','HUE','HERTHA','FRANCENE','ELINORE','DESPINA','DELSIE','DEEDRA','CLEMENCIA','CARRY','CAROLIN','CARLOS','BULAH','BRITTANIE','BOK','BLONDELL','BIBI','BEAULAH','BEATA','ANNITA','AGRIPINA','VIRGEN','VALENE','UN','TWANDA','TOMMYE','TOI','TARRA','TARI','TAMMERA','SHAKIA','SADYE','RUTHANNE','ROCHEL','RIVKA','PURA','NENITA','NATISHA','MING','MERRILEE','MELODEE','MARVIS','LUCILLA','LEENA','LAVETA','LARITA','LANIE','KEREN','ILEEN','GEORGEANN','GENNA','GENESIS','FRIDA','EWA','EUFEMIA','EMELY','ELA','EDYTH','DEONNA','DEADRA','DARLENA','CHANELL','CHAN','CATHERN','CASSONDRA','CASSAUNDRA','BERNARDA','BERNA','ARLINDA','ANAMARIA','ALBERT','WESLEY','VERTIE','VALERI','TORRI','TATYANA','STASIA','SHERISE','SHERILL','SEASON','SCOTTIE','SANDA','RUTHE','ROSY','ROBERTO','ROBBI','RANEE','QUYEN','PEARLY','PALMIRA','ONITA','NISHA','NIESHA','NIDA','NEVADA','NAM','MERLYN','MAYOLA','MARYLOUISE','MARYLAND','MARX','MARTH','MARGENE','MADELAINE','LONDA','LEONTINE','LEOMA','LEIA','LAWRENCE','LAURALEE','LANORA','LAKITA','KIYOKO','KETURAH','KATELIN','KAREEN','JONIE','JOHNETTE','JENEE','JEANETT','IZETTA','HIEDI','HEIKE','HASSIE','HAROLD','GIUSEPPINA','GEORGANN','FIDELA','FERNANDE','ELWANDA','ELLAMAE','ELIZ','DUSTI','DOTTY','CYNDY','CORALIE','CELESTA','ARGENTINA','ALVERTA','XENIA','WAVA','VANETTA','TORRIE','TASHINA','TANDY','TAMBRA','TAMA','STEPANIE','SHILA','SHAUNTA','SHARAN','SHANIQUA','SHAE','SETSUKO','SERAFINA','SANDEE','ROSAMARIA','PRISCILA','OLINDA','NADENE','MUOI','MICHELINA','MERCEDEZ','MARYROSE','MARIN','MARCENE','MAO','MAGALI','MAFALDA','LOGAN','LINN','LANNIE','KAYCE','KAROLINE','KAMILAH','KAMALA','JUSTA','JOLINE','JENNINE','JACQUETTA','IRAIDA','GERALD','GEORGEANNA','FRANCHESCA','FAIRY','EMELINE','ELANE','EHTEL','EARLIE','DULCIE','DALENE','CRIS','CLASSIE','CHERE','CHARIS','CAROYLN','CARMINA','CARITA','BRIAN','BETHANIE','AYAKO','ARICA','AN','ALYSA','ALESSANDRA','AKILAH','ADRIEN','ZETTA','YOULANDA','YELENA','YAHAIRA','XUAN','WENDOLYN','VICTOR','TIJUANA','TERRELL','TERINA','TERESIA','SUZI','SUNDAY','SHERELL','SHAVONDA','SHAUNTE','SHARDA','SHAKITA','SENA','RYANN','RUBI','RIVA','REGINIA','REA','RACHAL','PARTHENIA','PAMULA','MONNIE','MONET','MICHAELE','MELIA','MARINE','MALKA','MAISHA','LISANDRA','LEO','LEKISHA','LEAN','LAURENCE','LAKENDRA','KRYSTIN','KORTNEY','KIZZIE','KITTIE','KERA','KENDAL','KEMBERLY','KANISHA','JULENE','JULE','JOSHUA','JOHANNE','JEFFREY','JAMEE','HAN','HALLEY','GIDGET','GALINA','FREDRICKA','FLETA','FATIMAH','EUSEBIA','ELZA','ELEONORE','DORTHEY','DORIA','DONELLA','DINORAH','DELORSE','CLARETHA','CHRISTINIA','CHARLYN','BONG','BELKIS','AZZIE','ANDERA','AIKO','ADENA','YER','YAJAIRA','WAN','VANIA','ULRIKE','TOSHIA','TIFANY','STEFANY','SHIZUE','SHENIKA','SHAWANNA','SHAROLYN','SHARILYN','SHAQUANA','SHANTAY','SEE','ROZANNE','ROSELEE','RICKIE','REMONA','REANNA','RAELENE','QUINN','PHUNG','PETRONILA','NATACHA','NANCEY','MYRL','MIYOKO','MIESHA','MERIDETH','MARVELLA','MARQUITTA','MARHTA','MARCHELLE','LIZETH','LIBBIE','LAHOMA','LADAWN','KINA','KATHELEEN','KATHARYN','KARISA','KALEIGH','JUNIE','JULIEANN','JOHNSIE','JANEAN','JAIMEE','JACKQUELINE','HISAKO','HERMA','HELAINE','GWYNETH','GLENN','GITA','EUSTOLIA','EMELINA','ELIN','EDRIS','DONNETTE','DONNETTA','DIERDRE','DENAE','DARCEL','CLAUDE','CLARISA','CINDERELLA','CHIA','CHARLESETTA','CHARITA','CELSA','CASSY','CASSI','CARLEE','BRUNA','BRITTANEY','BRANDE','BILLI','BAO','ANTONETTA','ANGLA','ANGELYN','ANALISA','ALANE','WENONA','WENDIE','VERONIQUE','VANNESA','TOBIE','TEMPIE','SUMIKO','SULEMA','SPARKLE','SOMER','SHEBA','SHAYNE','SHARICE','SHANEL','SHALON','SAGE','ROY','ROSIO','ROSELIA','RENAY','REMA','REENA','PORSCHE','PING','PEG','OZIE','ORETHA','ORALEE','ODA','NU','NGAN','NAKESHA','MILLY','MARYBELLE','MARLIN','MARIS','MARGRETT','MARAGARET','MANIE','LURLENE','LILLIA','LIESELOTTE','LAVELLE','LASHAUNDA','LAKEESHA','KEITH','KAYCEE','KALYN','JOYA','JOETTE','JENAE','JANIECE','ILLA','GRISEL','GLAYDS','GENEVIE','GALA','FREDDA','FRED','ELMER','ELEONOR','DEBERA','DEANDREA','DAN','CORRINNE','CORDIA','CONTESSA','COLENE','CLEOTILDE','CHARLOTT','CHANTAY','CECILLE','BEATRIS','AZALEE','ARLEAN','ARDATH','ANJELICA','ANJA','ALFREDIA','ALEISHA','ADAM','ZADA','YUONNE','XIAO','WILLODEAN','WHITLEY','VENNIE','VANNA','TYISHA','TOVA','TORIE','TONISHA','TILDA','TIEN','TEMPLE','SIRENA','SHERRIL','SHANTI','SHAN','SENAIDA','SAMELLA','ROBBYN','RENDA','REITA','PHEBE','PAULITA','NOBUKO','NGUYET','NEOMI','MOON','MIKAELA','MELANIA','MAXIMINA','MARG','MAISIE','LYNNA','LILLI','LAYNE','LASHAUN','LAKENYA','LAEL','KIRSTIE','KATHLINE','KASHA','KARLYN','KARIMA','JOVAN','JOSEFINE','JENNELL','JACQUI','JACKELYN','HYO','HIEN','GRAZYNA','FLORRIE','FLORIA','ELEONORA','DWANA','DORLA','DONG','DELMY','DEJA','DEDE','DANN','CRYSTA','CLELIA','CLARIS','CLARENCE','CHIEKO','CHERLYN','CHERELLE','CHARMAIN','CHARA','CAMMY','BEE','ARNETTE','ARDELLE','ANNIKA','AMIEE','AMEE','ALLENA','YVONE','YUKI','YOSHIE','YEVETTE','YAEL','WILLETTA','VONCILE','VENETTA','TULA','TONETTE','TIMIKA','TEMIKA','TELMA','TEISHA','TAREN','TA','STACEE','SHIN','SHAWNTA','SATURNINA','RICARDA','POK','PASTY','ONIE','NUBIA','MORA','MIKE','MARIELLE','MARIELLA','MARIANELA','MARDELL','MANY','LUANNA','LOISE','LISABETH','LINDSY','LILLIANA','LILLIAM','LELAH','LEIGHA','LEANORA','LANG','KRISTEEN','KHALILAH','KEELEY','KANDRA','JUNKO','JOAQUINA','JERLENE','JANI','JAMIKA','JAME','HSIU','HERMILA','GOLDEN','GENEVIVE','EVIA','EUGENA','EMMALINE','ELFREDA','ELENE','DONETTE','DELCIE','DEEANNA','DARCEY','CUC','CLARINDA','CIRA','CHAE','CELINDA','CATHERYN','CATHERIN','CASIMIRA','CARMELIA','CAMELLIA','BREANA','BOBETTE','BERNARDINA','BEBE','BASILIA','ARLYNE','AMAL','ALAYNA','ZONIA','ZENIA','YURIKO','YAEKO','WYNELL','WILLOW','WILLENA','VERNIA','TU','TRAVIS','TORA','TERRILYN','TERICA','TENESHA','TAWNA','TAJUANA','TAINA','STEPHNIE','SONA','SOL','SINA','SHONDRA','SHIZUKO','SHERLENE','SHERICE','SHARIKA','ROSSIE','ROSENA','RORY','RIMA','RIA','RHEBA','RENNA','PETER','NATALYA','NANCEE','MELODI','MEDA','MAXIMA','MATHA','MARKETTA','MARICRUZ','MARCELENE','MALVINA','LUBA','LOUETTA','LEIDA','LECIA','LAURAN','LASHAWNA','LAINE','KHADIJAH','KATERINE','KASI','KALLIE','JULIETTA','JESUSITA','JESTINE','JESSIA','JEREMY','JEFFIE','JANYCE','ISADORA','GEORGIANNE','FIDELIA','EVITA','EURA','EULAH','ESTEFANA','ELSY','ELIZABET','ELADIA','DODIE','DION','DIA','DENISSE','DELORAS','DELILA','DAYSI','DAKOTA','CURTIS','CRYSTLE','CONCHA','COLBY','CLARETTA','CHU','CHRISTIA','CHARLSIE','CHARLENA','CARYLON','BETTYANN','ASLEY','ASHLEA','AMIRA','AI','AGUEDA','AGNUS','YUETTE','VINITA','VICTORINA','TYNISHA','TREENA','TOCCARA','TISH','THOMASENA','TEGAN','SOILA','SHILOH','SHENNA','SHARMAINE','SHANTAE','SHANDI','SEPTEMBER','SARAN','SARAI','SANA','SAMUEL','SALLEY','ROSETTE','ROLANDE','REGINE','OTELIA','OSCAR','OLEVIA','NICHOLLE','NECOLE','NAIDA','MYRTA','MYESHA','MITSUE','MINTA','MERTIE','MARGY','MAHALIA','MADALENE','LOVE','LOURA','LOREAN','LEWIS','LESHA','LEONIDA','LENITA','LAVONE','LASHELL','LASHANDRA','LAMONICA','KIMBRA','KATHERINA','KARRY','KANESHA','JULIO','JONG','JENEVA','JAQUELYN','HWA','GILMA','GHISLAINE','GERTRUDIS','FRANSISCA','FERMINA','ETTIE','ETSUKO','ELLIS','ELLAN','ELIDIA','EDRA','DORETHEA','DOREATHA','DENYSE','DENNY','DEETTA','DAINE','CYRSTAL','CORRIN','CAYLA','CARLITA','CAMILA','BURMA','BULA','BUENA','BLAKE','BARABARA','AVRIL','AUSTIN','ALAINE','ZANA','WILHEMINA','WANETTA','VIRGIL','VI','VERONIKA','VERNON','VERLINE','VASILIKI','TONITA','TISA','TEOFILA','TAYNA','TAUNYA','TANDRA','TAKAKO','SUNNI','SUANNE','SIXTA','SHARELL','SEEMA','RUSSELL','ROSENDA','ROBENA','RAYMONDE','PEI','PAMILA','OZELL','NEIDA','NEELY','MISTIE','MICHA','MERISSA','MAURITA','MARYLN','MARYETTA','MARSHALL','MARCELL','MALENA','MAKEDA','MADDIE','LOVETTA','LOURIE','LORRINE','LORILEE','LESTER','LAURENA','LASHAY','LARRAINE','LAREE','LACRESHA','KRISTLE','KRISHNA','KEVA','KEIRA','KAROLE','JOIE','JINNY','JEANNETTA','JAMA','HEIDY','GILBERTE','GEMA','FAVIOLA','EVELYNN','ENDA','ELLI','ELLENA','DIVINA','DAGNY','COLLENE','CODI','CINDIE','CHASSIDY','CHASIDY','CATRICE','CATHERINA','CASSEY','CAROLL','CARLENA','CANDRA','CALISTA','BRYANNA','BRITTENY','BEULA','BARI','AUDRIE','AUDRIA','ARDELIA','ANNELLE','ANGILA','ALONA','ALLYN','DOUGLAS','ROGER','JONATHAN','RALPH','NICHOLAS','BENJAMIN','BRUCE','HARRY','WAYNE','STEVE','HOWARD','ERNEST','PHILLIP','TODD','CRAIG','ALAN','PHILIP','EARL','DANNY','BRYAN','STANLEY','LEONARD','NATHAN','MANUEL','RODNEY','MARVIN','VINCENT','JEFFERY','JEFF','CHAD','JACOB','ALFRED','BRADLEY','HERBERT','FREDERICK','EDWIN','DON','RICKY','RANDALL','BARRY','BERNARD','LEROY','MARCUS','THEODORE','CLIFFORD','MIGUEL','JIM','TOM','CALVIN','BILL','LLOYD','DEREK','WARREN','DARRELL','JEROME','FLOYD','ALVIN','TIM','GORDON','GREG','JORGE','DUSTIN','PEDRO','DERRICK','ZACHARY','HERMAN','GLEN','HECTOR','RICARDO','RICK','BRENT','RAMON','GILBERT','MARC','REGINALD','RUBEN','NATHANIEL','RAFAEL','EDGAR','MILTON','RAUL','BEN','CHESTER','DUANE','FRANKLIN','BRAD','RON','ROLAND','ARNOLD','HARVEY','JARED','ERIK','DARRYL','NEIL','JAVIER','FERNANDO','CLINTON','TED','MATHEW','TYRONE','DARREN','LANCE','KURT','ALLAN','NELSON','GUY','CLAYTON','HUGH','MAX','DWAYNE','DWIGHT','ARMANDO','FELIX','EVERETT','IAN','WALLACE','KEN','BOB','ALFREDO','ALBERTO','DAVE','IVAN','BYRON','ISAAC','MORRIS','CLIFTON','WILLARD','ROSS','ANDY','SALVADOR','KIRK','SERGIO','SETH','KENT','TERRANCE','EDUARDO','TERRENCE','ENRIQUE','WADE','STUART','FREDRICK','ARTURO','ALEJANDRO','NICK','LUTHER','WENDELL','JEREMIAH','JULIUS','OTIS','TREVOR','OLIVER','LUKE','HOMER','GERARD','DOUG','KENNY','HUBERT','LYLE','MATT','ALFONSO','ORLANDO','REX','CARLTON','ERNESTO','NEAL','PABLO','LORENZO','OMAR','WILBUR','GRANT','HORACE','RODERICK','ABRAHAM','WILLIS','RICKEY','ANDRES','CESAR','JOHNATHAN','MALCOLM','RUDOLPH','DAMON','KELVIN','PRESTON','ALTON','ARCHIE','MARCO','WM','PETE','RANDOLPH','GARRY','GEOFFREY','JONATHON','FELIPE','GERARDO','ED','DOMINIC','DELBERT','COLIN','GUILLERMO','EARNEST','LUCAS','BENNY','SPENCER','RODOLFO','MYRON','EDMUND','GARRETT','SALVATORE','CEDRIC','LOWELL','GREGG','SHERMAN','WILSON','SYLVESTER','ROOSEVELT','ISRAEL','JERMAINE','FORREST','WILBERT','LELAND','SIMON','CLARK','IRVING','BRYANT','OWEN','RUFUS','WOODROW','KRISTOPHER','MACK','LEVI','MARCOS','GUSTAVO','JAKE','LIONEL','GILBERTO','CLINT','NICOLAS','ISMAEL','ORVILLE','ERVIN','DEWEY','AL','WILFRED','JOSH','HUGO','IGNACIO','CALEB','TOMAS','SHELDON','ERICK','STEWART','DOYLE','DARREL','ROGELIO','TERENCE','SANTIAGO','ALONZO','ELIAS','BERT','ELBERT','RAMIRO','CONRAD','NOAH','GRADY','PHIL','CORNELIUS','LAMAR','ROLANDO','CLAY','PERCY','DEXTER','BRADFORD','DARIN','AMOS','MOSES','IRVIN','SAUL','ROMAN','RANDAL','TIMMY','DARRIN','WINSTON','BRENDAN','ABEL','DOMINICK','BOYD','EMILIO','ELIJAH','DOMINGO','EMMETT','MARLON','EMANUEL','JERALD','EDMOND','EMIL','DEWAYNE','WILL','OTTO','TEDDY','REYNALDO','BRET','JESS','TRENT','HUMBERTO','EMMANUEL','STEPHAN','VICENTE','LAMONT','GARLAND','MILES','EFRAIN','HEATH','RODGER','HARLEY','ETHAN','ELDON','ROCKY','PIERRE','JUNIOR','FREDDY','ELI','BRYCE','ANTOINE','STERLING','CHASE','GROVER','ELTON','CLEVELAND','DYLAN','CHUCK','DAMIAN','REUBEN','STAN','AUGUST','LEONARDO','JASPER','RUSSEL','ERWIN','BENITO','HANS','MONTE','BLAINE','ERNIE','CURT','QUENTIN','AGUSTIN','MURRAY','JAMAL','ADOLFO','HARRISON','TYSON','BURTON','BRADY','ELLIOTT','WILFREDO','BART','JARROD','VANCE','DENIS','DAMIEN','JOAQUIN','HARLAN','DESMOND','ELLIOT','DARWIN','GREGORIO','BUDDY','XAVIER','KERMIT','ROSCOE','ESTEBAN','ANTON','SOLOMON','SCOTTY','NORBERT','ELVIN','WILLIAMS','NOLAN','ROD','QUINTON','HAL','BRAIN','ROB','ELWOOD','KENDRICK','DARIUS','MOISES','FIDEL','THADDEUS','CLIFF','MARCEL','JACKSON','RAPHAEL','BRYON','ARMAND','ALVARO','JEFFRY','DANE','JOESPH','THURMAN','NED','RUSTY','MONTY','FABIAN','REGGIE','MASON','GRAHAM','ISAIAH','VAUGHN','GUS','LOYD','DIEGO','ADOLPH','NORRIS','MILLARD','ROCCO','GONZALO','DERICK','RODRIGO','WILEY','RIGOBERTO','ALPHONSO','TY','NOE','VERN','REED','JEFFERSON','ELVIS','BERNARDO','MAURICIO','HIRAM','DONOVAN','BASIL','RILEY','NICKOLAS','MAYNARD','SCOT','VINCE','QUINCY','EDDY','SEBASTIAN','FEDERICO','ULYSSES','HERIBERTO','DONNELL','COLE','DAVIS','GAVIN','EMERY','WARD','ROMEO','JAYSON','DANTE','CLEMENT','COY','MAXWELL','JARVIS','BRUNO','ISSAC','DUDLEY','BROCK','SANFORD','CARMELO','BARNEY','NESTOR','STEFAN','DONNY','ART','LINWOOD','BEAU','WELDON','GALEN','ISIDRO','TRUMAN','DELMAR','JOHNATHON','SILAS','FREDERIC','DICK','IRWIN','MERLIN','CHARLEY','MARCELINO','HARRIS','CARLO','TRENTON','KURTIS','HUNTER','AURELIO','WINFRED','VITO','COLLIN','DENVER','CARTER','LEONEL','EMORY','PASQUALE','MOHAMMAD','MARIANO','DANIAL','LANDON','DIRK','BRANDEN','ADAN','BUFORD','GERMAN','WILMER','EMERSON','ZACHERY','FLETCHER','JACQUES','ERROL','DALTON','MONROE','JOSUE','EDWARDO','BOOKER','WILFORD','SONNY','SHELTON','CARSON','THERON','RAYMUNDO','DAREN','HOUSTON','ROBBY','LINCOLN','GENARO','BENNETT','OCTAVIO','CORNELL','HUNG','ARRON','ANTONY','HERSCHEL','GIOVANNI','GARTH','CYRUS','CYRIL','RONNY','LON','FREEMAN','DUNCAN','KENNITH','CARMINE','ERICH','CHADWICK','WILBURN','RUSS','REID','MYLES','ANDERSON','MORTON','JONAS','FOREST','MITCHEL','MERVIN','ZANE','RICH','JAMEL','LAZARO','ALPHONSE','RANDELL','MAJOR','JARRETT','BROOKS','ABDUL','LUCIANO','SEYMOUR','EUGENIO','MOHAMMED','VALENTIN','CHANCE','ARNULFO','LUCIEN','FERDINAND','THAD','EZRA','ALDO','RUBIN','ROYAL','MITCH','EARLE','ABE','WYATT','MARQUIS','LANNY','KAREEM','JAMAR','BORIS','ISIAH','EMILE','ELMO','ARON','LEOPOLDO','EVERETTE','JOSEF','ELOY','RODRICK','REINALDO','LUCIO','JERROD','WESTON','HERSHEL','BARTON','PARKER','LEMUEL','BURT','JULES','GIL','ELISEO','AHMAD','NIGEL','EFREN','ANTWAN','ALDEN','MARGARITO','COLEMAN','DINO','OSVALDO','LES','DEANDRE','NORMAND','KIETH','TREY','NORBERTO','NAPOLEON','JEROLD','FRITZ','ROSENDO','MILFORD','CHRISTOPER','ALFONZO','LYMAN','JOSIAH','BRANT','WILTON','RICO','JAMAAL','DEWITT','BRENTON','OLIN','FOSTER','FAUSTINO','CLAUDIO','JUDSON','GINO','EDGARDO','ALEC','TANNER','JARRED','DONN','TAD','PRINCE','PORFIRIO','ODIS','LENARD','CHAUNCEY','TOD','MEL','MARCELO','KORY','AUGUSTUS','KEVEN','HILARIO','BUD','SAL','ORVAL','MAURO','ZACHARIAH','OLEN','ANIBAL','MILO','JED','DILLON','AMADO','NEWTON','LENNY','RICHIE','HORACIO','BRICE','MOHAMED','DELMER','DARIO','REYES','MAC','JONAH','JERROLD','ROBT','HANK','RUPERT','ROLLAND','KENTON','DAMION','ANTONE','WALDO','FREDRIC','BRADLY','KIP','BURL','WALKER','TYREE','JEFFEREY','AHMED','WILLY','STANFORD','OREN','NOBLE','MOSHE','MIKEL','ENOCH','BRENDON','QUINTIN','JAMISON','FLORENCIO','DARRICK','TOBIAS','HASSAN','GIUSEPPE','DEMARCUS','CLETUS','TYRELL','LYNDON','KEENAN','WERNER','GERALDO','COLUMBUS','CHET','BERTRAM','MARKUS','HUEY','HILTON','DWAIN','DONTE','TYRON','OMER','ISAIAS','HIPOLITO','FERMIN','ADALBERTO','BO','BARRETT','TEODORO','MCKINLEY','MAXIMO','GARFIELD','RALEIGH','LAWERENCE','ABRAM','RASHAD','KING','EMMITT','DARON','SAMUAL','MIQUEL','EUSEBIO','DOMENIC','DARRON','BUSTER','WILBER','RENATO','JC','HOYT','HAYWOOD','EZEKIEL','CHAS','FLORENTINO','ELROY','CLEMENTE','ARDEN','NEVILLE','EDISON','DESHAWN','NATHANIAL','JORDON','DANILO','CLAUD','SHERWOOD','RAYMON','RAYFORD','CRISTOBAL','AMBROSE','TITUS','HYMAN','FELTON','EZEQUIEL','ERASMO','STANTON','LONNY','LEN','IKE','MILAN','LINO','JAROD','HERB','ANDREAS','WALTON','RHETT','PALMER','DOUGLASS','CORDELL','OSWALDO','ELLSWORTH','VIRGILIO','TONEY','NATHANAEL','DEL','BENEDICT','MOSE','JOHNSON','ISREAL','GARRET','FAUSTO','ASA','ARLEN','ZACK','WARNER','MODESTO','FRANCESCO','MANUAL','GAYLORD','GASTON','FILIBERTO','DEANGELO','MICHALE','GRANVILLE','WES','MALIK','ZACKARY','TUAN','ELDRIDGE','CRISTOPHER','CORTEZ','ANTIONE','MALCOM','LONG','KOREY','JOSPEH','COLTON','WAYLON','VON','HOSEA','SHAD','SANTO','RUDOLF','ROLF','REY','RENALDO','MARCELLUS','LUCIUS','KRISTOFER','BOYCE','BENTON','HAYDEN','HARLAND','ARNOLDO','RUEBEN','LEANDRO','KRAIG','JERRELL','JEROMY','HOBERT','CEDRICK','ARLIE','WINFORD','WALLY','LUIGI','KENETH','JACINTO','GRAIG','FRANKLYN','EDMUNDO','SID','PORTER','LEIF','JERAMY','BUCK','WILLIAN','VINCENZO','SHON','LYNWOOD','JERE','HAI','ELDEN','DORSEY','DARELL','BRODERICK','ALONSO'];", + "tail": "" + } + } + }, + { + "id": "5900f3831000cf542c50fe96", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 23: Non-abundant sums", + "tests": [ + { + "text": "sumOfNonAbundantNumbers(10000) should return 3731004.", + "testString": "assert(sumOfNonAbundantNumbers(10000) === 3731004, 'sumOfNonAbundantNumbers(10000) should return 3731004.');" + }, + { + "text": "sumOfNonAbundantNumbers(15000) should return 4039939.", + "testString": "assert(sumOfNonAbundantNumbers(15000) === 4039939, 'sumOfNonAbundantNumbers(15000) should return 4039939.');" + }, + { + "text": "sumOfNonAbundantNumbers(20000) should return 4159710.", + "testString": "assert(sumOfNonAbundantNumbers(20000) === 4159710, 'sumOfNonAbundantNumbers(20000) should return 4159710.');" + }, + { + "text": "sumOfNonAbundantNumbers(28123) should return 4179871.", + "testString": "assert(sumOfNonAbundantNumbers(28123) === 4179871, 'sumOfNonAbundantNumbers(28123) should return 4179871.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.", + "A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.", + "", + "As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.", + "Find the sum of all positive integers <= n which cannot be written as the sum of two abundant numbers." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function sumOfNonAbundantNumbers(n) {", + " // Good luck!", + " return n;", + "}", + "", + "sumOfNonAbundantNumbers(28123);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3841000cf542c50fe97", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 24: Lexicographic permutations", + "tests": [ + { + "text": "lexicographicPermutations(699999) should return 1938246570.", + "testString": "assert(lexicographicPermutations(699999) == 1938246570, 'lexicographicPermutations(699999) should return 1938246570.');" + }, + { + "text": "lexicographicPermutations(899999) should return 2536987410.", + "testString": "assert(lexicographicPermutations(899999) == 2536987410, 'lexicographicPermutations(899999) should return 2536987410.');" + }, + { + "text": "lexicographicPermutations(900000) should return 2537014689.", + "testString": "assert(lexicographicPermutations(900000) == 2537014689, 'lexicographicPermutations(900000) should return 2537014689.');" + }, + { + "text": "lexicographicPermutations(999999) should return 2783915460.", + "testString": "assert(lexicographicPermutations(999999) == 2783915460, 'lexicographicPermutations(999999) should return 2783915460.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:", + "012   021   102   120   201   210", + "What is the n-th lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function lexicographicPermutations(n) {", + " // Good luck!", + " return n;", + "}", + "", + "lexicographicPermutations(999999);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3851000cf542c50fe98", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 25: 1000-digit Fibonacci number", + "tests": [ + { + "text": "digitFibonacci(5) should return 20.", + "testString": "assert(digitFibonacci(5) == 20, 'digitFibonacci(5) should return 20.');" + }, + { + "text": "digitFibonacci(10) should return 44.", + "testString": "assert(digitFibonacci(10) == 44, 'digitFibonacci(10) should return 44.');" + }, + { + "text": "digitFibonacci(15) should return 68.", + "testString": "assert(digitFibonacci(15) == 68, 'digitFibonacci(15) should return 68.');" + }, + { + "text": "digitFibonacci(20) should return 92.", + "testString": "assert(digitFibonacci(20) == 92, 'digitFibonacci(20) should return 92.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The Fibonacci sequence is defined by the recurrence relation:", + "Fn = Fn−1 + Fn−2, where F1 = 1 and F2 = 1.", + "Hence the first 12 terms will be:", + "F1 = 1", + "F2 = 1", + "F3 = 2", + "F4 = 3", + "F5 = 5", + "F6 = 8", + "F7 = 13", + "F8 = 21", + "F9 = 34", + "F10 = 55", + "F11 = 89", + "F12 = 144", + "The 12th term, F12, is the first term to contain three digits.", + "What is the index of the first term in the Fibonacci sequence to contain n digits?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function digitFibonacci(n) {", + " // Good luck!", + " return n;", + "}", + "", + "digitFibonacci(20);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3861000cf542c50fe99", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 26: Reciprocal cycles", + "tests": [ + { + "text": "reciprocalCycles(700) should return 659.", + "testString": "assert(reciprocalCycles(700) == 659, 'reciprocalCycles(700) should return 659.');" + }, + { + "text": "reciprocalCycles(800) should return 743.", + "testString": "assert(reciprocalCycles(800) == 743, 'reciprocalCycles(800) should return 743.');" + }, + { + "text": "reciprocalCycles(900) should return 887.", + "testString": "assert(reciprocalCycles(900) == 887, 'reciprocalCycles(900) should return 887.');" + }, + { + "text": "reciprocalCycles(1000) should return 983.", + "testString": "assert(reciprocalCycles(1000) == 983, 'reciprocalCycles(1000) should return 983.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:", + "", + "1/2= 0.5", + "1/3= 0.(3)", + "1/4= 0.25", + "1/5= 0.2", + "1/6= 0.1(6)", + "1/7= 0.(142857)", + "1/8= 0.125", + "1/9= 0.(1)", + "1/10= 0.1", + "", + "Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.", + "Find the value of d < n for which 1/d contains the longest recurring cycle in its decimal fraction part." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function reciprocalCycles(n) {", + " // Good luck!", + " return n;", + "}", + "", + "reciprocalCycles(1000);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3871000cf542c50fe9a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 27: Quadratic primes", + "tests": [ + { + "text": "quadraticPrimes(200) should return -4925.", + "testString": "assert(quadraticPrimes(200) == -4925, 'quadraticPrimes(200) should return -4925.');" + }, + { + "text": "quadraticPrimes(500) should return -18901.", + "testString": "assert(quadraticPrimes(500) == -18901, 'quadraticPrimes(500) should return -18901.');" + }, + { + "text": "quadraticPrimes(800) should return -43835.", + "testString": "assert(quadraticPrimes(800) == -43835, 'quadraticPrimes(800) should return -43835.');" + }, + { + "text": "quadraticPrimes(1000) should return -59231.", + "testString": "assert(quadraticPrimes(1000) == -59231, 'quadraticPrimes(1000) should return -59231.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Euler discovered the remarkable quadratic formula:", + "$n^2 + n + 41$", + "It turns out that the formula will produce 40 primes for the consecutive integer values $0 \\le n \\le 39$. However, when $n = 40, 40^2 + 40 + 41 = 40(40 + 1) + 41$ is divisible by 41, and certainly when $n = 41, 41^2 + 41 + 41$ is clearly divisible by 41.", + "The incredible formula $n^2 - 79n + 1601$ was discovered, which produces 80 primes for the consecutive values $0 \\le n \\le 79$. The product of the coefficients, −79 and 1601, is −126479.", + "Considering quadratics of the form:", + "", + "$n^2 + an + b$, where $|a| < range$ and $|b| \\le range$where $|n|$ is the modulus/absolute value of $n$e.g. $|11| = 11$ and $|-4| = 4$", + "", + "Find the product of the coefficients, $a$ and $b$, for the quadratic expression that produces the maximum number of primes for consecutive values of $n$, starting with $n = 0$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function quadraticPrimes(range) {", + " // Good luck!", + " return range;", + "}", + "", + "quadraticPrimes(1000);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3881000cf542c50fe9b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 28: Number spiral diagonals", + "tests": [ + { + "text": "spiralDiagonals(101) should return 692101.", + "testString": "assert(spiralDiagonals(101) == 692101, 'spiralDiagonals(101) should return 692101.');" + }, + { + "text": "spiralDiagonals(303) should return 18591725.", + "testString": "assert(spiralDiagonals(303) == 18591725, 'spiralDiagonals(303) should return 18591725.');" + }, + { + "text": "spiralDiagonals(505) should return 85986601.", + "testString": "assert(spiralDiagonals(505) == 85986601, 'spiralDiagonals(505) should return 85986601.');" + }, + { + "text": "spiralDiagonals(1001) should return 669171001.", + "testString": "assert(spiralDiagonals(1001) == 669171001, 'spiralDiagonals(1001) should return 669171001.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:", + "21 22 23 24 25", + "20  7  8  9 10", + "19  6  1  2 11", + "18  5  4  3 12", + "17 16 15 14 13", + "It can be verified that the sum of the numbers on the diagonals is 101.", + "What is the sum of the numbers on the diagonals in a n by n spiral formed in the same way?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function spiralDiagonals(n) {", + " // Good luck!", + " return n;", + "}", + "", + "spiralDiagonals(1001);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3891000cf542c50fe9c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 29: Distinct powers", + "tests": [ + { + "text": "distinctPowers(15) should return 177.", + "testString": "assert.strictEqual(distinctPowers(15), 177, 'distinctPowers(15) should return 177.');" + }, + { + "text": "distinctPowers(20) should return 324.", + "testString": "assert.strictEqual(distinctPowers(20), 324, 'distinctPowers(20) should return 324.');" + }, + { + "text": "distinctPowers(25) should return 519.", + "testString": "assert.strictEqual(distinctPowers(25), 519, 'distinctPowers(25) should return 519.');" + }, + { + "text": "distinctPowers(30) should return 755.", + "testString": "assert.strictEqual(distinctPowers(30), 755, 'distinctPowers(30) should return 755.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider all integer combinations of ab for 2 ≤ a ≤ 5 and 2 ≤ b ≤ 5:", + "22=4, 23=8, 24=16, 25=32", + "32=9, 33=27, 34=81, 35=243", + "42=16, 43=64, 44=256, 45=1024", + "52=25, 53=125, 54=625, 55=3125", + "If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms:", + "4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125", + "How many distinct terms are in the sequence generated by ab for 2 ≤ a ≤ n and 2 ≤ b ≤ n?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function distinctPowers(n) {", + " // Good luck!", + " return n;", + "}", + "", + "distinctPowers(30);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f38a1000cf542c50fe9d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 30: Digit n powers", + "tests": [ + { + "text": "digitnPowers(2) should return 0.", + "testString": "assert(digitnPowers(2) == 0, 'digitnPowers(2) should return 0.');" + }, + { + "text": "digitnPowers(3) should return 1301.", + "testString": "assert(digitnPowers(3) == 1301, 'digitnPowers(3) should return 1301.');" + }, + { + "text": "digitnPowers(4) should return 19316.", + "testString": "assert(digitnPowers(4) == 19316, 'digitnPowers(4) should return 19316.');" + }, + { + "text": "digitnPowers(5) should return 443839.", + "testString": "assert(digitnPowers(5) == 443839, 'digitnPowers(5) should return 443839.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Surprisingly there are only three numbers that can be written as the sum of fourth powers of their digits:", + "1634 = 14 + 64 + 34 + 44", + "8208 = 84 + 24 + 04 + 84", + "9474 = 94 + 44 + 74 + 44", + "As 1 = 14 is not a sum it is not included.", + "The sum of these numbers is 1634 + 8208 + 9474 = 19316.", + "Find the sum of all the numbers that can be written as the sum of n powers of their digits." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function digitnPowers(n) {", + " // Good luck!", + " return n;", + "}", + "", + "digitnPowers(5);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f38b1000cf542c50fe9e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 31: Coin sums", + "tests": [ + { + "text": "coinSums(50) should return 451.", + "testString": "assert(coinSums(50) == 451, 'coinSums(50) should return 451.');" + }, + { + "text": "coinSums(100) should return 4563.", + "testString": "assert(coinSums(100) == 4563, 'coinSums(100) should return 4563.');" + }, + { + "text": "coinSums(150) should return 21873.", + "testString": "assert(coinSums(150) == 21873, 'coinSums(150) should return 21873.');" + }, + { + "text": "coinSums(200) should return 73682.", + "testString": "assert(coinSums(200) == 73682, 'coinSums(200) should return 73682.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In England the currency is made up of pound, £, and pence, p, and there are eight coins in general circulation:", + "1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p).", + "It is possible to make £2 in the following way:", + "1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p", + "How many different ways can £(n) be made using any number of coins?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function coinSums(n) {", + " // Good luck!", + " return n;", + "}", + "", + "coinSums(200);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f38c1000cf542c50fe9f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 32: Pandigital products", + "tests": [ + { + "text": "euler32() should return 45228.", + "testString": "assert.strictEqual(euler32(), 45228, 'euler32() should return 45228.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.", + "", + "The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.", + "", + "Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.", + "", + "HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler32() {", + " // Good luck!", + " return true;", + "}", + "", + "euler32();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f38d1000cf542c50fea0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 33: Digit cancelling fractions", + "tests": [ + { + "text": "euler33() should return 100.", + "testString": "assert.strictEqual(euler33(), 100, 'euler33() should return 100.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The fraction 49/98 is a curious fraction, as an inexperienced mathematician in attempting to simplify it may incorrectly believe that 49/98 = 4/8, which is correct, is obtained by cancelling the 9s.", + "We shall consider fractions like, 30/50 = 3/5, to be trivial examples.", + "There are exactly four non-trivial examples of this type of fraction, less than one in value, and containing two digits in the numerator and denominator.", + "If the product of these four fractions is given in its lowest common terms, find the value of the denominator." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler33() {", + " // Good luck!", + " return true;", + "}", + "", + "euler33();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f38e1000cf542c50fea1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 34: Digit factorials", + "tests": [ + { + "text": "digitFactorial() should return { sum: 40730, numbers: [145, 40585] }.", + "testString": "assert.deepEqual(digitFactorial(), { sum: 40730, numbers: [145, 40585] }, 'digitFactorial() should return { sum: 40730, numbers: [145, 40585] }.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145.", + "Find the numbers and the sum of the numbers which are equal to the sum of the factorial of their digits.", + "Note: as 1! = 1 and 2! = 2 are not sums they are not included." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function digitFactorial() {", + " // Good luck!", + " var sum = 0;", + " var numbers = [];", + " return { sum, numbers };", + "}", + "", + "digitFactorial();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f38f1000cf542c50fea2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 35: Circular primes", + "tests": [ + { + "text": "circularPrimes(100) should return 13.", + "testString": "assert(circularPrimes(100) == 13, 'circularPrimes(100) should return 13.');" + }, + { + "text": "circularPrimes(100000) should return 43.", + "testString": "assert(circularPrimes(100000) == 43, 'circularPrimes(100000) should return 43.');" + }, + { + "text": "circularPrimes(250000) should return 45.", + "testString": "assert(circularPrimes(250000) == 45, 'circularPrimes(250000) should return 45.');" + }, + { + "text": "circularPrimes(500000) should return 49.", + "testString": "assert(circularPrimes(500000) == 49, 'circularPrimes(500000) should return 49.');" + }, + { + "text": "circularPrimes(750000) should return 49.", + "testString": "assert(circularPrimes(750000) == 49, 'circularPrimes(750000) should return 49.');" + }, + { + "text": "circularPrimes(1000000) should return 55.", + "testString": "assert(circularPrimes(1000000) == 55, 'circularPrimes(1000000) should return 55.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.", + "There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.", + "How many circular primes are there below n, whereas 100 <= n <= 1000000?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function circularPrimes(n) {", + " // Good luck!", + " return n;", + "}", + "", + "circularPrimes(1000000);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3901000cf542c50fea3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 36: Double-base palindromes", + "tests": [ + { + "text": "doubleBasePalindromes(1000) should return 1772.", + "testString": "assert(doubleBasePalindromes(1000) == 1772, 'doubleBasePalindromes(1000) should return 1772.');" + }, + { + "text": "doubleBasePalindromes(50000) should return 105795.", + "testString": "assert(doubleBasePalindromes(50000) == 105795, 'doubleBasePalindromes(50000) should return 105795.');" + }, + { + "text": "doubleBasePalindromes(500000) should return 286602.", + "testString": "assert(doubleBasePalindromes(500000) == 286602, 'doubleBasePalindromes(500000) should return 286602.');" + }, + { + "text": "doubleBasePalindromes(1000000) should return 872187.", + "testString": "assert(doubleBasePalindromes(1000000) == 872187, 'doubleBasePalindromes(1000000) should return 872187.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The decimal number, 585 = 10010010012 (binary), is palindromic in both bases.", + "Find the sum of all numbers, less than n, whereas 1000 <= n <= 1000000, which are palindromic in base 10 and base 2.", + "(Please note that the palindromic number, in either base, may not include leading zeros.)" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function doubleBasePalindromes(n) {", + " // Good luck!", + " return n;", + "}", + "", + "doubleBasePalindromes(1000000);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3911000cf542c50fea4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 37: Truncatable primes", + "tests": [ + { + "text": "truncatablePrimes(8) should return 1986.", + "testString": "assert(truncatablePrimes(8) == 1986, 'truncatablePrimes(8) should return 1986.');" + }, + { + "text": "truncatablePrimes(9) should return 5123.", + "testString": "assert(truncatablePrimes(9) == 5123, 'truncatablePrimes(9) should return 5123.');" + }, + { + "text": "truncatablePrimes(10) should return 8920.", + "testString": "assert(truncatablePrimes(10) == 8920, 'truncatablePrimes(10) should return 8920.');" + }, + { + "text": "truncatablePrimes(11) should return 748317.", + "testString": "assert(truncatablePrimes(11) == 748317, 'truncatablePrimes(11) should return 748317.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.", + "Find the sum of the only n (8 <= n <= 11) primes that are both truncatable from left to right and right to left.", + "NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function truncatablePrimes(n) {", + " // Good luck!", + " return n;", + "}", + "", + "truncatablePrimes(11);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3931000cf542c50fea5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 38: Pandigital multiples", + "tests": [ + { + "text": "euler38() should return 932718654.", + "testString": "assert.strictEqual(euler38(), 932718654, 'euler38() should return 932718654.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Take the number 192 and multiply it by each of 1, 2, and 3:", + "192 × 1 = 192", + "192 × 2 = 384", + "192 × 3 = 576", + "By concatenating each product we get the 1 to 9 pandigital, 192384576. We will call 192384576 the concatenated product of 192 and (1,2,3)", + "The same can be achieved by starting with 9 and multiplying by 1, 2, 3, 4, and 5, giving the pandigital, 918273645, which is the concatenated product of 9 and (1,2,3,4,5).", + "What is the largest 1 to 9 pandigital 9-digit number that can be formed as the concatenated product of an integer with (1,2, ... , n) where n > 1?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler38() {", + " // Good luck!", + " return true;", + "}", + "", + "euler38();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3931000cf542c50fea6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 39: Integer right triangles", + "tests": [ + { + "text": "intRightTriangles(500) should return 420.", + "testString": "assert(intRightTriangles(500) == 420, 'intRightTriangles(500) should return 420.');" + }, + { + "text": "intRightTriangles(800) should return 420.", + "testString": "assert(intRightTriangles(800) == 420, 'intRightTriangles(800) should return 420.');" + }, + { + "text": "intRightTriangles(900) should return 840.", + "testString": "assert(intRightTriangles(900) == 840, 'intRightTriangles(900) should return 840.');" + }, + { + "text": "intRightTriangles(1000) should return 840.", + "testString": "assert(intRightTriangles(1000) == 840, 'intRightTriangles(1000) should return 840.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "If p is the perimeter of a right angle triangle with integral length sides, {a,b,c}, there are exactly three solutions for p = 120.", + "{20,48,52}, {24,45,51}, {30,40,50}", + "For which value of p ≤ n, is the number of solutions maximised?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function intRightTriangles(n) {", + " // Good luck!", + " return n;", + "}", + "", + "intRightTriangles(1000);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3941000cf542c50fea7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 40: Champernowne's constant", + "tests": [ + { + "text": "euler40() should return 210.", + "testString": "assert.strictEqual(euler40(), 210, 'euler40() should return 210.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An irrational decimal fraction is created by concatenating the positive integers:", + "0.123456789101112131415161718192021...", + "It can be seen that the 12th digit of the fractional part is 1.", + "If dn represents the nth digit of the fractional part, find the value of the following expression.", + "d1 × d10 × d100 × d1000 × d10000 × d100000 × d1000000" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler40() {", + " // Good luck!", + " return true;", + "}", + "", + "euler40();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3951000cf542c50fea8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 41: Pandigital prime", + "tests": [ + { + "text": "pandigitalPrime(4) should return 4231.", + "testString": "assert(pandigitalPrime(4) == 4231, 'pandigitalPrime(4) should return 4231.');" + }, + { + "text": "pandigitalPrime(5) should return 0.", + "testString": "assert(pandigitalPrime(5) == 0, 'pandigitalPrime(5) should return 0.');" + }, + { + "text": "pandigitalPrime(6) should return 0.", + "testString": "assert(pandigitalPrime(6) == 0, 'pandigitalPrime(6) should return 0.');" + }, + { + "text": "pandigitalPrime(7) should return 7652413.", + "testString": "assert(pandigitalPrime(7) == 7652413, 'pandigitalPrime(7) should return 7652413.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is also prime.", + "What is the largest n-length digit pandigital prime that exists?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function pandigitalPrime(n) {", + " // Good luck!", + " return n;", + "}", + "", + "pandigitalPrime(7);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3961000cf542c50fea9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 42: Coded triangle numbers", + "tests": [ + { + "text": "codedTriangleNumbers(1400) should return 129.", + "testString": "assert(codedTriangleNumbers(1400) == 129, 'codedTriangleNumbers(1400) should return 129.');" + }, + { + "text": "codedTriangleNumbers(1500) should return 137.", + "testString": "assert(codedTriangleNumbers(1500) == 137, 'codedTriangleNumbers(1500) should return 137.');" + }, + { + "text": "codedTriangleNumbers(1600) should return 141.", + "testString": "assert(codedTriangleNumbers(1600) == 141, 'codedTriangleNumbers(1600) should return 141.');" + }, + { + "text": "codedTriangleNumbers(1786) should return 162.", + "testString": "assert(codedTriangleNumbers(1786) == 162, 'codedTriangleNumbers(1786) should return 162.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The nth term of the sequence of triangle numbers is given by, tn = ½n(n+1); so the first ten triangle numbers are:", + "1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...", + "By converting each letter in a word to a number corresponding to its alphabetical position and adding these values we form a word value. For example, the word value for SKY is 19 + 11 + 25 = 55 = t10. If the word value is a triangle number then we shall call the word a triangle word.", + "Using words array of n-length, how many are triangle words?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function codedTriangleNumbers(n) {", + " // Good luck!", + " return 1;", + "}", + "// only change code above this line", + "", + "const words = ['A','ABILITY','ABLE','ABOUT','ABOVE','ABSENCE','ABSOLUTELY','ACADEMIC','ACCEPT','ACCESS','ACCIDENT','ACCOMPANY','ACCORDING','ACCOUNT','ACHIEVE','ACHIEVEMENT','ACID','ACQUIRE','ACROSS','ACT','ACTION','ACTIVE','ACTIVITY','ACTUAL','ACTUALLY','ADD','ADDITION','ADDITIONAL','ADDRESS','ADMINISTRATION','ADMIT','ADOPT','ADULT','ADVANCE','ADVANTAGE','ADVICE','ADVISE','AFFAIR','AFFECT','AFFORD','AFRAID','AFTER','AFTERNOON','AFTERWARDS','AGAIN','AGAINST','AGE','AGENCY','AGENT','AGO','AGREE','AGREEMENT','AHEAD','AID','AIM','AIR','AIRCRAFT','ALL','ALLOW','ALMOST','ALONE','ALONG','ALREADY','ALRIGHT','ALSO','ALTERNATIVE','ALTHOUGH','ALWAYS','AMONG','AMONGST','AMOUNT','AN','ANALYSIS','ANCIENT','AND','ANIMAL','ANNOUNCE','ANNUAL','ANOTHER','ANSWER','ANY','ANYBODY','ANYONE','ANYTHING','ANYWAY','APART','APPARENT','APPARENTLY','APPEAL','APPEAR','APPEARANCE','APPLICATION','APPLY','APPOINT','APPOINTMENT','APPROACH','APPROPRIATE','APPROVE','AREA','ARGUE','ARGUMENT','ARISE','ARM','ARMY','AROUND','ARRANGE','ARRANGEMENT','ARRIVE','ART','ARTICLE','ARTIST','AS','ASK','ASPECT','ASSEMBLY','ASSESS','ASSESSMENT','ASSET','ASSOCIATE','ASSOCIATION','ASSUME','ASSUMPTION','AT','ATMOSPHERE','ATTACH','ATTACK','ATTEMPT','ATTEND','ATTENTION','ATTITUDE','ATTRACT','ATTRACTIVE','AUDIENCE','AUTHOR','AUTHORITY','AVAILABLE','AVERAGE','AVOID','AWARD','AWARE','AWAY','AYE','BABY','BACK','BACKGROUND','BAD','BAG','BALANCE','BALL','BAND','BANK','BAR','BASE','BASIC','BASIS','BATTLE','BE','BEAR','BEAT','BEAUTIFUL','BECAUSE','BECOME','BED','BEDROOM','BEFORE','BEGIN','BEGINNING','BEHAVIOUR','BEHIND','BELIEF','BELIEVE','BELONG','BELOW','BENEATH','BENEFIT','BESIDE','BEST','BETTER','BETWEEN','BEYOND','BIG','BILL','BIND','BIRD','BIRTH','BIT','BLACK','BLOCK','BLOOD','BLOODY','BLOW','BLUE','BOARD','BOAT','BODY','BONE','BOOK','BORDER','BOTH','BOTTLE','BOTTOM','BOX','BOY','BRAIN','BRANCH','BREAK','BREATH','BRIDGE','BRIEF','BRIGHT','BRING','BROAD','BROTHER','BUDGET','BUILD','BUILDING','BURN','BUS','BUSINESS','BUSY','BUT','BUY','BY','CABINET','CALL','CAMPAIGN','CAN','CANDIDATE','CAPABLE','CAPACITY','CAPITAL','CAR','CARD','CARE','CAREER','CAREFUL','CAREFULLY','CARRY','CASE','CASH','CAT','CATCH','CATEGORY','CAUSE','CELL','CENTRAL','CENTRE','CENTURY','CERTAIN','CERTAINLY','CHAIN','CHAIR','CHAIRMAN','CHALLENGE','CHANCE','CHANGE','CHANNEL','CHAPTER','CHARACTER','CHARACTERISTIC','CHARGE','CHEAP','CHECK','CHEMICAL','CHIEF','CHILD','CHOICE','CHOOSE','CHURCH','CIRCLE','CIRCUMSTANCE','CITIZEN','CITY','CIVIL','CLAIM','CLASS','CLEAN','CLEAR','CLEARLY','CLIENT','CLIMB','CLOSE','CLOSELY','CLOTHES','CLUB','COAL','CODE','COFFEE','COLD','COLLEAGUE','COLLECT','COLLECTION','COLLEGE','COLOUR','COMBINATION','COMBINE','COME','COMMENT','COMMERCIAL','COMMISSION','COMMIT','COMMITMENT','COMMITTEE','COMMON','COMMUNICATION','COMMUNITY','COMPANY','COMPARE','COMPARISON','COMPETITION','COMPLETE','COMPLETELY','COMPLEX','COMPONENT','COMPUTER','CONCENTRATE','CONCENTRATION','CONCEPT','CONCERN','CONCERNED','CONCLUDE','CONCLUSION','CONDITION','CONDUCT','CONFERENCE','CONFIDENCE','CONFIRM','CONFLICT','CONGRESS','CONNECT','CONNECTION','CONSEQUENCE','CONSERVATIVE','CONSIDER','CONSIDERABLE','CONSIDERATION','CONSIST','CONSTANT','CONSTRUCTION','CONSUMER','CONTACT','CONTAIN','CONTENT','CONTEXT','CONTINUE','CONTRACT','CONTRAST','CONTRIBUTE','CONTRIBUTION','CONTROL','CONVENTION','CONVERSATION','COPY','CORNER','CORPORATE','CORRECT','COS','COST','COULD','COUNCIL','COUNT','COUNTRY','COUNTY','COUPLE','COURSE','COURT','COVER','CREATE','CREATION','CREDIT','CRIME','CRIMINAL','CRISIS','CRITERION','CRITICAL','CRITICISM','CROSS','CROWD','CRY','CULTURAL','CULTURE','CUP','CURRENT','CURRENTLY','CURRICULUM','CUSTOMER','CUT','DAMAGE','DANGER','DANGEROUS','DARK','DATA','DATE','DAUGHTER','DAY','DEAD','DEAL','DEATH','DEBATE','DEBT','DECADE','DECIDE','DECISION','DECLARE','DEEP','DEFENCE','DEFENDANT','DEFINE','DEFINITION','DEGREE','DELIVER','DEMAND','DEMOCRATIC','DEMONSTRATE','DENY','DEPARTMENT','DEPEND','DEPUTY','DERIVE','DESCRIBE','DESCRIPTION','DESIGN','DESIRE','DESK','DESPITE','DESTROY','DETAIL','DETAILED','DETERMINE','DEVELOP','DEVELOPMENT','DEVICE','DIE','DIFFERENCE','DIFFERENT','DIFFICULT','DIFFICULTY','DINNER','DIRECT','DIRECTION','DIRECTLY','DIRECTOR','DISAPPEAR','DISCIPLINE','DISCOVER','DISCUSS','DISCUSSION','DISEASE','DISPLAY','DISTANCE','DISTINCTION','DISTRIBUTION','DISTRICT','DIVIDE','DIVISION','DO','DOCTOR','DOCUMENT','DOG','DOMESTIC','DOOR','DOUBLE','DOUBT','DOWN','DRAW','DRAWING','DREAM','DRESS','DRINK','DRIVE','DRIVER','DROP','DRUG','DRY','DUE','DURING','DUTY','EACH','EAR','EARLY','EARN','EARTH','EASILY','EAST','EASY','EAT','ECONOMIC','ECONOMY','EDGE','EDITOR','EDUCATION','EDUCATIONAL','EFFECT','EFFECTIVE','EFFECTIVELY','EFFORT','EGG','EITHER','ELDERLY','ELECTION','ELEMENT','ELSE','ELSEWHERE','EMERGE','EMPHASIS','EMPLOY','EMPLOYEE','EMPLOYER','EMPLOYMENT','EMPTY','ENABLE','ENCOURAGE','END','ENEMY','ENERGY','ENGINE','ENGINEERING','ENJOY','ENOUGH','ENSURE','ENTER','ENTERPRISE','ENTIRE','ENTIRELY','ENTITLE','ENTRY','ENVIRONMENT','ENVIRONMENTAL','EQUAL','EQUALLY','EQUIPMENT','ERROR','ESCAPE','ESPECIALLY','ESSENTIAL','ESTABLISH','ESTABLISHMENT','ESTATE','ESTIMATE','EVEN','EVENING','EVENT','EVENTUALLY','EVER','EVERY','EVERYBODY','EVERYONE','EVERYTHING','EVIDENCE','EXACTLY','EXAMINATION','EXAMINE','EXAMPLE','EXCELLENT','EXCEPT','EXCHANGE','EXECUTIVE','EXERCISE','EXHIBITION','EXIST','EXISTENCE','EXISTING','EXPECT','EXPECTATION','EXPENDITURE','EXPENSE','EXPENSIVE','EXPERIENCE','EXPERIMENT','EXPERT','EXPLAIN','EXPLANATION','EXPLORE','EXPRESS','EXPRESSION','EXTEND','EXTENT','EXTERNAL','EXTRA','EXTREMELY','EYE','FACE','FACILITY','FACT','FACTOR','FACTORY','FAIL','FAILURE','FAIR','FAIRLY','FAITH','FALL','FAMILIAR','FAMILY','FAMOUS','FAR','FARM','FARMER','FASHION','FAST','FATHER','FAVOUR','FEAR','FEATURE','FEE','FEEL','FEELING','FEMALE','FEW','FIELD','FIGHT','FIGURE','FILE','FILL','FILM','FINAL','FINALLY','FINANCE','FINANCIAL','FIND','FINDING','FINE','FINGER','FINISH','FIRE','FIRM','FIRST','FISH','FIT','FIX','FLAT','FLIGHT','FLOOR','FLOW','FLOWER','FLY','FOCUS','FOLLOW','FOLLOWING','FOOD','FOOT','FOOTBALL','FOR','FORCE','FOREIGN','FOREST','FORGET','FORM','FORMAL','FORMER','FORWARD','FOUNDATION','FREE','FREEDOM','FREQUENTLY','FRESH','FRIEND','FROM','FRONT','FRUIT','FUEL','FULL','FULLY','FUNCTION','FUND','FUNNY','FURTHER','FUTURE','GAIN','GAME','GARDEN','GAS','GATE','GATHER','GENERAL','GENERALLY','GENERATE','GENERATION','GENTLEMAN','GET','GIRL','GIVE','GLASS','GO','GOAL','GOD','GOLD','GOOD','GOVERNMENT','GRANT','GREAT','GREEN','GREY','GROUND','GROUP','GROW','GROWING','GROWTH','GUEST','GUIDE','GUN','HAIR','HALF','HALL','HAND','HANDLE','HANG','HAPPEN','HAPPY','HARD','HARDLY','HATE','HAVE','HE','HEAD','HEALTH','HEAR','HEART','HEAT','HEAVY','HELL','HELP','HENCE','HER','HERE','HERSELF','HIDE','HIGH','HIGHLY','HILL','HIM','HIMSELF','HIS','HISTORICAL','HISTORY','HIT','HOLD','HOLE','HOLIDAY','HOME','HOPE','HORSE','HOSPITAL','HOT','HOTEL','HOUR','HOUSE','HOUSEHOLD','HOUSING','HOW','HOWEVER','HUGE','HUMAN','HURT','HUSBAND','I','IDEA','IDENTIFY','IF','IGNORE','ILLUSTRATE','IMAGE','IMAGINE','IMMEDIATE','IMMEDIATELY','IMPACT','IMPLICATION','IMPLY','IMPORTANCE','IMPORTANT','IMPOSE','IMPOSSIBLE','IMPRESSION','IMPROVE','IMPROVEMENT','IN','INCIDENT','INCLUDE','INCLUDING','INCOME','INCREASE','INCREASED','INCREASINGLY','INDEED','INDEPENDENT','INDEX','INDICATE','INDIVIDUAL','INDUSTRIAL','INDUSTRY','INFLUENCE','INFORM','INFORMATION','INITIAL','INITIATIVE','INJURY','INSIDE','INSIST','INSTANCE','INSTEAD','INSTITUTE','INSTITUTION','INSTRUCTION','INSTRUMENT','INSURANCE','INTEND','INTENTION','INTEREST','INTERESTED','INTERESTING','INTERNAL','INTERNATIONAL','INTERPRETATION','INTERVIEW','INTO','INTRODUCE','INTRODUCTION','INVESTIGATE','INVESTIGATION','INVESTMENT','INVITE','INVOLVE','IRON','IS','ISLAND','ISSUE','IT','ITEM','ITS','ITSELF','JOB','JOIN','JOINT','JOURNEY','JUDGE','JUMP','JUST','JUSTICE','KEEP','KEY','KID','KILL','KIND','KING','KITCHEN','KNEE','KNOW','KNOWLEDGE','LABOUR','LACK','LADY','LAND','LANGUAGE','LARGE','LARGELY','LAST','LATE','LATER','LATTER','LAUGH','LAUNCH','LAW','LAWYER','LAY','LEAD','LEADER','LEADERSHIP','LEADING','LEAF','LEAGUE','LEAN','LEARN','LEAST','LEAVE','LEFT','LEG','LEGAL','LEGISLATION','LENGTH','LESS','LET','LETTER','LEVEL','LIABILITY','LIBERAL','LIBRARY','LIE','LIFE','LIFT','LIGHT','LIKE','LIKELY','LIMIT','LIMITED','LINE','LINK','LIP','LIST','LISTEN','LITERATURE','LITTLE','LIVE','LIVING','LOAN','LOCAL','LOCATION','LONG','LOOK','LORD','LOSE','LOSS','LOT','LOVE','LOVELY','LOW','LUNCH','MACHINE','MAGAZINE','MAIN','MAINLY','MAINTAIN','MAJOR','MAJORITY','MAKE','MALE','MAN','MANAGE','MANAGEMENT','MANAGER','MANNER','MANY','MAP','MARK','MARKET','MARRIAGE','MARRIED','MARRY','MASS','MASTER','MATCH','MATERIAL','MATTER','MAY','MAYBE','ME','MEAL','MEAN','MEANING','MEANS','MEANWHILE','MEASURE','MECHANISM','MEDIA','MEDICAL','MEET','MEETING','MEMBER','MEMBERSHIP','MEMORY','MENTAL','MENTION','MERELY','MESSAGE','METAL','METHOD','MIDDLE','MIGHT','MILE','MILITARY','MILK','MIND','MINE','MINISTER','MINISTRY','MINUTE','MISS','MISTAKE','MODEL','MODERN','MODULE','MOMENT','MONEY','MONTH','MORE','MORNING','MOST','MOTHER','MOTION','MOTOR','MOUNTAIN','MOUTH','MOVE','MOVEMENT','MUCH','MURDER','MUSEUM','MUSIC','MUST','MY','MYSELF','NAME','NARROW','NATION','NATIONAL','NATURAL','NATURE','NEAR','NEARLY','NECESSARILY','NECESSARY','NECK','NEED','NEGOTIATION','NEIGHBOUR','NEITHER','NETWORK','NEVER','NEVERTHELESS','NEW','NEWS','NEWSPAPER','NEXT','NICE','NIGHT','NO','NOBODY','NOD','NOISE','NONE','NOR','NORMAL','NORMALLY','NORTH','NORTHERN','NOSE','NOT','NOTE','NOTHING','NOTICE','NOTION','NOW','NUCLEAR','NUMBER','NURSE','OBJECT','OBJECTIVE','OBSERVATION','OBSERVE','OBTAIN','OBVIOUS','OBVIOUSLY','OCCASION','OCCUR','ODD','OF','OFF','OFFENCE','OFFER','OFFICE','OFFICER','OFFICIAL','OFTEN','OIL','OKAY','OLD','ON','ONCE','ONE','ONLY','ONTO','OPEN','OPERATE','OPERATION','OPINION','OPPORTUNITY','OPPOSITION','OPTION','OR','ORDER','ORDINARY','ORGANISATION','ORGANISE','ORGANIZATION','ORIGIN','ORIGINAL','OTHER','OTHERWISE','OUGHT','OUR','OURSELVES','OUT','OUTCOME','OUTPUT','OUTSIDE','OVER','OVERALL','OWN','OWNER','PACKAGE','PAGE','PAIN','PAINT','PAINTING','PAIR','PANEL','PAPER','PARENT','PARK','PARLIAMENT','PART','PARTICULAR','PARTICULARLY','PARTLY','PARTNER','PARTY','PASS','PASSAGE','PAST','PATH','PATIENT','PATTERN','PAY','PAYMENT','PEACE','PENSION','PEOPLE','PER','PERCENT','PERFECT','PERFORM','PERFORMANCE','PERHAPS','PERIOD','PERMANENT','PERSON','PERSONAL','PERSUADE','PHASE','PHONE','PHOTOGRAPH','PHYSICAL','PICK','PICTURE','PIECE','PLACE','PLAN','PLANNING','PLANT','PLASTIC','PLATE','PLAY','PLAYER','PLEASE','PLEASURE','PLENTY','PLUS','POCKET','POINT','POLICE','POLICY','POLITICAL','POLITICS','POOL','POOR','POPULAR','POPULATION','POSITION','POSITIVE','POSSIBILITY','POSSIBLE','POSSIBLY','POST','POTENTIAL','POUND','POWER','POWERFUL','PRACTICAL','PRACTICE','PREFER','PREPARE','PRESENCE','PRESENT','PRESIDENT','PRESS','PRESSURE','PRETTY','PREVENT','PREVIOUS','PREVIOUSLY','PRICE','PRIMARY','PRIME','PRINCIPLE','PRIORITY','PRISON','PRISONER','PRIVATE','PROBABLY','PROBLEM','PROCEDURE','PROCESS','PRODUCE','PRODUCT','PRODUCTION','PROFESSIONAL','PROFIT','PROGRAM','PROGRAMME','PROGRESS','PROJECT','PROMISE','PROMOTE','PROPER','PROPERLY','PROPERTY','PROPORTION','PROPOSE','PROPOSAL','PROSPECT','PROTECT','PROTECTION','PROVE','PROVIDE','PROVIDED','PROVISION','PUB','PUBLIC','PUBLICATION','PUBLISH','PULL','PUPIL','PURPOSE','PUSH','PUT','QUALITY','QUARTER','QUESTION','QUICK','QUICKLY','QUIET','QUITE','RACE','RADIO','RAILWAY','RAIN','RAISE','RANGE','RAPIDLY','RARE','RATE','RATHER','REACH','REACTION','READ','READER','READING','READY','REAL','REALISE','REALITY','REALIZE','REALLY','REASON','REASONABLE','RECALL','RECEIVE','RECENT','RECENTLY','RECOGNISE','RECOGNITION','RECOGNIZE','RECOMMEND','RECORD','RECOVER','RED','REDUCE','REDUCTION','REFER','REFERENCE','REFLECT','REFORM','REFUSE','REGARD','REGION','REGIONAL','REGULAR','REGULATION','REJECT','RELATE','RELATION','RELATIONSHIP','RELATIVE','RELATIVELY','RELEASE','RELEVANT','RELIEF','RELIGION','RELIGIOUS','RELY','REMAIN','REMEMBER','REMIND','REMOVE','REPEAT','REPLACE','REPLY','REPORT','REPRESENT','REPRESENTATION','REPRESENTATIVE','REQUEST','REQUIRE','REQUIREMENT','RESEARCH','RESOURCE','RESPECT','RESPOND','RESPONSE','RESPONSIBILITY','RESPONSIBLE','REST','RESTAURANT','RESULT','RETAIN','RETURN','REVEAL','REVENUE','REVIEW','REVOLUTION','RICH','RIDE','RIGHT','RING','RISE','RISK','RIVER','ROAD','ROCK','ROLE','ROLL','ROOF','ROOM','ROUND','ROUTE','ROW','ROYAL','RULE','RUN','RURAL','SAFE','SAFETY','SALE','SAME','SAMPLE','SATISFY','SAVE','SAY','SCALE','SCENE','SCHEME','SCHOOL','SCIENCE','SCIENTIFIC','SCIENTIST','SCORE','SCREEN','SEA','SEARCH','SEASON','SEAT','SECOND','SECONDARY','SECRETARY','SECTION','SECTOR','SECURE','SECURITY','SEE','SEEK','SEEM','SELECT','SELECTION','SELL','SEND','SENIOR','SENSE','SENTENCE','SEPARATE','SEQUENCE','SERIES','SERIOUS','SERIOUSLY','SERVANT','SERVE','SERVICE','SESSION','SET','SETTLE','SETTLEMENT','SEVERAL','SEVERE','SEX','SEXUAL','SHAKE','SHALL','SHAPE','SHARE','SHE','SHEET','SHIP','SHOE','SHOOT','SHOP','SHORT','SHOT','SHOULD','SHOULDER','SHOUT','SHOW','SHUT','SIDE','SIGHT','SIGN','SIGNAL','SIGNIFICANCE','SIGNIFICANT','SILENCE','SIMILAR','SIMPLE','SIMPLY','SINCE','SING','SINGLE','SIR','SISTER','SIT','SITE','SITUATION','SIZE','SKILL','SKIN','SKY','SLEEP','SLIGHTLY','SLIP','SLOW','SLOWLY','SMALL','SMILE','SO','SOCIAL','SOCIETY','SOFT','SOFTWARE','SOIL','SOLDIER','SOLICITOR','SOLUTION','SOME','SOMEBODY','SOMEONE','SOMETHING','SOMETIMES','SOMEWHAT','SOMEWHERE','SON','SONG','SOON','SORRY','SORT','SOUND','SOURCE','SOUTH','SOUTHERN','SPACE','SPEAK','SPEAKER','SPECIAL','SPECIES','SPECIFIC','SPEECH','SPEED','SPEND','SPIRIT','SPORT','SPOT','SPREAD','SPRING','STAFF','STAGE','STAND','STANDARD','STAR','START','STATE','STATEMENT','STATION','STATUS','STAY','STEAL','STEP','STICK','STILL','STOCK','STONE','STOP','STORE','STORY','STRAIGHT','STRANGE','STRATEGY','STREET','STRENGTH','STRIKE','STRONG','STRONGLY','STRUCTURE','STUDENT','STUDIO','STUDY','STUFF','STYLE','SUBJECT','SUBSTANTIAL','SUCCEED','SUCCESS','SUCCESSFUL','SUCH','SUDDENLY','SUFFER','SUFFICIENT','SUGGEST','SUGGESTION','SUITABLE','SUM','SUMMER','SUN','SUPPLY','SUPPORT','SUPPOSE','SURE','SURELY','SURFACE','SURPRISE','SURROUND','SURVEY','SURVIVE','SWITCH','SYSTEM','TABLE','TAKE','TALK','TALL','TAPE','TARGET','TASK','TAX','TEA','TEACH','TEACHER','TEACHING','TEAM','TEAR','TECHNICAL','TECHNIQUE','TECHNOLOGY','TELEPHONE','TELEVISION','TELL','TEMPERATURE','TEND','TERM','TERMS','TERRIBLE','TEST','TEXT','THAN','THANK','THANKS','THAT','THE','THEATRE','THEIR','THEM','THEME','THEMSELVES','THEN','THEORY','THERE','THEREFORE','THESE','THEY','THIN','THING','THINK','THIS','THOSE','THOUGH','THOUGHT','THREAT','THREATEN','THROUGH','THROUGHOUT','THROW','THUS','TICKET','TIME','TINY','TITLE','TO','TODAY','TOGETHER','TOMORROW','TONE','TONIGHT','TOO','TOOL','TOOTH','TOP','TOTAL','TOTALLY','TOUCH','TOUR','TOWARDS','TOWN','TRACK','TRADE','TRADITION','TRADITIONAL','TRAFFIC','TRAIN','TRAINING','TRANSFER','TRANSPORT','TRAVEL','TREAT','TREATMENT','TREATY','TREE','TREND','TRIAL','TRIP','TROOP','TROUBLE','TRUE','TRUST','TRUTH','TRY','TURN','TWICE','TYPE','TYPICAL','UNABLE','UNDER','UNDERSTAND','UNDERSTANDING','UNDERTAKE','UNEMPLOYMENT','UNFORTUNATELY','UNION','UNIT','UNITED','UNIVERSITY','UNLESS','UNLIKELY','UNTIL','UP','UPON','UPPER','URBAN','US','USE','USED','USEFUL','USER','USUAL','USUALLY','VALUE','VARIATION','VARIETY','VARIOUS','VARY','VAST','VEHICLE','VERSION','VERY','VIA','VICTIM','VICTORY','VIDEO','VIEW','VILLAGE','VIOLENCE','VISION','VISIT','VISITOR','VITAL','VOICE','VOLUME','VOTE','WAGE','WAIT','WALK','WALL','WANT','WAR','WARM','WARN','WASH','WATCH','WATER','WAVE','WAY','WE','WEAK','WEAPON','WEAR','WEATHER','WEEK','WEEKEND','WEIGHT','WELCOME','WELFARE','WELL','WEST','WESTERN','WHAT','WHATEVER','WHEN','WHERE','WHEREAS','WHETHER','WHICH','WHILE','WHILST','WHITE','WHO','WHOLE','WHOM','WHOSE','WHY','WIDE','WIDELY','WIFE','WILD','WILL','WIN','WIND','WINDOW','WINE','WING','WINNER','WINTER','WISH','WITH','WITHDRAW','WITHIN','WITHOUT','WOMAN','WONDER','WONDERFUL','WOOD','WORD','WORK','WORKER','WORKING','WORKS','WORLD','WORRY','WORTH','WOULD','WRITE','WRITER','WRITING','WRONG','YARD','YEAH','YEAR','YES','YESTERDAY','YET','YOU','YOUNG','YOUR','YOURSELF','YOUTH'];", + "", + "codedTriangleNumbers(1786);" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3971000cf542c50feaa", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 43: Sub-string divisibility", + "tests": [ + { + "text": "substringDivisibility() should return [ 1430952867, 1460357289, 1406357289, 4130952867, 4160357289, 4106357289 ].", + "testString": "assert.deepEqual(substringDivisibility(), [ 1430952867, 1460357289, 1406357289, 4130952867, 4160357289, 4106357289 ], 'substringDivisibility() should return [ 1430952867, 1460357289, 1406357289, 4130952867, 4160357289, 4106357289 ].');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The number, 1406357289, is a 0 to 9 pandigital number because it is made up of each of the digits 0 to 9 in some order, but it also has a rather interesting sub-string divisibility property.", + "Let d1 be the 1st digit, d2 be the 2nd digit, and so on. In this way, we note the following:", + "d2d3d4=406 is divisible by 2", + "d3d4d5=063 is divisible by 3", + "d4d5d6=635 is divisible by 5", + "d5d6d7=357 is divisible by 7", + "d6d7d8=572 is divisible by 11", + "d7d8d9=728 is divisible by 13", + "d8d9d10=289 is divisible by 17", + "Find the numbers of all 0 to 9 pandigital numbers with this property." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function substringDivisibility() {", + " // Good luck!", + " return [];", + "}", + "", + "substringDivisibility();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3981000cf542c50feab", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 44: Pentagon numbers", + "tests": [ + { + "text": "euler44() should return 5482660.", + "testString": "assert.strictEqual(euler44(), 5482660, 'euler44() should return 5482660.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Pentagonal numbers are generated by the formula, Pn=n(3n−1)/2. The first ten pentagonal numbers are:", + "1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...", + "It can be seen that P4 + P7 = 22 + 70 = 92 = P8. However, their difference, 70 − 22 = 48, is not pentagonal.", + "Find the pair of pentagonal numbers, Pj and Pk, for which their sum and difference are pentagonal and D = |Pk − Pj| is minimised; what is the value of D?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler44() {", + " // Good luck!", + " return true;", + "}", + "", + "euler44();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3991000cf542c50feac", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 45: Triangular, pentagonal, and hexagonal", + "tests": [ + { + "text": "euler45() should return 1533776805.", + "testString": "assert.strictEqual(euler45(), 1533776805, 'euler45() should return 1533776805.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Triangle, pentagonal, and hexagonal numbers are generated by the following formulae:", + "Triangle", + " ", + "Tn=n(n+1)/2", + " ", + "1, 3, 6, 10, 15, ...", + "Pentagonal", + " ", + "Pn=n(3n−1)/2", + " ", + "1, 5, 12, 22, 35, ...", + "Hexagonal", + " ", + "Hn=n(2n−1)", + " ", + "1, 6, 15, 28, 45, ...", + "It can be verified that T285 = P165 = H143 = 40755.", + "Find the next triangle number that is also pentagonal and hexagonal." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler45() {", + " // Good luck!", + " return true;", + "}", + "", + "euler45();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f39a1000cf542c50fead", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 46: Goldbach's other conjecture", + "tests": [ + { + "text": "euler46() should return 5777.", + "testString": "assert.strictEqual(euler46(), 5777, 'euler46() should return 5777.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It was proposed by Christian Goldbach that every odd composite number can be written as the sum of a prime and twice a square.", + "9 = 7 + 2×12", + "15 = 7 + 2×22", + "21 = 3 + 2×32", + "25 = 7 + 2×32", + "27 = 19 + 2×22", + "33 = 31 + 2×12", + "It turns out that the conjecture was false.", + "What is the smallest odd composite that cannot be written as the sum of a prime and twice a square?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler46() {", + " // Good luck!", + " return true;", + "}", + "", + "euler46();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f39c1000cf542c50feae", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 47: Distinct primes factors", + "tests": [ + { + "text": "euler47() should return 134043.", + "testString": "assert.strictEqual(euler47(), 134043, 'euler47() should return 134043.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The first two consecutive numbers to have two distinct prime factors are:", + "14 = 2 × 715 = 3 × 5", + "The first three consecutive numbers to have three distinct prime factors are:", + "644 = 2² × 7 × 23645 = 3 × 5 × 43646 = 2 × 17 × 19.", + "Find the first four consecutive integers to have four distinct prime factors each. What is the first of these numbers?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler47() {", + " // Good luck!", + " return true;", + "}", + "", + "euler47();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f39c1000cf542c50feaf", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 48: Self powers", + "tests": [ + { + "text": "euler48() should return 9110846700.", + "testString": "assert.strictEqual(euler48(), 9110846700, 'euler48() should return 9110846700.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The series, 11 + 22 + 33 + ... + 1010 = 10405071317.", + "Find the last ten digits of the series, 11 + 22 + 33 + ... + 10001000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler48() {", + " // Good luck!", + " return true;", + "}", + "", + "euler48();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f39d1000cf542c50feb0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 49: Prime permutations", + "tests": [ + { + "text": "euler49() should return 296962999629.", + "testString": "assert.strictEqual(euler49(), 296962999629, 'euler49() should return 296962999629.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330, is unusual in two ways: (i) each of the three terms are prime, and, (ii) each of the 4-digit numbers are permutations of one another.", + "There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property, but there is one other 4-digit increasing sequence.", + "What 12-digit number do you form by concatenating the three terms in this sequence?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler49() {", + " // Good luck!", + " return true;", + "}", + "", + "euler49();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f39e1000cf542c50feb1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 50: Consecutive prime sum", + "tests": [ + { + "text": "euler50() should return 997651.", + "testString": "assert.strictEqual(euler50(), 997651, 'euler50() should return 997651.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The prime 41, can be written as the sum of six consecutive primes:", + "41 = 2 + 3 + 5 + 7 + 11 + 13", + "This is the longest sum of consecutive primes that adds to a prime below one-hundred.", + "The longest sum of consecutive primes below one-thousand that adds to a prime, contains 21 terms, and is equal to 953.", + "Which prime, below one-million, can be written as the sum of the most consecutive primes?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler50() {", + " // Good luck!", + " return true;", + "}", + "", + "euler50();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f39f1000cf542c50feb2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 51: Prime digit replacements", + "tests": [ + { + "text": "euler51() should return 121313.", + "testString": "assert.strictEqual(euler51(), 121313, 'euler51() should return 121313.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "By replacing the 1st digit of the 2-digit number *3, it turns out that six of the nine possible values: 13, 23, 43, 53, 73, and 83, are all prime.", + "By replacing the 3rd and 4th digits of 56**3 with the same digit, this 5-digit number is the first example having seven primes among the ten generated numbers, yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 56993. Consequently 56003, being the first member of this family, is the smallest prime with this property.", + "Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an eight prime value family." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler51() {", + " // Good luck!", + " return true;", + "}", + "", + "euler51();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3a01000cf542c50feb3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 52: Permuted multiples", + "tests": [ + { + "text": "euler52() should return 142857.", + "testString": "assert.strictEqual(euler52(), 142857, 'euler52() should return 142857.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It can be seen that the number, 125874, and its double, 251748, contain exactly the same digits, but in a different order.", + "Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler52() {", + " // Good luck!", + " return true;", + "}", + "", + "euler52();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3a11000cf542c50feb4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 53: Combinatoric selections", + "tests": [ + { + "text": "euler53() should return 4075.", + "testString": "assert.strictEqual(euler53(), 4075, 'euler53() should return 4075.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "There are exactly ten ways of selecting three from five, 12345:", + "123, 124, 125, 134, 135, 145, 234, 235, 245, and 345", + "In combinatorics, we use the notation, 5C3 = 10.", + "In general,", + "", + "nCr = ", + "n!r!(n−r)!", + ",where r ≤ n, n! = n×(n−1)×...×3×2×1, and 0! = 1.", + "", + "It is not until n = 23, that a value exceeds one-million: 23C10 = 1144066.", + "How many, not necessarily distinct, values of  nCr, for 1 ≤ n ≤ 100, are greater than one-million?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler53() {", + " // Good luck!", + " return true;", + "}", + "", + "euler53();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3a21000cf542c50feb5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 54: Poker hands", + "tests": [ + { + "text": "euler54() should return 376.", + "testString": "assert.strictEqual(euler54(), 376, 'euler54() should return 376.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In the card game poker, a hand consists of five cards and are ranked, from lowest to highest, in the following way:", + "High Card: Highest value card.", + "One Pair: Two cards of the same value.", + "Two Pairs: Two different pairs.", + "Three of a Kind: Three cards of the same value.", + "Straight: All cards are consecutive values.", + "Flush: All cards of the same suit.", + "Full House: Three of a kind and a pair.", + "Four of a Kind: Four cards of the same value.", + "Straight Flush: All cards are consecutive values of same suit.", + "Royal Flush: Ten, Jack, Queen, King, Ace, in same suit.", + "The cards are valued in the order:2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.", + "If two players have the same ranked hands then the rank made up of the highest value wins; for example, a pair of eights beats a pair of fives (see example 1 below). But if two ranks tie, for example, both players have a pair of queens, then highest cards in each hand are compared (see example 4 below); if the highest cards tie then the next highest cards are compared, and so on.", + "Consider the following five hands dealt to two players:", + "", + "Hand Player 1 Player 2 Winner", + "1 5H 5C 6S 7S KDPair of Fives 2C 3S 8S 8D TDPair of Eights Player 2", + "2 5D 8C 9S JS ACHighest card Ace 2C 5C 7D 8S QHHighest card Queen Player 1", + "3 2D 9C AS AH ACThree Aces 3D 6D 7D TD QDFlush with Diamonds Player 2", + "4 4D 6S 9H QH QCPair of QueensHighest card Nine 3D 6D 7H QD QSPair of QueensHighest card Seven Player 1", + "5 2H 2D 4C 4D 4SFull HouseWith Three Fours 3C 3D 3S 9S 9DFull Housewith Three Threes Player 1", + "", + "The file, poker.txt, contains one-thousand random hands dealt to two players. Each line of the file contains ten cards (separated by a single space): the first five are Player 1's cards and the last five are Player 2's cards. You can assume that all hands are valid (no invalid characters or repeated cards), each player's hand is in no specific order, and in each hand there is a clear winner.", + "How many hands does Player 1 win?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler54() {", + " // Good luck!", + " return true;", + "}", + "", + "euler54();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3a31000cf542c50feb6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 55: Lychrel numbers", + "tests": [ + { + "text": "euler55() should return 249.", + "testString": "assert.strictEqual(euler55(), 249, 'euler55() should return 249.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "If we take 47, reverse and add, 47 + 74 = 121, which is palindromic.", + "Not all numbers produce palindromes so quickly. For example,", + "349 + 943 = 1292,", + "1292 + 2921 = 4213", + "4213 + 3124 = 7337", + "That is, 349 took three iterations to arrive at a palindrome.", + "Although no one has proved it yet, it is thought that some numbers, like 196, never produce a palindrome. A number that never forms a palindrome through the reverse and add process is called a Lychrel number. Due to the theoretical nature of these numbers, and for the purpose of this problem, we shall assume that a number is Lychrel until proven otherwise. In addition you are given that for every number below ten-thousand, it will either (i) become a palindrome in less than fifty iterations, or, (ii) no one, with all the computing power that exists, has managed so far to map it to a palindrome. In fact, 10677 is the first number to be shown to require over fifty iterations before producing a palindrome: 4668731596684224866951378664 (53 iterations, 28-digits).", + "Surprisingly, there are palindromic numbers that are themselves Lychrel numbers; the first example is 4994.", + "How many Lychrel numbers are there below ten-thousand?", + "NOTE: Wording was modified slightly on 24 April 2007 to emphasise the theoretical nature of Lychrel numbers." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler55() {", + " // Good luck!", + " return true;", + "}", + "", + "euler55();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3a41000cf542c50feb7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 56: Powerful digit sum", + "tests": [ + { + "text": "euler56() should return 972.", + "testString": "assert.strictEqual(euler56(), 972, 'euler56() should return 972.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A googol (10100) is a massive number: one followed by one-hundred zeros; 100100 is almost unimaginably large: one followed by two-hundred zeros. Despite their size, the sum of the digits in each number is only 1.", + "Considering natural numbers of the form, ab, where a, b < 100, what is the maximum digital sum?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler56() {", + " // Good luck!", + " return true;", + "}", + "", + "euler56();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3a51000cf542c50feb8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 57: Square root convergents", + "tests": [ + { + "text": "euler57() should return 153.", + "testString": "assert.strictEqual(euler57(), 153, 'euler57() should return 153.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It is possible to show that the square root of two can be expressed as an infinite continued fraction.", + "√ 2 = 1 + 1/(2 + 1/(2 + 1/(2 + ... ))) = 1.414213...", + "By expanding this for the first four iterations, we get:", + "1 + 1/2 = 3/2 = 1.5", + "1 + 1/(2 + 1/2) = 7/5 = 1.4", + "1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666...", + "1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379...", + "The next three expansions are 99/70, 239/169, and 577/408, but the eighth expansion, 1393/985, is the first example where the number of digits in the numerator exceeds the number of digits in the denominator.", + "In the first one-thousand expansions, how many fractions contain a numerator with more digits than denominator?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler57() {", + " // Good luck!", + " return true;", + "}", + "", + "euler57();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3a61000cf542c50feb9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 58: Spiral primes", + "tests": [ + { + "text": "euler58() should return 26241.", + "testString": "assert.strictEqual(euler58(), 26241, 'euler58() should return 26241.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length 7 is formed.", + "37 36 35 34 33 32 31", + "38 17 16 15 14 13 30", + "39 18  5  4  3 12 29", + "40 19  6  1  2 11 28", + "41 20  7  8  9 10 27", + "42 21 22 23 24 25 2643 44 45 46 47 48 49", + "It is interesting to note that the odd squares lie along the bottom right diagonal, but what is more interesting is that 8 out of the 13 numbers lying along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%.", + "If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, what is the side length of the square spiral for which the ratio of primes along both diagonals first falls below 10%?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler58() {", + " // Good luck!", + " return true;", + "}", + "", + "euler58();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3a81000cf542c50feba", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 59: XOR decryption", + "tests": [ + { + "text": "euler59() should return 107359.", + "testString": "assert.strictEqual(euler59(), 107359, 'euler59() should return 107359.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Each character on a computer is assigned a unique code and the preferred standard is ASCII (American Standard Code for Information Interchange). For example, uppercase A = 65, asterisk (*) = 42, and lowercase k = 107.", + "A modern encryption method is to take a text file, convert the bytes to ASCII, then XOR each byte with a given value, taken from a secret key. The advantage with the XOR function is that using the same encryption key on the cipher text, restores the plain text; for example, 65 XOR 42 = 107, then 107 XOR 42 = 65.", + "For unbreakable encryption, the key is the same length as the plain text message, and the key is made up of random bytes. The user would keep the encrypted message and the encryption key in different locations, and without both \"halves\", it is impossible to decrypt the message.", + "Unfortunately, this method is impractical for most users, so the modified method is to use a password as a key. If the password is shorter than the message, which is likely, the key is repeated cyclically throughout the message. The balance for this method is using a sufficiently long password key for security, but short enough to be memorable.", + "Your task has been made easy, as the encryption key consists of three lower case characters. Using cipher.txt (right click and 'Save Link/Target As...'), a file containing the encrypted ASCII codes, and the knowledge that the plain text must contain common English words, decrypt the message and find the sum of the ASCII values in the original text." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler59() {", + " // Good luck!", + " return true;", + "}", + "", + "euler59();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3a81000cf542c50febb", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 60: Prime pair sets", + "tests": [ + { + "text": "euler60() should return 26033.", + "testString": "assert.strictEqual(euler60(), 26033, 'euler60() should return 26033.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.", + "Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler60() {", + " // Good luck!", + " return true;", + "}", + "", + "euler60();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3a91000cf542c50febc", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 61: Cyclical figurate numbers", + "tests": [ + { + "text": "euler61() should return 28684.", + "testString": "assert.strictEqual(euler61(), 28684, 'euler61() should return 28684.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Triangle, square, pentagonal, hexagonal, heptagonal, and octagonal numbers are all figurate (polygonal) numbers and are generated by the following formulae:", + "Triangle", + " ", + "P3,n=n(n+1)/2", + " ", + "1, 3, 6, 10, 15, ...", + "Square", + " ", + "P4,n=n2", + " ", + "1, 4, 9, 16, 25, ...", + "Pentagonal", + " ", + "P5,n=n(3n−1)/2", + " ", + "1, 5, 12, 22, 35, ...", + "Hexagonal", + " ", + "P6,n=n(2n−1)", + " ", + "1, 6, 15, 28, 45, ...", + "Heptagonal", + " ", + "P7,n=n(5n−3)/2", + " ", + "1, 7, 18, 34, 55, ...", + "Octagonal", + " ", + "P8,n=n(3n−2)", + " ", + "1, 8, 21, 40, 65, ...", + "The ordered set of three 4-digit numbers: 8128, 2882, 8281, has three interesting properties.", + "The set is cyclic, in that the last two digits of each number is the first two digits of the next number (including the last number with the first).", + "Each polygonal type: triangle (P3,127=8128), square (P4,91=8281), and pentagonal (P5,44=2882), is represented by a different number in the set.", + "This is the only set of 4-digit numbers with this property.", + "Find the sum of the only ordered set of six cyclic 4-digit numbers for which each polygonal type: triangle, square, pentagonal, hexagonal, heptagonal, and octagonal, is represented by a different number in the set." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler61() {", + " // Good luck!", + " return true;", + "}", + "", + "euler61();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3aa1000cf542c50febd", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 62: Cubic permutations", + "tests": [ + { + "text": "euler62() should return 127035954683.", + "testString": "assert.strictEqual(euler62(), 127035954683, 'euler62() should return 127035954683.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The cube, 41063625 (3453), can be permuted to produce two other cubes: 56623104 (3843) and 66430125 (4053). In fact, 41063625 is the smallest cube which has exactly three permutations of its digits which are also cube.", + "Find the smallest cube for which exactly five permutations of its digits are cube." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler62() {", + " // Good luck!", + " return true;", + "}", + "", + "euler62();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ab1000cf542c50febe", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 63: Powerful digit counts", + "tests": [ + { + "text": "euler63() should return 49.", + "testString": "assert.strictEqual(euler63(), 49, 'euler63() should return 49.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The 5-digit number, 16807=75, is also a fifth power. Similarly, the 9-digit number, 134217728=89, is a ninth power.", + "How many n-digit positive integers exist which are also an nth power?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler63() {", + " // Good luck!", + " return true;", + "}", + "", + "euler63();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ac1000cf542c50febf", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 64: Odd period square roots", + "tests": [ + { + "text": "euler64() should return 1322.", + "testString": "assert.strictEqual(euler64(), 1322, 'euler64() should return 1322.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "All square roots are periodic when written as continued fractions and can be written in the form:", + "", + "√N = a0 +", + "1", + " ", + "a1 +", + "1", + " ", + " ", + "a2 +", + "1", + " ", + " ", + " ", + "a3 + ...", + "", + "For example, let us consider √23:", + "", + "√23 = 4 + √23 — 4 = 4 + ", + "1", + " = 4 + ", + "1", + " ", + "1√23—4", + " ", + "1 + ", + "√23 – 37", + "", + "If we continue we would get the following expansion:", + "", + "√23 = 4 +", + "1", + " ", + "1 +", + "1", + " ", + " ", + "3 +", + "1", + " ", + " ", + " ", + "1 +", + "1", + " ", + " ", + " ", + " ", + "8 + ...", + "", + "The process can be summarised as follows:", + "", + "a0 = 4,", + " ", + "1√23—4", + " = ", + "√23+47", + " = 1 + ", + "√23—37", + "a1 = 1,", + " ", + "7√23—3", + " = ", + "7(√23+3)14", + " = 3 + ", + "√23—32", + "a2 = 3,", + " ", + "2√23—3", + " = ", + "2(√23+3)14", + " = 1 + ", + "√23—47", + "a3 = 1,", + " ", + "7√23—4", + " = ", + "7(√23+4)7", + " = 8 + ", + "√23—4", + "a4 = 8,", + " ", + "1√23—4", + " = ", + "√23+47", + " = 1 + ", + "√23—37", + "a5 = 1,", + " ", + "7√23—3", + " = ", + "7(√23+3)14", + " = 3 + ", + "√23—32", + "a6 = 3,", + " ", + "2√23—3", + " = ", + "2(√23+3)14", + " = 1 + ", + "√23—47", + "a7 = 1,", + " ", + "7√23—4", + " = ", + "7(√23+4)7", + " = 8 + ", + "√23—4", + "", + "It can be seen that the sequence is repeating. For conciseness, we use the notation √23 = [4;(1,3,1,8)], to indicate that the block (1,3,1,8) repeats indefinitely.", + "", + "The first ten continued fraction representations of (irrational) square roots are:", + "√2=[1;(2)], period=1", + "√3=[1;(1,2)], period=2", + "√5=[2;(4)], period=1", + "√6=[2;(2,4)], period=2", + "√7=[2;(1,1,1,4)], period=4", + "√8=[2;(1,4)], period=2", + "√10=[3;(6)], period=1", + "√11=[3;(3,6)], period=2", + "√12= [3;(2,6)], period=2", + "√13=[3;(1,1,1,1,6)], period=5", + "Exactly four continued fractions, for N ≤ 13, have an odd period.", + "How many continued fractions for N ≤ 10000 have an odd period?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler64() {", + " // Good luck!", + " return true;", + "}", + "", + "euler64();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ad1000cf542c50fec0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 65: Convergents of e", + "tests": [ + { + "text": "euler65() should return 272.", + "testString": "assert.strictEqual(euler65(), 272, 'euler65() should return 272.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The square root of 2 can be written as an infinite continued fraction.", + "", + "√2 = 1 +", + "1", + " ", + "2 +", + "1", + " ", + " ", + "2 +", + "1", + " ", + " ", + " ", + "2 +", + "1", + " ", + " ", + " ", + " ", + "2 + ...", + "", + "The infinite continued fraction can be written, √2 = [1;(2)], (2) indicates that 2 repeats ad infinitum. In a similar way, √23 = [4;(1,3,1,8)].", + "It turns out that the sequence of partial values of continued fractions for square roots provide the best rational approximations. Let us consider the convergents for √2.", + "", + "", + "1 +", + "1", + "= 3/2", + " ", + "2", + " ", + "1 +", + "1", + "= 7/5", + " ", + "2 +", + "1", + " ", + " ", + "2", + " ", + "1 +", + "1", + "= 17/12", + " ", + "2 +", + "1", + " ", + " ", + " ", + "2 +", + "1", + " ", + " ", + " ", + " ", + "2", + " ", + "1 +", + "1", + "= 41/29", + " ", + "2 +", + "1", + " ", + " ", + "2 +", + "1", + " ", + " ", + " ", + " ", + "2 +", + "1", + " ", + " ", + " ", + " ", + " ", + "2", + " ", + "", + "Hence the sequence of the first ten convergents for √2 are:", + "1, 3/2, 7/5, 17/12, 41/29, 99/70, 239/169, 577/408, 1393/985, 3363/2378, ...", + "What is most surprising is that the important mathematical constant,e = [2; 1,2,1, 1,4,1, 1,6,1 , ... , 1,2k,1, ...].", + "The first ten terms in the sequence of convergents for e are:", + "2, 3, 8/3, 11/4, 19/7, 87/32, 106/39, 193/71, 1264/465, 1457/536, ...", + "The sum of digits in the numerator of the 10th convergent is 1+4+5+7=17.", + "Find the sum of digits in the numerator of the 100th convergent of the continued fraction for e." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler65() {", + " // Good luck!", + " return true;", + "}", + "", + "euler65();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ae1000cf542c50fec1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 66: Diophantine equation", + "tests": [ + { + "text": "euler66() should return 661.", + "testString": "assert.strictEqual(euler66(), 661, 'euler66() should return 661.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider quadratic Diophantine equations of the form:", + "x2 – Dy2 = 1", + "For example, when D=13, the minimal solution in x is 6492 – 13×1802 = 1.", + "It can be assumed that there are no solutions in positive integers when D is square.", + "By finding minimal solutions in x for D = {2, 3, 5, 6, 7}, we obtain the following:", + "32 – 2×22 = 1", + "22 – 3×12 = 192 – 5×42 = 1", + "52 – 6×22 = 1", + "82 – 7×32 = 1", + "Hence, by considering minimal solutions in x for D ≤ 7, the largest x is obtained when D=5.", + "Find the value of D ≤ 1000 in minimal solutions of x for which the largest value of x is obtained." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler66() {", + " // Good luck!", + " return true;", + "}", + "", + "euler66();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3b01000cf542c50fec2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 67: Maximum path sum II", + "tests": [ + { + "text": "euler67() should return 7273.", + "testString": "assert.strictEqual(euler67(), 7273, 'euler67() should return 7273.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.", + "37 4", + "2 4 6", + "8 5 9 3", + "That is, 3 + 7 + 4 + 9 = 23.", + "Find the maximum total from top to bottom in triangle.txt (right click and 'Save Link/Target As...'), a 15K text file containing a triangle with one-hundred rows.", + "NOTE: This is a much more difficult version of Problem 18. It is not possible to try every route to solve this problem, as there are 299 altogether! If you could check one trillion (1012) routes every second it would take over twenty billion years to check them all. There is an efficient algorithm to solve it. ;o)" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler67() {", + " // Good luck!", + " return true;", + "}", + "", + "euler67();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3b01000cf542c50fec3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 68: Magic 5-gon ring", + "tests": [ + { + "text": "euler68() should return 6531031914842725.", + "testString": "assert.strictEqual(euler68(), 6531031914842725, 'euler68() should return 6531031914842725.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the following \"magic\" 3-gon ring, filled with the numbers 1 to 6, and each line adding to nine.", + "", + "", + "Working clockwise, and starting from the group of three with the numerically lowest external node (4,3,2 in this example), each solution can be described uniquely. For example, the above solution can be described by the set: 4,3,2; 6,2,1; 5,1,3.", + "It is possible to complete the ring with four different totals: 9, 10, 11, and 12. There are eight solutions in total.", + "", + "TotalSolution Set", + "94,2,3; 5,3,1; 6,1,2", + "94,3,2; 6,2,1; 5,1,3", + "102,3,5; 4,5,1; 6,1,3", + "102,5,3; 6,3,1; 4,1,5", + "111,4,6; 3,6,2; 5,2,4", + "111,6,4; 5,4,2; 3,2,6", + "121,5,6; 2,6,4; 3,4,5", + "121,6,5; 3,5,4; 2,4,6", + "", + "By concatenating each group it is possible to form 9-digit strings; the maximum string for a 3-gon ring is 432621513.", + "Using the numbers 1 to 10, and depending on arrangements, it is possible to form 16- and 17-digit strings. What is the maximum 16-digit string for a \"magic\" 5-gon ring?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler68() {", + " // Good luck!", + " return true;", + "}", + "", + "euler68();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3b11000cf542c50fec4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 69: Totient maximum", + "tests": [ + { + "text": "euler69() should return 510510.", + "testString": "assert.strictEqual(euler69(), 510510, 'euler69() should return 510510.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Euler's Totient function, φ(n) [sometimes called the phi function], is used to determine the number of numbers less than n which are relatively prime to n. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, φ(9)=6.", + "", + "n", + "Relatively Prime", + "φ(n)", + "n/φ(n)", + "2", + "1", + "1", + "2", + "3", + "1,2", + "2", + "1.5", + "4", + "1,3", + "2", + "2", + "5", + "1,2,3,4", + "4", + "1.25", + "6", + "1,5", + "2", + "3", + "7", + "1,2,3,4,5,6", + "6", + "1.1666...", + "8", + "1,3,5,7", + "4", + "2", + "9", + "1,2,4,5,7,8", + "6", + "1.5", + "10", + "1,3,7,9", + "4", + "2.5", + "", + "It can be seen that n=6 produces a maximum n/φ(n) for n ≤ 10.", + "Find the value of n ≤ 1,000,000 for which n/φ(n) is a maximum." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler69() {", + " // Good luck!", + " return true;", + "}", + "", + "euler69();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3b21000cf542c50fec5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 70: Totient permutation", + "tests": [ + { + "text": "euler70() should return 8319823.", + "testString": "assert.strictEqual(euler70(), 8319823, 'euler70() should return 8319823.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Euler's Totient function, φ(n) [sometimes called the phi function], is used to determine the number of positive numbers less than or equal to n which are relatively prime to n. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, φ(9)=6.The number 1 is considered to be relatively prime to every positive number, so φ(1)=1. ", + "Interestingly, φ(87109)=79180, and it can be seen that 87109 is a permutation of 79180.", + "Find the value of n, 1 < n < 107, for which φ(n) is a permutation of n and the ratio n/φ(n) produces a minimum." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler70() {", + " // Good luck!", + " return true;", + "}", + "", + "euler70();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3b31000cf542c50fec6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 71: Ordered fractions", + "tests": [ + { + "text": "euler71() should return 428570.", + "testString": "assert.strictEqual(euler71(), 428570, 'euler71() should return 428570.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the fraction, n/d, where n and d are positive integers. If neuler72() should return 303963552391.", + "testString": "assert.strictEqual(euler72(), 303963552391, 'euler72() should return 303963552391.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the fraction, n/d, where n and d are positive integers. If neuler73() should return 7295372.", + "testString": "assert.strictEqual(euler73(), 7295372, 'euler73() should return 7295372.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the fraction, n/d, where n and d are positive integers. If neuler74() should return 402.", + "testString": "assert.strictEqual(euler74(), 402, 'euler74() should return 402.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The number 145 is well known for the property that the sum of the factorial of its digits is equal to 145:", + "1! + 4! + 5! = 1 + 24 + 120 = 145", + "Perhaps less well known is 169, in that it produces the longest chain of numbers that link back to 169; it turns out that there are only three such loops that exist:", + "169 → 363601 → 1454 → 169", + "871 → 45361 → 871", + "872 → 45362 → 872", + "It is not difficult to prove that EVERY starting number will eventually get stuck in a loop. For example,", + "69 → 363600 → 1454 → 169 → 363601 (→ 1454)", + "78 → 45360 → 871 → 45361 (→ 871)", + "540 → 145 (→ 145)", + "Starting with 69 produces a chain of five non-repeating terms, but the longest non-repeating chain with a starting number below one million is sixty terms.", + "How many chains, with a starting number below one million, contain exactly sixty non-repeating terms?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler74() {", + " // Good luck!", + " return true;", + "}", + "", + "euler74();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3b71000cf542c50feca", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 75: Singular integer right triangles", + "tests": [ + { + "text": "euler75() should return 161667.", + "testString": "assert.strictEqual(euler75(), 161667, 'euler75() should return 161667.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It turns out that 12 cm is the smallest length of wire that can be bent to form an integer sided right angle triangle in exactly one way, but there are many more examples.", + "12 cm: (3,4,5)24 cm: (6,8,10)30 cm: (5,12,13)36 cm: (9,12,15)40 cm: (8,15,17)48 cm: (12,16,20)", + "In contrast, some lengths of wire, like 20 cm, cannot be bent to form an integer sided right angle triangle, and other lengths allow more than one solution to be found; for example, using 120 cm it is possible to form exactly three different integer sided right angle triangles.", + "120 cm: (30,40,50), (20,48,52), (24,45,51)", + "Given that L is the length of the wire, for how many values of L ≤ 1,500,000 can exactly one integer sided right angle triangle be formed?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler75() {", + " // Good luck!", + " return true;", + "}", + "", + "euler75();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3b81000cf542c50fecb", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 76: Counting summations", + "tests": [ + { + "text": "euler76() should return 190569291.", + "testString": "assert.strictEqual(euler76(), 190569291, 'euler76() should return 190569291.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It is possible to write five as a sum in exactly six different ways:", + "4 + 1", + "3 + 2", + "3 + 1 + 1", + "2 + 2 + 1", + "2 + 1 + 1 + 1", + "1 + 1 + 1 + 1 + 1", + "How many different ways can one hundred be written as a sum of at least two positive integers?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler76() {", + " // Good luck!", + " return true;", + "}", + "", + "euler76();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3b91000cf542c50fecc", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 77: Prime summations", + "tests": [ + { + "text": "euler77() should return 71.", + "testString": "assert.strictEqual(euler77(), 71, 'euler77() should return 71.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It is possible to write ten as the sum of primes in exactly five different ways:", + "7 + 3", + "5 + 5", + "5 + 3 + 2", + "3 + 3 + 2 + 2", + "2 + 2 + 2 + 2 + 2", + "What is the first value which can be written as the sum of primes in over five thousand different ways?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler77() {", + " // Good luck!", + " return true;", + "}", + "", + "euler77();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ba1000cf542c50fecd", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 78: Coin partitions", + "tests": [ + { + "text": "euler78() should return 55374.", + "testString": "assert.strictEqual(euler78(), 55374, 'euler78() should return 55374.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let p(n) represent the number of different ways in which n coins can be separated into piles. For example, five coins can be separated into piles in exactly seven different ways, so p(5)=7.", + "", + "OOOOO", + "OOOO   O", + "OOO   OO", + "OOO   O   O", + "OO   OO   O", + "OO   O   O   O", + "O   O   O   O   O", + "", + "Find the least value of n for which p(n) is divisible by one million." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler78() {", + " // Good luck!", + " return true;", + "}", + "", + "euler78();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3bb1000cf542c50fece", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 79: Passcode derivation", + "tests": [ + { + "text": "euler79() should return 73162890.", + "testString": "assert.strictEqual(euler79(), 73162890, 'euler79() should return 73162890.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A common security method used for online banking is to ask the user for three random characters from a passcode. For example, if the passcode was 531278, they may ask for the 2nd, 3rd, and 5th characters; the expected reply would be: 317.", + "The text file, keylog.txt, contains fifty successful login attempts.", + "Given that the three characters are always asked for in order, analyse the file so as to determine the shortest possible secret passcode of unknown length." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler79() {", + " // Good luck!", + " return true;", + "}", + "", + "euler79();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3bc1000cf542c50fecf", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 80: Square root digital expansion", + "tests": [ + { + "text": "euler80() should return 40886.", + "testString": "assert.strictEqual(euler80(), 40886, 'euler80() should return 40886.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It is well known that if the square root of a natural number is not an integer, then it is irrational. The decimal expansion of such square roots is infinite without any repeating pattern at all.", + "The square root of two is 1.41421356237309504880..., and the digital sum of the first one hundred decimal digits is 475.", + "For the first one hundred natural numbers, find the total of the digital sums of the first one hundred decimal digits for all the irrational square roots." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler80() {", + " // Good luck!", + " return true;", + "}", + "", + "euler80();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3bd1000cf542c50fed0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 81: Path sum: two ways", + "tests": [ + { + "text": "euler81() should return 427337.", + "testString": "assert.strictEqual(euler81(), 427337, 'euler81() should return 427337.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by only moving to the right and down, is indicated in bold red and is equal to 2427.", + "", + "$$", + "\\begin{pmatrix}", + "\\color{red}{131} & 673 & 234 & 103 & 18\\\\", + "\\color{red}{201} & \\color{red}{96} & \\color{red}{342} & 965 & 150\\\\", + "630 & 803 & \\color{red}{746} & \\color{red}{422} & 111\\\\", + "537 & 699 & 497 & \\color{red}{121} & 956\\\\", + "805 & 732 & 524 & \\color{red}{37} & \\color{red}{331}", + "\\end{pmatrix}", + "$$", + "", + "Find the minimal path sum, in matrix.txt (right click and \"Save Link/Target As...\"), a 31K text file containing a 80 by 80 matrix, from the top left to the bottom right by only moving right and down." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler81() {", + " // Good luck!", + " return true;", + "}", + "", + "euler81();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3be1000cf542c50fed1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 82: Path sum: three ways", + "tests": [ + { + "text": "euler82() should return 260324.", + "testString": "assert.strictEqual(euler82(), 260324, 'euler82() should return 260324.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "NOTE: This problem is a more challenging version of Problem 81.", + "The minimal path sum in the 5 by 5 matrix below, by starting in any cell in the left column and finishing in any cell in the right column, and only moving up, down, and right, is indicated in red and bold; the sum is equal to 994.", + "", + "$$", + "\\begin{pmatrix}", + "131 & 673 & \\color{red}{234} & \\color{red}{103} & \\color{red}{18}\\\\", + "\\color{red}{201} & \\color{red}{96} & \\color{red}{342} & 965 & 150\\\\", + "630 & 803 & 746 & 422 & 111\\\\", + "537 & 699 & 497 & 121 & 956\\\\", + "805 & 732 & 524 & 37 & 331", + "\\end{pmatrix}", + "$$", + "", + "Find the minimal path sum, in matrix.txt (right click and \"Save Link/Target As...\"), a 31K text file containing a 80 by 80 matrix, from the left column to the right column." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler82() {", + " // Good luck!", + " return true;", + "}", + "", + "euler82();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3bf1000cf542c50fed2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 83: Path sum: four ways", + "tests": [ + { + "text": "euler83() should return 425185.", + "testString": "assert.strictEqual(euler83(), 425185, 'euler83() should return 425185.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "NOTE: This problem is a significantly more challenging version of Problem 81.", + "In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by moving left, right, up, and down, is indicated in bold red and is equal to 2297.", + "", + "$$", + "\\begin{pmatrix}", + "\\color{red}{131} & 673 & \\color{red}{234} & \\color{red}{103} & \\color{red}{18}\\\\", + "\\color{red}{201} & \\color{red}{96} & \\color{red}{342} & 965 & \\color{red}{150}\\\\", + "630 & 803 & 746 & \\color{red}{422} & \\color{red}{111}\\\\", + "537 & 699 & 497 & \\color{red}{121} & 956\\\\", + "805 & 732 & 524 & \\color{red}{37} & \\color{red}{331}", + "\\end{pmatrix}", + "$$", + "", + "Find the minimal path sum, in matrix.txt (right click and ", + "\"Save Link/Target As...\"), a 31K text file containing a 80 by 80 matrix, from the top left to the bottom right by moving left, right, up, and down." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler83() {", + " // Good luck!", + " return true;", + "}", + "", + "euler83();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3c11000cf542c50fed3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 84: Monopoly odds", + "tests": [ + { + "text": "euler84() should return 101524.", + "testString": "assert.strictEqual(euler84(), 101524, 'euler84() should return 101524.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In the game, Monopoly, the standard board is set up in the following way:", + "", + "GO", + "A1", + "CC1", + "A2", + "T1", + "R1", + "B1", + "CH1", + "B2", + "B3", + "JAIL", + "H2", + " ", + "C1", + "T2", + " ", + "U1", + "H1", + " ", + "C2", + "CH3", + " ", + "C3", + "R4", + " ", + "R2", + "G3", + " ", + "D1", + "CC3", + " ", + "CC2", + "G2", + " ", + "D2", + "G1", + " ", + "D3", + "G2J", + "F3", + "U2", + "F2", + "F1", + "R3", + "E3", + "E2", + "CH2", + "E1", + "FP", + "", + "A player starts on the GO square and adds the scores on two 6-sided dice to determine the number of squares they advance in a clockwise direction. Without any further rules we would expect to visit each square with equal probability: 2.5%. However, landing on G2J (Go To Jail), CC (community chest), and CH (chance) changes this distribution.", + "In addition to G2J, and one card from each of CC and CH, that orders the player to go directly to jail, if a player rolls three consecutive doubles, they do not advance the result of their 3rd roll. Instead they proceed directly to jail.", + "At the beginning of the game, the CC and CH cards are shuffled. When a player lands on CC or CH they take a card from the top of the respective pile and, after following the instructions, it is returned to the bottom of the pile. There are sixteen cards in each pile, but for the purpose of this problem we are only concerned with cards that order a movement; any instruction not concerned with movement will be ignored and the player will remain on the CC/CH square.", + "Community Chest (2/16 cards):", + "Advance to GO", + "Go to JAIL", + "", + "Chance (10/16 cards):", + "Advance to GO", + "Go to JAIL", + "Go to C1", + "Go to E3", + "Go to H2", + "Go to R1", + "Go to next R (railway company)", + "Go to next R", + "Go to next U (utility company)", + "Go back 3 squares.", + "", + "The heart of this problem concerns the likelihood of visiting a particular square. That is, the probability of finishing at that square after a roll. For this reason it should be clear that, with the exception of G2J for which the probability of finishing on it is zero, the CH squares will have the lowest probabilities, as 5/8 request a movement to another square, and it is the final square that the player finishes at on each roll that we are interested in. We shall make no distinction between \"Just Visiting\" and being sent to JAIL, and we shall also ignore the rule about requiring a double to \"get out of jail\", assuming that they pay to get out on their next turn.", + "By starting at GO and numbering the squares sequentially from 00 to 39 we can concatenate these two-digit numbers to produce strings that correspond with sets of squares.", + "Statistically it can be shown that the three most popular squares, in order, are JAIL (6.24%) = Square 10, E3 (3.18%) = Square 24, and GO (3.09%) = Square 00. So these three most popular squares can be listed with the six-digit modal string: 102400.", + "If, instead of using two 6-sided dice, two 4-sided dice are used, find the six-digit modal string." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler84() {", + " // Good luck!", + " return true;", + "}", + "", + "euler84();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3c11000cf542c50fed4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 85: Counting rectangles", + "tests": [ + { + "text": "euler85() should return 2772.", + "testString": "assert.strictEqual(euler85(), 2772, 'euler85() should return 2772.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "By counting carefully it can be seen that a rectangular grid measuring 3 by 2 contains eighteen rectangles:", + "", + "", + "Although there exists no rectangular grid that contains exactly two million rectangles, find the area of the grid with the nearest solution." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler85() {", + " // Good luck!", + " return true;", + "}", + "", + "euler85();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3c31000cf542c50fed5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 86: Cuboid route", + "tests": [ + { + "text": "euler86() should return 1818.", + "testString": "assert.strictEqual(euler86(), 1818, 'euler86() should return 1818.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A spider, S, sits in one corner of a cuboid room, measuring 6 by 5 by 3, and a fly, F, sits in the opposite corner. By travelling on the surfaces of the room the shortest \"straight line\" distance from S to F is 10 and the path is shown on the diagram.", + "", + "", + "However, there are up to three \"shortest\" path candidates for any given cuboid and the shortest route doesn't always have integer length.", + "It can be shown that there are exactly 2060 distinct cuboids, ignoring rotations, with integer dimensions, up to a maximum size of M by M by M, for which the shortest route has integer length when M = 100. This is the least value of M for which the number of solutions first exceeds two thousand; the number of solutions when M = 99 is 1975.", + "Find the least value of M such that the number of solutions first exceeds one million." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler86() {", + " // Good luck!", + " return true;", + "}", + "", + "euler86();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3c51000cf542c50fed8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 87: Prime power triples", + "tests": [ + { + "text": "euler87() should return 1097343.", + "testString": "assert.strictEqual(euler87(), 1097343, 'euler87() should return 1097343.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The smallest number expressible as the sum of a prime square, prime cube, and prime fourth power is 28. In fact, there are exactly four numbers below fifty that can be expressed in such a way:", + "28 = 22 + 23 + 24", + "33 = 32 + 23 + 24", + "49 = 52 + 23 + 24", + "47 = 22 + 33 + 24", + "How many numbers below fifty million can be expressed as the sum of a prime square, prime cube, and prime fourth power?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler87() {", + " // Good luck!", + " return true;", + "}", + "", + "euler87();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3c51000cf542c50fed6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 88: Product-sum numbers", + "tests": [ + { + "text": "euler88() should return 7587457.", + "testString": "assert.strictEqual(euler88(), 7587457, 'euler88() should return 7587457.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A natural number, N, that can be written as the sum and product of a given set of at least two natural numbers, {a1, a2, ... , ak} is called a product-sum number: N = a1 + a2 + ... + ak = a1 × a2 × ... × ak.", + "For example, 6 = 1 + 2 + 3 = 1 × 2 × 3.", + "For a given set of size, k, we shall call the smallest N with this property a minimal product-sum number. The minimal product-sum numbers for sets of size, k = 2, 3, 4, 5, and 6 are as follows.", + "k=2: 4 = 2 × 2 = 2 + 2k=3: 6 = 1 × 2 × 3 = 1 + 2 + 3k=4: 8 = 1 × 1 × 2 × 4 = 1 + 1 + 2 + 4k=5: 8 = 1 × 1 × 2 × 2 × 2 = 1 + 1 + 2 + 2 + 2k=6: 12 = 1 × 1 × 1 × 1 × 2 × 6 = 1 + 1 + 1 + 1 + 2 + 6", + "Hence for 2≤k≤6, the sum of all the minimal product-sum numbers is 4+6+8+12 = 30; note that 8 is only counted once in the sum.", + "In fact, as the complete set of minimal product-sum numbers for 2≤k≤12 is {4, 6, 8, 12, 15, 16}, the sum is 61.", + "What is the sum of all the minimal product-sum numbers for 2≤k≤12000?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler88() {", + " // Good luck!", + " return true;", + "}", + "", + "euler88();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3c51000cf542c50fed7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 89: Roman numerals", + "tests": [ + { + "text": "euler89() should return 743.", + "testString": "assert.strictEqual(euler89(), 743, 'euler89() should return 743.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a number written in Roman numerals to be considered valid there are basic rules which must be followed. Even though the rules allow some numbers to be expressed in more than one way there is always a \"best\" way of writing a particular number.", + "For example, it would appear that there are at least six ways of writing the number sixteen:", + "IIIIIIIIIIIIIIII", + "VIIIIIIIIIII", + "VVIIIIII", + "XIIIIII", + "VVVI", + "XVI", + "However, according to the rules only XIIIIII and XVI are valid, and the last example is considered to be the most efficient, as it uses the least number of numerals.", + "The 11K text file, roman.txt (right click and 'Save Link/Target As...'), contains one thousand numbers written in valid, but not necessarily minimal, Roman numerals; see About... Roman Numerals for the definitive rules for this problem.", + "Find the number of characters saved by writing each of these in their minimal form.", + "Note: You can assume that all the Roman numerals in the file contain no more than four consecutive identical units." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler89() {", + " // Good luck!", + " return true;", + "}", + "", + "euler89();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3c61000cf542c50fed9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 90: Cube digit pairs", + "tests": [ + { + "text": "euler90() should return 1217.", + "testString": "assert.strictEqual(euler90(), 1217, 'euler90() should return 1217.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Each of the six faces on a cube has a different digit (0 to 9) written on it; the same is done to a second cube. By placing the two cubes side-by-side in different positions we can form a variety of 2-digit numbers.", + "", + "For example, the square number 64 could be formed:", + "", + "", + "", + "", + "In fact, by carefully choosing the digits on both cubes it is possible to display all of the square numbers below one-hundred: 01, 04, 09, 16, 25, 36, 49, 64, and 81.", + "", + "For example, one way this can be achieved is by placing {0, 5, 6, 7, 8, 9} on one cube and {1, 2, 3, 4, 8, 9} on the other cube.", + "", + "However, for this problem we shall allow the 6 or 9 to be turned upside-down so that an arrangement like {0, 5, 6, 7, 8, 9} and {1, 2, 3, 4, 6, 7} allows for all nine square numbers to be displayed; otherwise it would be impossible to obtain 09.", + "", + "In determining a distinct arrangement we are interested in the digits on each cube, not the order.", + "", + "{1, 2, 3, 4, 5, 6} is equivalent to {3, 6, 4, 1, 2, 5}", + "{1, 2, 3, 4, 5, 6} is distinct from {1, 2, 3, 4, 5, 9}", + "", + "But because we are allowing 6 and 9 to be reversed, the two distinct sets in the last example both represent the extended set {1, 2, 3, 4, 5, 6, 9} for the purpose of forming 2-digit numbers.", + "", + "How many distinct arrangements of the two cubes allow for all of the square numbers to be displayed?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler90() {", + " // Good luck!", + " return true;", + "}", + "", + "euler90();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3c71000cf542c50feda", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 91: Right triangles with integer coordinates", + "tests": [ + { + "text": "euler91() should return 14234.", + "testString": "assert.strictEqual(euler91(), 14234, 'euler91() should return 14234.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The points P (x1, y1) and Q (x2, y2) are plotted at integer co-ordinates and are joined to the origin, O(0,0), to form ΔOPQ.", + "", + "", + "", + "", + "There are exactly fourteen triangles containing a right angle that can be formed when each co-ordinate lies between 0 and 2 inclusive; that is,0 ≤ x1, y1, x2, y2 ≤ 2.", + "", + "", + "", + "", + "Given that 0 ≤ x1, y1, x2, y2 ≤ 50, how many right triangles can be formed?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler91() {", + " // Good luck!", + " return true;", + "}", + "", + "euler91();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3c81000cf542c50fedb", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 92: Square digit chains", + "tests": [ + { + "text": "euler92() should return 8581146.", + "testString": "assert.strictEqual(euler92(), 8581146, 'euler92() should return 8581146.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A number chain is created by continuously adding the square of the digits in a number to form a new number until it has been seen before.", + "For example,", + "44 → 32 → 13 → 10 → 1 → 1", + "85 → 89 → 145 → 42 → 20 → 4 → 16 → 37 → 58 → 89", + "Therefore any chain that arrives at 1 or 89 will become stuck in an endless loop. What is most amazing is that EVERY starting number will eventually arrive at 1 or 89.", + "How many starting numbers below ten million will arrive at 89?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler92() {", + " // Good luck!", + " return true;", + "}", + "", + "euler92();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ca1000cf542c50fedc", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 93: Arithmetic expressions", + "tests": [ + { + "text": "euler93() should return 1258.", + "testString": "assert.strictEqual(euler93(), 1258, 'euler93() should return 1258.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "By using each of the digits from the set, {1, 2, 3, 4}, exactly once, and making use of the four arithmetic operations (+, −, *, /) and brackets/parentheses, it is possible to form different positive integer targets.", + "For example,", + "8 = (4 * (1 + 3)) / 2", + "14 = 4 * (3 + 1 / 2)", + "19 = 4 * (2 + 3) − 1", + "36 = 3 * 4 * (2 + 1)", + "Note that concatenations of the digits, like 12 + 34, are not allowed.", + "Using the set, {1, 2, 3, 4}, it is possible to obtain thirty-one different target numbers of which 36 is the maximum, and each of the numbers 1 to 28 can be obtained before encountering the first non-expressible number.", + "Find the set of four distinct digits, a < b < c < d, for which the longest set of consecutive positive integers, 1 to n, can be obtained, giving your answer as a string: abcd." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler93() {", + " // Good luck!", + " return true;", + "}", + "", + "euler93();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ca1000cf542c50fedd", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 94: Almost equilateral triangles", + "tests": [ + { + "text": "euler94() should return 518408346.", + "testString": "assert.strictEqual(euler94(), 518408346, 'euler94() should return 518408346.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It is easily proved that no equilateral triangle exists with integral length sides and integral area. However, the almost equilateral triangle 5-5-6 has an area of 12 square units.", + "We shall define an almost equilateral triangle to be a triangle for which two sides are equal and the third differs by no more than one unit.", + "Find the sum of the perimeters of all almost equilateral triangles with integral side lengths and area and whose perimeters do not exceed one billion (1,000,000,000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler94() {", + " // Good luck!", + " return true;", + "}", + "", + "euler94();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3cc1000cf542c50fede", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 95: Amicable chains", + "tests": [ + { + "text": "euler95() should return 14316.", + "testString": "assert.strictEqual(euler95(), 14316, 'euler95() should return 14316.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The proper divisors of a number are all the divisors excluding the number itself. For example, the proper divisors of 28 are 1, 2, 4, 7, and 14. As the sum of these divisors is equal to 28, we call it a perfect number.", + "Interestingly the sum of the proper divisors of 220 is 284 and the sum of the proper divisors of 284 is 220, forming a chain of two numbers. For this reason, 220 and 284 are called an amicable pair.", + "Perhaps less well known are longer chains. For example, starting with 12496, we form a chain of five numbers:", + "12496 → 14288 → 15472 → 14536 → 14264 (→ 12496 → ...)", + "Since this chain returns to its starting point, it is called an amicable chain.", + "Find the smallest member of the longest amicable chain with no element exceeding one million." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler95() {", + " // Good luck!", + " return true;", + "}", + "", + "euler95();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3cc1000cf542c50fedf", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 96: Su Doku", + "tests": [ + { + "text": "euler96() should return 24702.", + "testString": "assert.strictEqual(euler96(), 24702, 'euler96() should return 24702.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Su Doku (Japanese meaning number place) is the name given to a popular puzzle concept. Its origin is unclear, but credit must be attributed to Leonhard Euler who invented a similar, and much more difficult, puzzle idea called Latin Squares. The objective of Su Doku puzzles, however, is to replace the blanks (or zeros) in a 9 by 9 grid in such that each row, column, and 3 by 3 box contains each of the digits 1 to 9. Below is an example of a typical starting puzzle grid and its solution grid.", + "", + "", + "0 0 39 0 00 0 1", + "0 2 03 0 58 0 6", + "6 0 00 0 14 0 0", + "0 0 87 0 00 0 6", + "1 0 20 0 07 0 8", + "9 0 00 0 82 0 0", + "0 0 28 0 00 0 5", + "6 0 92 0 30 1 0", + "5 0 00 0 93 0 0", + "", + "", + "", + "4 8 39 6 72 5 1", + "9 2 13 4 58 7 6", + "6 5 78 2 14 9 3", + "5 4 87 2 91 3 6", + "1 3 25 6 47 9 8", + "9 7 61 3 82 4 5", + "3 7 28 1 46 9 5", + "6 8 92 5 34 1 7", + "5 1 47 6 93 8 2", + "", + "", + "A well constructed Su Doku puzzle has a unique solution and can be solved by logic, although it may be necessary to employ \"guess and test\" methods in order to eliminate options (there is much contested opinion over this). The complexity of the search determines the difficulty of the puzzle; the example above is considered easy because it can be solved by straight forward direct deduction.", + "The 6K text file, sudoku.txt (right click and 'Save Link/Target As...'), contains fifty different Su Doku puzzles ranging in difficulty, but all with unique solutions (the first puzzle in the file is the example above).", + "By solving all fifty puzzles find the sum of the 3-digit numbers found in the top left corner of each solution grid; for example, 483 is the 3-digit number found in the top left corner of the solution grid above." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler96() {", + " // Good luck!", + " return true;", + "}", + "", + "euler96();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ce1000cf542c50fee0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 97: Large non-Mersenne prime", + "tests": [ + { + "text": "euler97() should return 8739992577.", + "testString": "assert.strictEqual(euler97(), 8739992577, 'euler97() should return 8739992577.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The first known prime found to exceed one million digits was discovered in 1999, and is a Mersenne prime of the form 26972593−1; it contains exactly 2,098,960 digits. Subsequently other Mersenne primes, of the form 2p−1, have been found which contain more digits.", + "However, in 2004 there was found a massive non-Mersenne prime which contains 2,357,207 digits: 28433×27830457+1.", + "Find the last ten digits of this prime number." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler97() {", + " // Good luck!", + " return true;", + "}", + "", + "euler97();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3cf1000cf542c50fee1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 98: Anagramic squares", + "tests": [ + { + "text": "euler98() should return 18769.", + "testString": "assert.strictEqual(euler98(), 18769, 'euler98() should return 18769.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "By replacing each of the letters in the word CARE with 1, 2, 9, and 6 respectively, we form a square number: 1296 = 362. What is remarkable is that, by using the same digital substitutions, the anagram, RACE, also forms a square number: 9216 = 962. We shall call CARE (and RACE) a square anagram word pair and specify further that leading zeroes are not permitted, neither may a different letter have the same digital value as another letter.", + "Using words.txt (right click and 'Save Link/Target As...'), a 16K text file containing nearly two-thousand common English words, find all the square anagram word pairs (a palindromic word is NOT considered to be an anagram of itself).", + "What is the largest square number formed by any member of such a pair?", + "NOTE: All anagrams formed must be contained in the given text file." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler98() {", + " // Good luck!", + " return true;", + "}", + "", + "euler98();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3d01000cf542c50fee2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 99: Largest exponential", + "tests": [ + { + "text": "euler99() should return 709.", + "testString": "assert.strictEqual(euler99(), 709, 'euler99() should return 709.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Comparing two numbers written in index form like 211 and 37 is not difficult, as any calculator would confirm that 211 = 2048 < 37 = 2187.", + "However, confirming that 632382518061 > 519432525806 would be much more difficult, as both numbers contain over three million digits.", + "Using base_exp.txt (right click and 'Save Link/Target As...'), a 22K text file containing one thousand lines with a base/exponent pair on each line, determine which line number has the greatest numerical value.", + "NOTE: The first two lines in the file represent the numbers in the example given above." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler99() {", + " // Good luck!", + " return true;", + "}", + "", + "euler99();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3d01000cf542c50fee3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 100: Arranged probability", + "tests": [ + { + "text": "euler100() should return 756872327473.", + "testString": "assert.strictEqual(euler100(), 756872327473, 'euler100() should return 756872327473.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "If a box contains twenty-one coloured discs, composed of fifteen blue discs and six red discs, and two discs were taken at random, it can be seen that the probability of taking two blue discs, P(BB) = (15/21)×(14/20) = 1/2.", + "The next such arrangement, for which there is exactly 50% chance of taking two blue discs at random, is a box containing eighty-five blue discs and thirty-five red discs.", + "By finding the first arrangement to contain over 1012 = 1,000,000,000,000 discs in total, determine the number of blue discs that the box would contain." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler100() {", + " // Good luck!", + " return true;", + "}", + "", + "euler100();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3d21000cf542c50fee4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 101: Optimum polynomial", + "tests": [ + { + "text": "euler101() should return 37076114526.", + "testString": "assert.strictEqual(euler101(), 37076114526, 'euler101() should return 37076114526.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "If we are presented with the first k terms of a sequence it is impossible to say with certainty the value of the next term, as there are infinitely many polynomial functions that can model the sequence.", + "As an example, let us consider the sequence of cube numbers. This is defined by the generating function, un = n3: 1, 8, 27, 64, 125, 216, ...", + "Suppose we were only given the first two terms of this sequence. Working on the principle that \"simple is best\" we should assume a linear relationship and predict the next term to be 15 (common difference 7). Even if we were presented with the first three terms, by the same principle of simplicity, a quadratic relationship should be assumed.", + "We shall define OP(k, n) to be the nth term of the optimum polynomial generating function for the first k terms of a sequence. It should be clear that OP(k, n) will accurately generate the terms of the sequence for n ≤ k, and potentially the first incorrect term (FIT) will be OP(k, k+1); in which case we shall call it a bad OP (BOP).", + "As a basis, if we were only given the first term of sequence, it would be most sensible to assume constancy; that is, for n ≥ 2, OP(1, n) = u1.", + "Hence we obtain the following OPs for the cubic sequence:", + "", + "OP(1, n) = 1", + "1, 1, 1, 1, ...", + "OP(2, n) = 7n−6", + "1, 8, 15, ...", + "OP(3, n) = 6n2−11n+6     ", + "1, 8, 27, 58, ...", + "OP(4, n) = n3", + "1, 8, 27, 64, 125, ...", + "", + "Clearly no BOPs exist for k ≥ 4.", + "By considering the sum of FITs generated by the BOPs (indicated in red above), we obtain 1 + 15 + 58 = 74.", + "Consider the following tenth degree polynomial generating function:", + "un = 1 − n + n2 − n3 + n4 − n5 + n6 − n7 + n8 − n9 + n10", + "Find the sum of FITs for the BOPs." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler101() {", + " // Good luck!", + " return true;", + "}", + "", + "euler101();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3d21000cf542c50fee5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 102: Triangle containment", + "tests": [ + { + "text": "euler102() should return 228.", + "testString": "assert.strictEqual(euler102(), 228, 'euler102() should return 228.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Three distinct points are plotted at random on a Cartesian plane, for which -1000 ≤ x, y ≤ 1000, such that a triangle is formed.", + "Consider the following two triangles:", + "A(-340,495), B(-153,-910), C(835,-947)", + "X(-175,41), Y(-421,-714), Z(574,-645)", + "It can be verified that triangle ABC contains the origin, whereas triangle XYZ does not.", + "Using triangles.txt (right click and 'Save Link/Target As...'), a 27K text file containing the co-ordinates of one thousand \"random\" triangles, find the number of triangles for which the interior contains the origin.", + "NOTE: The first two examples in the file represent the triangles in the example given above." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler102() {", + " // Good luck!", + " return true;", + "}", + "", + "euler102();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3d61000cf542c50fee7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 103: Special subset sums: optimum", + "tests": [ + { + "text": "euler103() should return 20313839404245.", + "testString": "assert.strictEqual(euler103(), 20313839404245, 'euler103() should return 20313839404245.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let S(A) represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:", + "S(B) ≠ S(C); that is, sums of subsets cannot be equal.", + "If B contains more elements than C then S(B) > S(C).", + "If S(A) is minimised for a given n, we shall call it an optimum special sum set. The first five optimum special sum sets are given below.", + "n = 1: {1}n = 2: {1, 2}n = 3: {2, 3, 4}n = 4: {3, 5, 6, 7}n = 5: {6, 9, 11, 12, 13}", + "It seems that for a given optimum set, A = {a1, a2, ... , an}, the next optimum set is of the form B = {b, a1+b, a2+b, ... ,an+b}, where b is the \"middle\" element on the previous row.", + "By applying this \"rule\" we would expect the optimum set for n = 6 to be A = {11, 17, 20, 22, 23, 24}, with S(A) = 117. However, this is not the optimum set, as we have merely applied an algorithm to provide a near optimum set. The optimum set for n = 6 is A = {11, 18, 19, 20, 22, 25}, with S(A) = 115 and corresponding set string: 111819202225.", + "Given that A is an optimum special sum set for n = 7, find its set string.", + "NOTE: This problem is related to Problem 105 and Problem 106." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler103() {", + " // Good luck!", + " return true;", + "}", + "", + "euler103();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3d51000cf542c50fee6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 104: Pandigital Fibonacci ends", + "tests": [ + { + "text": "euler104() should return 329468.", + "testString": "assert.strictEqual(euler104(), 329468, 'euler104() should return 329468.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The Fibonacci sequence is defined by the recurrence relation:", + "Fn = Fn−1 + Fn−2, where F1 = 1 and F2 = 1.", + "It turns out that F541, which contains 113 digits, is the first Fibonacci number for which the last nine digits are 1-9 pandigital (contain all the digits 1 to 9, but not necessarily in order). And F2749, which contains 575 digits, is the first Fibonacci number for which the first nine digits are 1-9 pandigital.", + "Given that Fk is the first Fibonacci number for which the first nine digits AND the last nine digits are 1-9 pandigital, find k." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler104() {", + " // Good luck!", + " return true;", + "}", + "", + "euler104();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3d61000cf542c50fee8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 105: Special subset sums: testing", + "tests": [ + { + "text": "euler105() should return 73702.", + "testString": "assert.strictEqual(euler105(), 73702, 'euler105() should return 73702.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let S(A) represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:", + "S(B) ≠ S(C); that is, sums of subsets cannot be equal.", + "If B contains more elements than C then S(B) > S(C).", + "For example, {81, 88, 75, 42, 87, 84, 86, 65} is not a special sum set because 65 + 87 + 88 = 75 + 81 + 84, whereas {157, 150, 164, 119, 79, 159, 161, 139, 158} satisfies both rules for all possible subset pair combinations and S(A) = 1286.", + "Using sets.txt (right click and \"Save Link/Target As...\"), a 4K text file with one-hundred sets containing seven to twelve elements (the two examples given above are the first two sets in the file), identify all the special sum sets, A1, A2, ..., Ak, and find the value of S(A1) + S(A2) + ... + S(Ak).", + "NOTE: This problem is related to Problem 103 and Problem 106." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler105() {", + " // Good luck!", + " return true;", + "}", + "", + "euler105();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3d71000cf542c50fee9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 106: Special subset sums: meta-testing", + "tests": [ + { + "text": "euler106() should return 21384.", + "testString": "assert.strictEqual(euler106(), 21384, 'euler106() should return 21384.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let S(A) represent the sum of elements in set A of size n. We shall call it a special sum set if for any two non-empty disjoint subsets, B and C, the following properties are true:", + "S(B) ≠ S(C); that is, sums of subsets cannot be equal.", + "If B contains more elements than C then S(B) > S(C).", + "For this problem we shall assume that a given set contains n strictly increasing elements and it already satisfies the second rule.", + "Surprisingly, out of the 25 possible subset pairs that can be obtained from a set for which n = 4, only 1 of these pairs need to be tested for equality (first rule). Similarly, when n = 7, only 70 out of the 966 subset pairs need to be tested.", + "For n = 12, how many of the 261625 subset pairs that can be obtained need to be tested for equality?", + "NOTE: This problem is related to Problem 103 and Problem 105." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler106() {", + " // Good luck!", + " return true;", + "}", + "", + "euler106();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3d91000cf542c50feea", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 107: Minimal network", + "tests": [ + { + "text": "euler107() should return 259679.", + "testString": "assert.strictEqual(euler107(), 259679, 'euler107() should return 259679.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The following undirected network consists of seven vertices and twelve edges with a total weight of 243.", + "", + "", + "The same network can be represented by the matrix below.", + "    ABCDEFG", + "A-161221---", + "B16--1720--", + "C12--28-31-", + "D211728-181923", + "E-20-18--11", + "F--3119--27", + "G---231127-", + "However, it is possible to optimise the network by removing some edges and still ensure that all points on the network remain connected. The network which achieves the maximum saving is shown below. It has a weight of 93, representing a saving of 243 − 93 = 150 from the original network.", + "", + "", + "Using network.txt (right click and 'Save Link/Target As...'), a 6K text file containing a network with forty vertices, and given in matrix form, find the maximum saving which can be achieved by removing redundant edges whilst ensuring that the network remains connected." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler107() {", + " // Good luck!", + " return true;", + "}", + "", + "euler107();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3d91000cf542c50feeb", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 108: About Project Euler", + "tests": [ + { + "text": "euler108() should return 180180.", + "testString": "assert.strictEqual(euler108(), 180180, 'euler108() should return 180180.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler108() {", + " // Good luck!", + " return true;", + "}", + "", + "euler108();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3db1000cf542c50feec", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 109: Darts", + "tests": [ + { + "text": "euler109() should return 38182.", + "testString": "assert.strictEqual(euler109(), 38182, 'euler109() should return 38182.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In the game of darts a player throws three darts at a target board which is split into twenty equal sized sections numbered one to twenty.", + "", + "", + "The score of a dart is determined by the number of the region that the dart lands in. A dart landing outside the red/green outer ring scores zero. The black and cream regions inside this ring represent single scores. However, the red/green outer ring and middle ring score double and treble scores respectively.", + "At the centre of the board are two concentric circles called the bull region, or bulls-eye. The outer bull is worth 25 points and the inner bull is a double, worth 50 points.", + "There are many variations of rules but in the most popular game the players will begin with a score 301 or 501 and the first player to reduce their running total to zero is a winner. However, it is normal to play a \"doubles out\" system, which means that the player must land a double (including the double bulls-eye at the centre of the board) on their final dart to win; any other dart that would reduce their running total to one or lower means the score for that set of three darts is \"bust\".", + "When a player is able to finish on their current score it is called a \"checkout\" and the highest checkout is 170: T20 T20 D25 (two treble 20s and double bull).", + "There are exactly eleven distinct ways to checkout on a score of 6:", + "", + "D3", + " ", + " ", + "D1", + "D2", + " ", + "S2", + "D2", + " ", + "D2", + "D1", + " ", + "S4", + "D1", + " ", + "S1", + "S1", + "D2", + "S1", + "T1", + "D1", + "S1", + "S3", + "D1", + "D1", + "D1", + "D1", + "D1", + "S2", + "D1", + "S2", + "S2", + "D1", + "", + "Note that D1 D2 is considered different to D2 D1 as they finish on different doubles. However, the combination S1 T1 D1 is considered the same as T1 S1 D1.", + "In addition we shall not include misses in considering combinations; for example, D3 is the same as 0 D3 and 0 0 D3.", + "Incredibly there are 42336 distinct ways of checking out in total.", + "How many distinct ways can a player checkout with a score less than 100?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler109() {", + " // Good luck!", + " return true;", + "}", + "", + "euler109();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3db1000cf542c50feed", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 110: About Project Euler", + "tests": [ + { + "text": "euler110() should return 9350130049860600.", + "testString": "assert.strictEqual(euler110(), 9350130049860600, 'euler110() should return 9350130049860600.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler110() {", + " // Good luck!", + " return true;", + "}", + "", + "euler110();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3db1000cf542c50feee", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 111: Primes with runs", + "tests": [ + { + "text": "euler111() should return 612407567715.", + "testString": "assert.strictEqual(euler111(), 612407567715, 'euler111() should return 612407567715.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Considering 4-digit primes containing repeated digits it is clear that they cannot all be the same: 1111 is divisible by 11, 2222 is divisible by 22, and so on. But there are nine 4-digit primes containing three ones:", + "1117, 1151, 1171, 1181, 1511, 1811, 2111, 4111, 8111", + "We shall say that M(n, d) represents the maximum number of repeated digits for an n-digit prime where d is the repeated digit, N(n, d) represents the number of such primes, and S(n, d) represents the sum of these primes.", + "So M(4, 1) = 3 is the maximum number of repeated digits for a 4-digit prime where one is the repeated digit, there are N(4, 1) = 9 such primes, and the sum of these primes is S(4, 1) = 22275. It turns out that for d = 0, it is only possible to have M(4, 0) = 2 repeated digits, but there are N(4, 0) = 13 such cases.", + "In the same way we obtain the following results for 4-digit primes.", + "", + "Digit, d", + "M(4, d)", + "N(4, d)", + "S(4, d)", + "0", + "2", + "13", + "67061", + "1", + "3", + "9", + "22275", + "2", + "3", + "1", + "2221", + "3", + "3", + "12", + "46214", + "4", + "3", + "2", + "8888", + "5", + "3", + "1", + "5557", + "6", + "3", + "1", + "6661", + "7", + "3", + "9", + "57863", + "8", + "3", + "1", + "8887", + "9", + "3", + "7", + "48073", + "", + "For d = 0 to 9, the sum of all S(4, d) is 273700.", + "Find the sum of all S(10, d)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler111() {", + " // Good luck!", + " return true;", + "}", + "", + "euler111();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3dd1000cf542c50feef", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 112: Bouncy numbers", + "tests": [ + { + "text": "euler112() should return 1587000.", + "testString": "assert.strictEqual(euler112(), 1587000, 'euler112() should return 1587000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Working from left-to-right if no digit is exceeded by the digit to its left it is called an increasing number; for example, 134468.", + "Similarly if no digit is exceeded by the digit to its right it is called a decreasing number; for example, 66420.", + "We shall call a positive integer that is neither increasing nor decreasing a \"bouncy\" number; for example, 155349.", + "Clearly there cannot be any bouncy numbers below one-hundred, but just over half of the numbers below one-thousand (525) are bouncy. In fact, the least number for which the proportion of bouncy numbers first reaches 50% is 538.", + "Surprisingly, bouncy numbers become more and more common and by the time we reach 21780 the proportion of bouncy numbers is equal to 90%.", + "Find the least number for which the proportion of bouncy numbers is exactly 99%." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler112() {", + " // Good luck!", + " return true;", + "}", + "", + "euler112();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3dd1000cf542c50fef0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 113: Non-bouncy numbers", + "tests": [ + { + "text": "euler113() should return 51161058134250.", + "testString": "assert.strictEqual(euler113(), 51161058134250, 'euler113() should return 51161058134250.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Working from left-to-right if no digit is exceeded by the digit to its left it is called an increasing number; for example, 134468.", + "Similarly if no digit is exceeded by the digit to its right it is called a decreasing number; for example, 66420.", + "We shall call a positive integer that is neither increasing nor decreasing a \"bouncy\" number; for example, 155349.", + "As n increases, the proportion of bouncy numbers below n increases such that there are only 12951 numbers below one-million that are not bouncy and only 277032 non-bouncy numbers below 1010.", + "How many numbers below a googol (10100) are not bouncy?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler113() {", + " // Good luck!", + " return true;", + "}", + "", + "euler113();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e01000cf542c50fef2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 114: Counting block combinations I", + "tests": [ + { + "text": "euler114() should return 16475640049.", + "testString": "assert.strictEqual(euler114(), 16475640049, 'euler114() should return 16475640049.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A row measuring seven units in length has red blocks with a minimum length of three units placed on it, such that any two red blocks (which are allowed to be different lengths) are separated by at least one black square. There are exactly seventeen ways of doing this.", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + " ", + "How many ways can a row measuring fifty units in length be filled?", + "NOTE: Although the example above does not lend itself to the possibility, in general it is permitted to mix block sizes. For example, on a row measuring eight units in length you could use red (3), black (1), and red (4)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler114() {", + " // Good luck!", + " return true;", + "}", + "", + "euler114();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3df1000cf542c50fef1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 115: Counting block combinations II", + "tests": [ + { + "text": "euler115() should return 168.", + "testString": "assert.strictEqual(euler115(), 168, 'euler115() should return 168.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "NOTE: This is a more difficult version of Problem 114.", + "A row measuring n units in length has red blocks with a minimum length of m units placed on it, such that any two red blocks (which are allowed to be different lengths) are separated by at least one black square.", + "Let the fill-count function, F(m, n), represent the number of ways that a row can be filled.", + "For example, F(3, 29) = 673135 and F(3, 30) = 1089155.", + "That is, for m = 3, it can be seen that n = 30 is the smallest value for which the fill-count function first exceeds one million.", + "In the same way, for m = 10, it can be verified that F(10, 56) = 880711 and F(10, 57) = 1148904, so n = 57 is the least value for which the fill-count function first exceeds one million.", + "For m = 50, find the least value of n for which the fill-count function first exceeds one million." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler115() {", + " // Good luck!", + " return true;", + "}", + "", + "euler115();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e01000cf542c50fef3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 116: Red, green or blue tiles", + "tests": [ + { + "text": "euler116() should return 20492570929.", + "testString": "assert.strictEqual(euler116(), 20492570929, 'euler116() should return 20492570929.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A row of five black square tiles is to have a number of its tiles replaced with coloured oblong tiles chosen from red (length two), green (length three), or blue (length four).", + "If red tiles are chosen there are exactly seven ways this can be done.", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + " ", + "If green tiles are chosen there are three ways.", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + " ", + "And if blue tiles are chosen there are two ways.", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "Assuming that colours cannot be mixed there are 7 + 3 + 2 = 12 ways of replacing the black tiles in a row measuring five units in length.", + "How many different ways can the black tiles in a row measuring fifty units in length be replaced if colours cannot be mixed and at least one coloured tile must be used?", + "NOTE: This is related to Problem 117." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler116() {", + " // Good luck!", + " return true;", + "}", + "", + "euler116();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e21000cf542c50fef4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 117: Red, green, and blue tiles", + "tests": [ + { + "text": "euler117() should return 100808458960497.", + "testString": "assert.strictEqual(euler117(), 100808458960497, 'euler117() should return 100808458960497.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Using a combination of black square tiles and oblong tiles chosen from: red tiles measuring two units, green tiles measuring three units, and blue tiles measuring four units, it is possible to tile a row measuring five units in length in exactly fifteen different ways.", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + " ", + "How many ways can a row measuring fifty units in length be tiled?", + "NOTE: This is related to Problem 116." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler117() {", + " // Good luck!", + " return true;", + "}", + "", + "euler117();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e21000cf542c50fef5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 118: Pandigital prime sets", + "tests": [ + { + "text": "euler118() should return 44680.", + "testString": "assert.strictEqual(euler118(), 44680, 'euler118() should return 44680.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Using all of the digits 1 through 9 and concatenating them freely to form decimal integers, different sets can be formed. Interestingly with the set {2,5,47,89,631}, all of the elements belonging to it are prime.", + "How many distinct sets containing each of the digits one through nine exactly once contain only prime elements?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler118() {", + " // Good luck!", + " return true;", + "}", + "", + "euler118();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e41000cf542c50fef6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 119: Digit power sum", + "tests": [ + { + "text": "euler119() should return 248155780267521.", + "testString": "assert.strictEqual(euler119(), 248155780267521, 'euler119() should return 248155780267521.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The number 512 is interesting because it is equal to the sum of its digits raised to some power: 5 + 1 + 2 = 8, and 83 = 512. Another example of a number with this property is 614656 = 284.", + "We shall define an to be the nth term of this sequence and insist that a number must contain at least two digits to have a sum.", + "You are given that a2 = 512 and a10 = 614656.", + "Find a30." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler119() {", + " // Good luck!", + " return true;", + "}", + "", + "euler119();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e41000cf542c50fef7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 120: Square remainders", + "tests": [ + { + "text": "euler120() should return 333082500.", + "testString": "assert.strictEqual(euler120(), 333082500, 'euler120() should return 333082500.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let r be the remainder when (a−1)n + (a+1)n is divided by a2.", + "For example, if a = 7 and n = 3, then r = 42: 63 + 83 = 728 ≡ 42 mod 49. And as n varies, so too will r, but for a = 7 it turns out that rmax = 42.", + "For 3 ≤ a ≤ 1000, find ∑ rmax." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler120() {", + " // Good luck!", + " return true;", + "}", + "", + "euler120();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e51000cf542c50fef8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 121: Disc game prize fund", + "tests": [ + { + "text": "euler121() should return 2269.", + "testString": "assert.strictEqual(euler121(), 2269, 'euler121() should return 2269.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A bag contains one red disc and one blue disc. In a game of chance a player takes a disc at random and its colour is noted. After each turn the disc is returned to the bag, an extra red disc is added, and another disc is taken at random.", + "The player pays £1 to play and wins if they have taken more blue discs than red discs at the end of the game.", + "If the game is played for four turns, the probability of a player winning is exactly 11/120, and so the maximum prize fund the banker should allocate for winning in this game would be £10 before they would expect to incur a loss. Note that any payout will be a whole number of pounds and also includes the original £1 paid to play the game, so in the example given the player actually wins £9.", + "Find the maximum prize fund that should be allocated to a single game in which fifteen turns are played." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler121() {", + " // Good luck!", + " return true;", + "}", + "", + "euler121();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e61000cf542c50fef9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 122: Efficient exponentiation", + "tests": [ + { + "text": "euler122() should return 1582.", + "testString": "assert.strictEqual(euler122(), 1582, 'euler122() should return 1582.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The most naive way of computing n15 requires fourteen multiplications:", + "n × n × ... × n = n15", + "But using a \"binary\" method you can compute it in six multiplications:", + "n × n = n2n2 × n2 = n4n4 × n4 = n8n8 × n4 = n12n12 × n2 = n14n14 × n = n15", + "However it is yet possible to compute it in only five multiplications:", + "n × n = n2n2 × n = n3n3 × n3 = n6n6 × n6 = n12n12 × n3 = n15", + "We shall define m(k) to be the minimum number of multiplications to compute nk; for example m(15) = 5.", + "For 1 ≤ k ≤ 200, find ∑ m(k)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler122() {", + " // Good luck!", + " return true;", + "}", + "", + "euler122();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e71000cf542c50fefa", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 123: Prime square remainders", + "tests": [ + { + "text": "euler123() should return 21035.", + "testString": "assert.strictEqual(euler123(), 21035, 'euler123() should return 21035.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let pn be the nth prime: 2, 3, 5, 7, 11, ..., and let r be the remainder when (pn−1)n + (pn+1)n is divided by pn2.", + "For example, when n = 3, p3 = 5, and 43 + 63 = 280 ≡ 5 mod 25.", + "The least value of n for which the remainder first exceeds 109 is 7037.", + "Find the least value of n for which the remainder first exceeds 1010." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler123() {", + " // Good luck!", + " return true;", + "}", + "", + "euler123();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e81000cf542c50fefb", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 124: Ordered radicals", + "tests": [ + { + "text": "euler124() should return 21417.", + "testString": "assert.strictEqual(euler124(), 21417, 'euler124() should return 21417.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The radical of n, rad(n), is the product of the distinct prime factors of n. For example, 504 = 23 × 32 × 7, so rad(504) = 2 × 3 × 7 = 42.", + "If we calculate rad(n) for 1 ≤ n ≤ 10, then sort them on rad(n), and sorting on n if the radical values are equal, we get:", + "Unsorted", + " ", + "Sorted", + "n", + "rad(n)", + "", + "n", + "rad(n)", + "k", + "11", + " ", + "111", + "22", + " ", + "222", + "33", + " ", + "423", + "42", + " ", + "824", + "55", + " ", + "335", + "66", + " ", + "936", + "77", + " ", + "557", + "82", + " ", + "668", + "93", + " ", + "779", + "1010", + " ", + "101010", + "Let E(k) be the kth element in the sorted n column; for example, E(4) = 8 and E(6) = 9.", + "If rad(n) is sorted for 1 ≤ n ≤ 100000, find E(10000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler124() {", + " // Good luck!", + " return true;", + "}", + "", + "euler124();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3e91000cf542c50fefc", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 125: Palindromic sums", + "tests": [ + { + "text": "euler125() should return 2906969179.", + "testString": "assert.strictEqual(euler125(), 2906969179, 'euler125() should return 2906969179.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The palindromic number 595 is interesting because it can be written as the sum of consecutive squares: 62 + 72 + 82 + 92 + 102 + 112 + 122.", + "There are exactly eleven palindromes below one-thousand that can be written as consecutive square sums, and the sum of these palindromes is 4164. Note that 1 = 02 + 12 has not been included as this problem is concerned with the squares of positive integers.", + "Find the sum of all the numbers less than 108 that are both palindromic and can be written as the sum of consecutive squares." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler125() {", + " // Good luck!", + " return true;", + "}", + "", + "euler125();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ea1000cf542c50fefd", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 126: Cuboid layers", + "tests": [ + { + "text": "euler126() should return 18522.", + "testString": "assert.strictEqual(euler126(), 18522, 'euler126() should return 18522.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The minimum number of cubes to cover every visible face on a cuboid measuring 3 x 2 x 1 is twenty-two.", + "", + "", + "If we then add a second layer to this solid it would require forty-six cubes to cover every visible face, the third layer would require seventy-eight cubes, and the fourth layer would require one-hundred and eighteen cubes to cover every visible face.", + "However, the first layer on a cuboid measuring 5 x 1 x 1 also requires twenty-two cubes; similarly the first layer on cuboids measuring 5 x 3 x 1, 7 x 2 x 1, and 11 x 1 x 1 all contain forty-six cubes.", + "We shall define C(n) to represent the number of cuboids that contain n cubes in one of its layers. So C(22) = 2, C(46) = 4, C(78) = 5, and C(118) = 8.", + "It turns out that 154 is the least value of n for which C(n) = 10.", + "Find the least value of n for which C(n) = 1000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler126() {", + " // Good luck!", + " return true;", + "}", + "", + "euler126();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ec1000cf542c50fefe", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 127: abc-hits", + "tests": [ + { + "text": "euler127() should return 18407904.", + "testString": "assert.strictEqual(euler127(), 18407904, 'euler127() should return 18407904.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The radical of n, rad(n), is the product of distinct prime factors of n. For example, 504 = 23 × 32 × 7, so rad(504) = 2 × 3 × 7 = 42.", + "We shall define the triplet of positive integers (a, b, c) to be an abc-hit if:", + "GCD(a, b) = GCD(a, c) = GCD(b, c) = 1", + "a < b", + "a + b = c", + "rad(abc) < c", + "For example, (5, 27, 32) is an abc-hit, because:", + "GCD(5, 27) = GCD(5, 32) = GCD(27, 32) = 1", + "5 < 27", + "5 + 27 = 32", + "rad(4320) = 30 < 32", + "It turns out that abc-hits are quite rare and there are only thirty-one abc-hits for c < 1000, with ∑c = 12523.", + "Find ∑c for c < 120000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler127() {", + " // Good luck!", + " return true;", + "}", + "", + "euler127();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ec1000cf542c50feff", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 128: Hexagonal tile differences", + "tests": [ + { + "text": "euler128() should return 14516824220.", + "testString": "assert.strictEqual(euler128(), 14516824220, 'euler128() should return 14516824220.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A hexagonal tile with number 1 is surrounded by a ring of six hexagonal tiles, starting at \"12 o'clock\" and numbering the tiles 2 to 7 in an anti-clockwise direction.", + "New rings are added in the same fashion, with the next rings being numbered 8 to 19, 20 to 37, 38 to 61, and so on. The diagram below shows the first three rings.", + "", + "", + "By finding the difference between tile n and each of its six neighbours we shall define PD(n) to be the number of those differences which are prime.", + "For example, working clockwise around tile 8 the differences are 12, 29, 11, 6, 1, and 13. So PD(8) = 3.", + "In the same way, the differences around tile 17 are 1, 17, 16, 1, 11, and 10, hence PD(17) = 2.", + "It can be shown that the maximum value of PD(n) is 3.", + "If all of the tiles for which PD(n) = 3 are listed in ascending order to form a sequence, the 10th tile would be 271.", + "Find the 2000th tile in this sequence." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler128() {", + " // Good luck!", + " return true;", + "}", + "", + "euler128();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ef1000cf542c50ff01", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 129: Repunit divisibility", + "tests": [ + { + "text": "euler129() should return 1000023.", + "testString": "assert.strictEqual(euler129(), 1000023, 'euler129() should return 1000023.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A number consisting entirely of ones is called a repunit. We shall define R(k) to be a repunit of length k; for example, R(6) = 111111.", + "Given that n is a positive integer and GCD(n, 10) = 1, it can be shown that there always exists a value, k, for which R(k) is divisible by n, and let A(n) be the least such value of k; for example, A(7) = 6 and A(41) = 5.", + "The least value of n for which A(n) first exceeds ten is 17.", + "Find the least value of n for which A(n) first exceeds one-million." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler129() {", + " // Good luck!", + " return true;", + "}", + "", + "euler129();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ee1000cf542c50ff00", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 130: Composites with prime repunit property", + "tests": [ + { + "text": "euler130() should return 149253.", + "testString": "assert.strictEqual(euler130(), 149253, 'euler130() should return 149253.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A number consisting entirely of ones is called a repunit. We shall define R(k) to be a repunit of length k; for example, R(6) = 111111.", + "Given that n is a positive integer and GCD(n, 10) = 1, it can be shown that there always exists a value, k, for which R(k) is divisible by n, and let A(n) be the least such value of k; for example, A(7) = 6 and A(41) = 5.", + "You are given that for all primes, p > 5, that p − 1 is divisible by A(p). For example, when p = 41, A(41) = 5, and 40 is divisible by 5.", + "However, there are rare composite values for which this is also true; the first five examples being 91, 259, 451, 481, and 703.", + "Find the sum of the first twenty-five composite values of n for whichGCD(n, 10) = 1 and n − 1 is divisible by A(n)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler130() {", + " // Good luck!", + " return true;", + "}", + "", + "euler130();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ef1000cf542c50ff02", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 131: Prime cube partnership", + "tests": [ + { + "text": "euler131() should return 173.", + "testString": "assert.strictEqual(euler131(), 173, 'euler131() should return 173.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "There are some prime values, p, for which there exists a positive integer, n, such that the expression n3 + n2p is a perfect cube.", + "For example, when p = 19, 83 + 82×19 = 123.", + "What is perhaps most surprising is that for each prime with this property the value of n is unique, and there are only four such primes below one-hundred.", + "How many primes below one million have this remarkable property?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler131() {", + " // Good luck!", + " return true;", + "}", + "", + "euler131();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3f11000cf542c50ff03", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 132: Large repunit factors", + "tests": [ + { + "text": "euler132() should return 843296.", + "testString": "assert.strictEqual(euler132(), 843296, 'euler132() should return 843296.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A number consisting entirely of ones is called a repunit. We shall define R(k) to be a repunit of length k.", + "For example, R(10) = 1111111111 = 11×41×271×9091, and the sum of these prime factors is 9414.", + "Find the sum of the first forty prime factors of R(109)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler132() {", + " // Good luck!", + " return true;", + "}", + "", + "euler132();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3f21000cf542c50ff04", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 133: Repunit nonfactors", + "tests": [ + { + "text": "euler133() should return 453647705.", + "testString": "assert.strictEqual(euler133(), 453647705, 'euler133() should return 453647705.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A number consisting entirely of ones is called a repunit. We shall define R(k) to be a repunit of length k; for example, R(6) = 111111.", + "Let us consider repunits of the form R(10n).", + "Although R(10), R(100), or R(1000) are not divisible by 17, R(10000) is divisible by 17. Yet there is no value of n for which R(10n) will divide by 19. In fact, it is remarkable that 11, 17, 41, and 73 are the only four primes below one-hundred that can be a factor of R(10n).", + "Find the sum of all the primes below one-hundred thousand that will never be a factor of R(10n)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler133() {", + " // Good luck!", + " return true;", + "}", + "", + "euler133();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3f21000cf542c50ff05", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 134: Prime pair connection", + "tests": [ + { + "text": "euler134() should return 18613426663617120.", + "testString": "assert.strictEqual(euler134(), 18613426663617120, 'euler134() should return 18613426663617120.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the consecutive primes p1 = 19 and p2 = 23. It can be verified that 1219 is the smallest number such that the last digits are formed by p1 whilst also being divisible by p2.", + "In fact, with the exception of p1 = 3 and p2 = 5, for every pair of consecutive primes, p2 > p1, there exist values of n for which the last digits are formed by p1 and n is divisible by p2. Let S be the smallest of these values of n.", + "Find ∑ S for every pair of consecutive primes with 5 ≤ p1 ≤ 1000000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler134() {", + " // Good luck!", + " return true;", + "}", + "", + "euler134();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3f31000cf542c50ff06", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 135: Same differences", + "tests": [ + { + "text": "euler135() should return 4989.", + "testString": "assert.strictEqual(euler135(), 4989, 'euler135() should return 4989.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given the positive integers, x, y, and z, are consecutive terms of an arithmetic progression, the least value of the positive integer, n, for which the equation, x2 − y2 − z2 = n, has exactly two solutions is n = 27:", + "342 − 272 − 202 = 122 − 92 − 62 = 27", + "It turns out that n = 1155 is the least value which has exactly ten solutions.", + "How many values of n less than one million have exactly ten distinct solutions?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler135() {", + " // Good luck!", + " return true;", + "}", + "", + "euler135();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3f51000cf542c50ff07", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 136: Singleton difference", + "tests": [ + { + "text": "euler136() should return 2544559.", + "testString": "assert.strictEqual(euler136(), 2544559, 'euler136() should return 2544559.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The positive integers, x, y, and z, are consecutive terms of an arithmetic progression. Given that n is a positive integer, the equation, x2 − y2 − z2 = n, has exactly one solution when n = 20:", + "132 − 102 − 72 = 20", + "In fact there are twenty-five values of n below one hundred for which the equation has a unique solution.", + "How many values of n less than fifty million have exactly one solution?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler136() {", + " // Good luck!", + " return true;", + "}", + "", + "euler136();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3f51000cf542c50ff08", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 137: Fibonacci golden nuggets", + "tests": [ + { + "text": "euler137() should return 1120149658760.", + "testString": "assert.strictEqual(euler137(), 1120149658760, 'euler137() should return 1120149658760.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the infinite polynomial series AF(x) = xF1 + x2F2 + x3F3 + ..., where Fk is the kth term in the Fibonacci sequence: 1, 1, 2, 3, 5, 8, ... ; that is, Fk = Fk−1 + Fk−2, F1 = 1 and F2 = 1.", + "For this problem we shall be interested in values of x for which AF(x) is a positive integer.", + "Surprisingly AF(1/2)", + " = ", + "(1/2).1 + (1/2)2.1 + (1/2)3.2 + (1/2)4.3 + (1/2)5.5 + ...", + " ", + " = ", + "1/2 + 1/4 + 2/8 + 3/16 + 5/32 + ...", + " ", + " = ", + "2", + "The corresponding values of x for the first five natural numbers are shown below.", + "", + "xAF(x)", + "√2−11", + "1/22", + "(√13−2)/33", + "(√89−5)/84", + "(√34−3)/55", + "", + "We shall call AF(x) a golden nugget if x is rational, because they become increasingly rarer; for example, the 10th golden nugget is 74049690.", + "Find the 15th golden nugget." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler137() {", + " // Good luck!", + " return true;", + "}", + "", + "euler137();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3f61000cf542c50ff09", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 138: Special isosceles triangles", + "tests": [ + { + "text": "euler138() should return 1118049290473932.", + "testString": "assert.strictEqual(euler138(), 1118049290473932, 'euler138() should return 1118049290473932.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the isosceles triangle with base length, b = 16, and legs, L = 17.", + "", + "", + "By using the Pythagorean theorem it can be seen that the height of the triangle, h = √(172 − 82) = 15, which is one less than the base length.", + "With b = 272 and L = 305, we get h = 273, which is one more than the base length, and this is the second smallest isosceles triangle with the property that h = b ± 1.", + "Find ∑ L for the twelve smallest isosceles triangles for which h = b ± 1 and b, L are positive integers." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler138() {", + " // Good luck!", + " return true;", + "}", + "", + "euler138();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3f71000cf542c50ff0a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 139: Pythagorean tiles", + "tests": [ + { + "text": "euler139() should return 10057761.", + "testString": "assert.strictEqual(euler139(), 10057761, 'euler139() should return 10057761.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let (a, b, c) represent the three sides of a right angle triangle with integral length sides. It is possible to place four such triangles together to form a square with length c.", + "For example, (3, 4, 5) triangles can be placed together to form a 5 by 5 square with a 1 by 1 hole in the middle and it can be seen that the 5 by 5 square can be tiled with twenty-five 1 by 1 squares.", + "", + "", + "However, if (5, 12, 13) triangles were used then the hole would measure 7 by 7 and these could not be used to tile the 13 by 13 square.", + "Given that the perimeter of the right triangle is less than one-hundred million, how many Pythagorean triangles would allow such a tiling to take place?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler139() {", + " // Good luck!", + " return true;", + "}", + "", + "euler139();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3fa1000cf542c50ff0c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 140: Modified Fibonacci golden nuggets", + "tests": [ + { + "text": "euler140() should return 5673835352990.", + "testString": "assert.strictEqual(euler140(), 5673835352990, 'euler140() should return 5673835352990.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the infinite polynomial series AG(x) = xG1 + x2G2 + x3G3 + ..., where Gk is the kth term of the second order recurrence relation Gk = Gk−1 + Gk−2, G1 = 1 and G2 = 4; that is, 1, 4, 5, 9, 14, 23, ... .", + "For this problem we shall be concerned with values of x for which AG(x) is a positive integer.", + "The corresponding values of x for the first five natural numbers are shown below.", + "", + "xAG(x)", + "(√5−1)/41", + "2/52", + "(√22−2)/63", + "(√137−5)/144", + "1/25", + "", + "We shall call AG(x) a golden nugget if x is rational, because they become increasingly rarer; for example, the 20th golden nugget is 211345365.", + "Find the sum of the first thirty golden nuggets." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler140() {", + " // Good luck!", + " return true;", + "}", + "", + "euler140();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3f91000cf542c50ff0b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 141: Investigating progressive numbers, n, which are also square", + "tests": [ + { + "text": "euler141() should return 878454337159.", + "testString": "assert.strictEqual(euler141(), 878454337159, 'euler141() should return 878454337159.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A positive integer, n, is divided by d and the quotient and remainder are q and r respectively. In addition d, q, and r are consecutive positive integer terms in a geometric sequence, but not necessarily in that order.", + "For example, 58 divided by 6 has quotient 9 and remainder 4. It can also be seen that 4, 6, 9 are consecutive terms in a geometric sequence (common ratio 3/2).", + "We will call such numbers, n, progressive.", + "Some progressive numbers, such as 9 and 10404 = 1022, happen to also be perfect squares. The sum of all progressive perfect squares below one hundred thousand is 124657.", + "Find the sum of all progressive perfect squares below one trillion (1012)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler141() {", + " // Good luck!", + " return true;", + "}", + "", + "euler141();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3fa1000cf542c50ff0d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 142: Perfect Square Collection", + "tests": [ + { + "text": "euler142() should return 1006193.", + "testString": "assert.strictEqual(euler142(), 1006193, 'euler142() should return 1006193.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Find the smallest x + y + z with integers x > y > z > 0 such that x + y, x − y, x + z, x − z, y + z, y − z are all perfect squares." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler142() {", + " // Good luck!", + " return true;", + "}", + "", + "euler142();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3fc1000cf542c50ff0e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 143: Investigating the Torricelli point of a triangle", + "tests": [ + { + "text": "euler143() should return 30758397.", + "testString": "assert.strictEqual(euler143(), 30758397, 'euler143() should return 30758397.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let ABC be a triangle with all interior angles being less than 120 degrees. Let X be any point inside the triangle and let XA = p, XC = q, and XB = r.", + "Fermat challenged Torricelli to find the position of X such that p + q + r was minimised.", + "Torricelli was able to prove that if equilateral triangles AOB, BNC and AMC are constructed on each side of triangle ABC, the circumscribed circles of AOB, BNC, and AMC will intersect at a single point, T, inside the triangle. Moreover he proved that T, called the Torricelli/Fermat point, minimises p + q + r. Even more remarkable, it can be shown that when the sum is minimised, AN = BM = CO = p + q + r and that AN, BM and CO also intersect at T.", + "", + "If the sum is minimised and a, b, c, p, q and r are all positive integers we shall call triangle ABC a Torricelli triangle. For example, a = 399, b = 455, c = 511 is an example of a Torricelli triangle, with p + q + r = 784.", + "Find the sum of all distinct values of p + q + r ≤ 120000 for Torricelli triangles." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler143() {", + " // Good luck!", + " return true;", + "}", + "", + "euler143();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3fc1000cf542c50ff0f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 144: Investigating multiple reflections of a laser beam", + "tests": [ + { + "text": "euler144() should return 354.", + "testString": "assert.strictEqual(euler144(), 354, 'euler144() should return 354.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In laser physics, a \"white cell\" is a mirror system that acts as a delay line for the laser beam. The beam enters the cell, bounces around on the mirrors, and eventually works its way back out.", + "The specific white cell we will be considering is an ellipse with the equation 4x2 + y2 = 100", + "The section corresponding to −0.01 ≤ x ≤ +0.01 at the top is missing, allowing the light to enter and exit through the hole.", + "", + "The light beam in this problem starts at the point (0.0,10.1) just outside the white cell, and the beam first impacts the mirror at (1.4,-9.6).", + "Each time the laser beam hits the surface of the ellipse, it follows the usual law of reflection \"angle of incidence equals angle of reflection.\" That is, both the incident and reflected beams make the same angle with the normal line at the point of incidence.", + "In the figure on the left, the red line shows the first two points of contact between the laser beam and the wall of the white cell; the blue line shows the line tangent to the ellipse at the point of incidence of the first bounce.The slope m of the tangent line at any point (x,y) of the given ellipse is: m = −4x/yThe normal line is perpendicular to this tangent line at the point of incidence.", + "The animation on the right shows the first 10 reflections of the beam.", + "", + "How many times does the beam hit the internal surface of the white cell before exiting?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler144() {", + " // Good luck!", + " return true;", + "}", + "", + "euler144();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3fd1000cf542c50ff10", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 145: How many reversible numbers are there below one-billion?", + "tests": [ + { + "text": "euler145() should return 608720.", + "testString": "assert.strictEqual(euler145(), 608720, 'euler145() should return 608720.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Some positive integers n have the property that the sum [ n + reverse(n) ] consists entirely of odd (decimal) digits. For instance, 36 + 63 = 99 and 409 + 904 = 1313. We will call such numbers reversible; so 36, 63, 409, and 904 are reversible. Leading zeroes are not allowed in either n or reverse(n).", + "", + "There are 120 reversible numbers below one-thousand.", + "", + "How many reversible numbers are there below one-billion (109)?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler145() {", + " // Good luck!", + " return true;", + "}", + "", + "euler145();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3fe1000cf542c50ff11", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 146: Investigating a Prime Pattern", + "tests": [ + { + "text": "euler146() should return 676333270.", + "testString": "assert.strictEqual(euler146(), 676333270, 'euler146() should return 676333270.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The smallest positive integer n for which the numbers n2+1, n2+3, n2+7, n2+9, n2+13, and n2+27 are consecutive primes is 10. The sum of all such integers n below one-million is 1242490.", + "", + "What is the sum of all such integers n below 150 million?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler146() {", + " // Good luck!", + " return true;", + "}", + "", + "euler146();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f3ff1000cf542c50ff12", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 147: Rectangles in cross-hatched grids", + "tests": [ + { + "text": "euler147() should return 846910284.", + "testString": "assert.strictEqual(euler147(), 846910284, 'euler147() should return 846910284.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In a 3x2 cross-hatched grid, a total of 37 different rectangles could be situated within that grid as indicated in the sketch.", + "", + "There are 5 grids smaller than 3x2, vertical and horizontal dimensions being important, i.e. 1x1, 2x1, 3x1, 1x2 and 2x2. If each of them is cross-hatched, the following number of different rectangles could be situated within those smaller grids:", + "1x1: 1", + "2x1: 4", + "3x1: 8", + "1x2: 4", + "2x2: 18", + "", + "Adding those to the 37 of the 3x2 grid, a total of 72 different rectangles could be situated within 3x2 and smaller grids.", + "", + "How many different rectangles could be situated within 47x43 and smaller grids?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler147() {", + " // Good luck!", + " return true;", + "}", + "", + "euler147();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4021000cf542c50ff14", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 148: Exploring Pascal's triangle", + "tests": [ + { + "text": "euler148() should return 2129970655314432.", + "testString": "assert.strictEqual(euler148(), 2129970655314432, 'euler148() should return 2129970655314432.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We can easily verify that none of the entries in the first seven rows of Pascal's triangle are divisible by 7:", + " ", + " ", + " ", + " ", + " ", + " ", + " 1", + " ", + " ", + " ", + " ", + " ", + " 1", + " ", + " 1", + " ", + " ", + " ", + " ", + " 1", + " ", + " 2", + " ", + " 1", + " ", + " ", + " ", + " 1", + " ", + " 3", + " ", + " 3", + " ", + " 1", + " ", + " ", + " 1", + " ", + " 4", + " ", + " 6", + " ", + " 4", + " ", + " 1", + " ", + " 1", + " ", + " 5", + " ", + "10", + " ", + "10", + " ", + " 5", + " ", + " 1", + "1", + " ", + " 6", + " ", + "15", + " ", + "20", + " ", + "15", + " ", + " 6", + " ", + " 1", + "However, if we check the first one hundred rows, we will find that only 2361 of the 5050 entries are not divisible by 7.", + "", + "Find the number of entries which are not divisible by 7 in the first one billion (109) rows of Pascal's triangle." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler148() {", + " // Good luck!", + " return true;", + "}", + "", + "euler148();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4021000cf542c50ff13", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 149: Searching for a maximum-sum subsequence", + "tests": [ + { + "text": "euler149() should return 52852124.", + "testString": "assert.strictEqual(euler149(), 52852124, 'euler149() should return 52852124.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Looking at the table below, it is easy to verify that the maximum possible sum of adjacent numbers in any direction (horizontal, vertical, diagonal or anti-diagonal) is 16 (= 8 + 7 + 1).", + "", + "", + "−25329−6513273−18−4  8", + "", + "Now, let us repeat the search, but on a much larger scale:", + "", + "First, generate four million pseudo-random numbers using a specific form of what is known as a \"Lagged Fibonacci Generator\":", + "", + "For 1 ≤ k ≤ 55, sk = [100003 − 200003k + 300007k3] (modulo 1000000) − 500000.", + "For 56 ≤ k ≤ 4000000, sk = [sk−24 + sk−55 + 1000000] (modulo 1000000) − 500000.", + "", + "Thus, s10 = −393027 and s100 = 86613.", + "", + "The terms of s are then arranged in a 2000×2000 table, using the first 2000 numbers to fill the first row (sequentially), the next 2000 numbers to fill the second row, and so on.", + "", + "Finally, find the greatest sum of (any number of) adjacent entries in any direction (horizontal, vertical, diagonal or anti-diagonal)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler149() {", + " // Good luck!", + " return true;", + "}", + "", + "euler149();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4031000cf542c50ff15", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 150: Searching a triangular array for a sub-triangle having minimum-sum", + "tests": [ + { + "text": "euler150() should return -271248680.", + "testString": "assert.strictEqual(euler150(), -271248680, 'euler150() should return -271248680.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In a triangular array of positive and negative integers, we wish to find a sub-triangle such that the sum of the numbers it contains is the smallest possible.", + "In the example below, it can be easily verified that the marked triangle satisfies this condition having a sum of −42.", + "", + "", + "We wish to make such a triangular array with one thousand rows, so we generate 500500 pseudo-random numbers sk in the range ±219, using a type of random number generator (known as a Linear Congruential Generator) as follows:", + "t := 0", + "", + "for k = 1 up to k = 500500:", + "", + "    t := (615949*t + 797807) modulo 220", + "    sk := t−219", + "Thus: s1 = 273519, s2 = −153582, s3 = 450905 etc", + "Our triangular array is then formed using the pseudo-random numbers thus:", + "", + "s1", + "s2  s3", + "s4  s5  s6  ", + "", + "s7  s8  s9  s10", + "...", + "", + "Sub-triangles can start at any element of the array and extend down as far as we like (taking-in the two elements directly below it from the next row, the three elements directly below from the row after that, and so on).", + "", + "The \"sum of a sub-triangle\" is defined as the sum of all the elements it contains.", + "", + "Find the smallest possible sub-triangle sum." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler150() {", + " // Good luck!", + " return true;", + "}", + "", + "euler150();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4031000cf542c50ff16", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 151: Paper sheets of standard sizes: an expected-value problem", + "tests": [ + { + "text": "euler151() should return 0.464399.", + "testString": "assert.strictEqual(euler151(), 0.464399, 'euler151() should return 0.464399.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A printing shop runs 16 batches (jobs) every week and each batch requires a sheet of special colour-proofing paper of size A5.", + "Every Monday morning, the foreman opens a new envelope, containing a large sheet of the special paper with size A1.", + "He proceeds to cut it in half, thus getting two sheets of size A2. Then he cuts one of them in half to get two sheets of size A3 and so on until he obtains the A5-size sheet needed for the first batch of the week.", + "All the unused sheets are placed back in the envelope.", + "", + "At the beginning of each subsequent batch, he takes from the envelope one sheet of paper at random. If it is of size A5, he uses it. If it is larger, he repeats the 'cut-in-half' procedure until he has what he needs and any remaining sheets are always placed back in the envelope.", + "Excluding the first and last batch of the week, find the expected number of times (during each week) that the foreman finds a single sheet of paper in the envelope.", + "Give your answer rounded to six decimal places using the format x.xxxxxx ." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler151() {", + " // Good luck!", + " return true;", + "}", + "", + "euler151();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4041000cf542c50ff17", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 152: Writing 1/2 as a sum of inverse squares", + "tests": [ + { + "text": "euler152() should return 301.", + "testString": "assert.strictEqual(euler152(), 301, 'euler152() should return 301.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "There are several ways to write the number 1/2 as a sum of inverse squares using distinct integers.", + "For instance, the numbers {2,3,4,5,7,12,15,20,28,35} can be used:", + "", + "In fact, only using integers between 2 and 45 inclusive, there are exactly three ways to do it, the remaining two being: {2,3,4,6,7,9,10,20,28,35,36,45} and {2,3,4,6,7,9,12,15,28,30,35,36,45}.", + "How many ways are there to write the number 1/2 as a sum of inverse squares using distinct integers between 2 and 80 inclusive?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler152() {", + " // Good luck!", + " return true;", + "}", + "", + "euler152();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4051000cf542c50ff18", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 153: Investigating Gaussian Integers", + "tests": [ + { + "text": "euler153() should return 17971254122360636.", + "testString": "assert.strictEqual(euler153(), 17971254122360636, 'euler153() should return 17971254122360636.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "As we all know the equation x2=-1 has no solutions for real x.", + "", + "If we however introduce the imaginary number i this equation has two solutions: x=i and x=-i.", + "", + "If we go a step further the equation (x-3)2=-4 has two complex solutions: x=3+2i and x=3-2i.", + "x=3+2i and x=3-2i are called each others' complex conjugate.", + "", + "Numbers of the form a+bi are called complex numbers.", + "", + "In general a+bi and a−bi are each other's complex conjugate.", + "A Gaussian Integer is a complex number a+bi such that both a and b are integers.", + "", + "The regular integers are also Gaussian integers (with b=0).", + "", + "To distinguish them from Gaussian integers with b ≠ 0 we call such integers \"rational integers.\"", + "", + "A Gaussian integer is called a divisor of a rational integer n if the result is also a Gaussian integer.", + "", + "If for example we divide 5 by 1+2i we can simplify in the following manner:", + "", + "Multiply numerator and denominator by the complex conjugate of 1+2i: 1−2i.", + "", + "The result is ", + ".", + "", + "So 1+2i is a divisor of 5.", + "", + "Note that 1+i is not a divisor of 5 because .", + "", + "Note also that if the Gaussian Integer (a+bi) is a divisor of a rational integer n, then its complex conjugate (a−bi) is also a divisor of n.", + "In fact, 5 has six divisors such that the real part is positive: {1, 1 + 2i, 1 − 2i, 2 + i, 2 − i, 5}.", + "", + "The following is a table of all of the divisors for the first five positive rational integers:", + "", + "n Gaussian integer divisors", + "with positive real partSum s(n) of these", + "", + "divisors111", + "21, 1+i, 1-i, 25", + "31, 34", + "41, 1+i, 1-i, 2, 2+2i, 2-2i,413", + "51, 1+2i, 1-2i, 2+i, 2-i, 512", + "For divisors with positive real parts, then, we have: .", + "For 1 ≤ n ≤ 105, ∑ s(n)=17924657155.", + "What is ∑ s(n) for 1 ≤ n ≤ 108?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler153() {", + " // Good luck!", + " return true;", + "}", + "", + "euler153();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4071000cf542c50ff19", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 154: Exploring Pascal's pyramid", + "tests": [ + { + "text": "euler154() should return 479742450.", + "testString": "assert.strictEqual(euler154(), 479742450, 'euler154() should return 479742450.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A triangular pyramid is constructed using spherical balls so that each ball rests on exactly three balls of the next lower level.", + "", + "Then, we calculate the number of paths leading from the apex to each position:", + "A path starts at the apex and progresses downwards to any of the three spheres directly below the current position.", + "Consequently, the number of paths to reach a certain position is the sum of the numbers immediately above it (depending on the position, there are up to three numbers above it).", + "The result is Pascal's pyramid and the numbers at each level n are the coefficients of the trinomial expansion ", + "(x + y + z)n.", + "How many coefficients in the expansion of (x + y + z)200000 are multiples of 1012?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler154() {", + " // Good luck!", + " return true;", + "}", + "", + "euler154();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4081000cf542c50ff1a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 155: Counting Capacitor Circuits", + "tests": [ + { + "text": "euler155() should return 3857447.", + "testString": "assert.strictEqual(euler155(), 3857447, 'euler155() should return 3857447.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An electric circuit uses exclusively identical capacitors of the same value C.", + "", + "The capacitors can be connected in series or in parallel to form sub-units, which can then be connected in series or in parallel with other capacitors or other sub-units to form larger sub-units, and so on up to a final circuit.", + "Using this simple procedure and up to n identical capacitors, we can make circuits having a range of different total capacitances. For example, using up to n=3 capacitors of 60 F each, we can obtain the following 7 distinct total capacitance values: ", + "", + "If we denote by D(n) the number of distinct total capacitance values we can obtain when using up to n equal-valued capacitors and the simple procedure described above, we have: D(1)=1, D(2)=3, D(3)=7 ...", + "Find D(18).", + "Reminder : When connecting capacitors C1, C2 etc in parallel, the total capacitance is CT = C1 + C2 +...,", + "", + "whereas when connecting them in series, the overall capacitance is given by:" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler155() {", + " // Good luck!", + " return true;", + "}", + "", + "euler155();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4091000cf542c50ff1b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 156: Counting Digits", + "tests": [ + { + "text": "euler156() should return 21295121502550.", + "testString": "assert.strictEqual(euler156(), 21295121502550, 'euler156() should return 21295121502550.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Starting from zero the natural numbers are written down in base 10 like this:", + "", + "0 1 2 3 4 5 6 7 8 9 10 11 12....", + "", + "Consider the digit d=1. After we write down each number n, we will update the number of ones that have occurred and call this number f(n,1). The first values for f(n,1), then, are as follows:", + "", + "nf(n,1)", + "00", + "11", + "21", + "31", + "41", + "51", + "61", + "71", + "81", + "91", + "102", + "114", + "125", + "", + "Note that f(n,1) never equals 3.", + "", + "So the first two solutions of the equation f(n,1)=n are n=0 and n=1. The next solution is n=199981.", + "In the same manner the function f(n,d) gives the total number of digits d that have been written down after the number n has been written.", + "", + "In fact, for every digit d ≠ 0, 0 is the first solution of the equation f(n,d)=n.", + "Let s(d) be the sum of all the solutions for which f(n,d)=n.", + "", + "You are given that s(1)=22786974071.", + "Find ∑ s(d) for 1 ≤ d ≤ 9.", + "Note: if, for some n, f(n,d)=n", + " for more than one value of d this value of n is counted again for every value of d for which f(n,d)=n." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler156() {", + " // Good luck!", + " return true;", + "}", + "", + "euler156();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4091000cf542c50ff1c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 157: Solving the diophantine equation 1/a+1/b= p/10n", + "tests": [ + { + "text": "euler157() should return 53490.", + "testString": "assert.strictEqual(euler157(), 53490, 'euler157() should return 53490.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the diophantine equation 1/a+1/b= p/10n with a, b, p, n positive integers and a ≤ b.", + "For n=1 this equation has 20 solutions that are listed below:", + "1/1+1/1=20/10", + "1/1+1/2=15/10", + "1/1+1/5=12/10", + "1/1+1/10=11/10", + "1/2+1/2=10/10", + "1/2+1/5=7/10", + "1/2+1/10=6/10", + "1/3+1/6=5/10", + "1/3+1/15=4/10", + "1/4+1/4=5/10", + "1/4+1/20=3/10", + "1/5+1/5=4/10", + "1/5+1/10=3/10", + "1/6+1/30=2/10", + "1/10+1/10=2/10", + "1/11+1/110=1/10", + "1/12+1/60=1/10", + "1/14+1/35=1/10", + "1/15+1/30=1/10", + "1/20+1/20=1/10", + "How many solutions has this equation for 1 ≤ n ≤ 9?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler157() {", + " // Good luck!", + " return true;", + "}", + "", + "euler157();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f40a1000cf542c50ff1d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 158: Exploring strings for which only one character comes lexicographically after its neighbour to the left", + "tests": [ + { + "text": "euler158() should return 409511334375.", + "testString": "assert.strictEqual(euler158(), 409511334375, 'euler158() should return 409511334375.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Taking three different letters from the 26 letters of the alphabet, character strings of length three can be formed.", + "Examples are 'abc', 'hat' and 'zyx'.", + "When we study these three examples we see that for 'abc' two characters come lexicographically after its neighbour to the left. ", + "For 'hat' there is exactly one character that comes lexicographically after its neighbour to the left. For 'zyx' there are zero characters that come lexicographically after its neighbour to the left.", + "In all there are 10400 strings of length 3 for which exactly one character comes lexicographically after its neighbour to the left.", + "We now consider strings of n ≤ 26 different characters from the alphabet. ", + "For every n, p(n) is the number of strings of length n for which exactly one character comes lexicographically after its neighbour to the left. ", + "What is the maximum value of p(n)?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler158() {", + " // Good luck!", + " return true;", + "}", + "", + "euler158();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f40c1000cf542c50ff1e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 159: Digital root sums of factorisations", + "tests": [ + { + "text": "euler159() should return 14489159.", + "testString": "assert.strictEqual(euler159(), 14489159, 'euler159() should return 14489159.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A composite number can be factored many different ways. ", + "For instance, not including multiplication by one, 24 can be factored in 7 distinct ways:", + "", + "24 = 2x2x2x3", + "24 = 2x3x4", + "24 = 2x2x6", + "24 = 4x6", + "24 = 3x8", + "24 = 2x12", + "24 = 24", + "", + "Recall that the digital root of a number, in base 10, is found by adding together the digits of that number, ", + "and repeating that process until a number is arrived at that is less than 10. ", + "Thus the digital root of 467 is 8.", + "We shall call a Digital Root Sum (DRS) the sum of the digital roots of the individual factors of our number.", + " The chart below demonstrates all of the DRS values for 24.", + "FactorisationDigital Root Sum2x2x2x3", + "92x3x4", + "92x2x6", + "104x6", + "103x8", + "112x12", + "524", + "6The maximum Digital Root Sum of 24 is 11.", + "The function mdrs(n) gives the maximum Digital Root Sum of n. So mdrs(24)=11.", + "Find ∑mdrs(n) for 1 < n < 1,000,000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler159() {", + " // Good luck!", + " return true;", + "}", + "", + "euler159();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f40d1000cf542c50ff1f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 160: Factorial trailing digits", + "tests": [ + { + "text": "euler160() should return 16576.", + "testString": "assert.strictEqual(euler160(), 16576, 'euler160() should return 16576.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For any N, let f(N) be the last five digits before the trailing zeroes in N!.", + "For example,", + "9! = 362880 so f(9)=36288", + "10! = 3628800 so f(10)=36288", + "20! = 2432902008176640000 so f(20)=17664", + "Find f(1,000,000,000,000)" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler160() {", + " // Good luck!", + " return true;", + "}", + "", + "euler160();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f40d1000cf542c50ff20", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 161: Triominoes", + "tests": [ + { + "text": "euler161() should return 20574308184277972.", + "testString": "assert.strictEqual(euler161(), 20574308184277972, 'euler161() should return 20574308184277972.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A triomino is a shape consisting of three squares joined via the edges.", + "There are two basic forms:", + "", + "", + "", + "If all possible orientations are taken into account there are six:", + "", + "", + "", + "Any n by m grid for which nxm is divisible by 3 can be tiled with triominoes.", + "If we consider tilings that can be obtained by reflection or rotation from another tiling as different there are 41 ways a 2 by 9 grid can be tiled with triominoes:", + "", + "", + "", + "In how many ways can a 9 by 12 grid be tiled in this way by triominoes?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler161() {", + " // Good luck!", + " return true;", + "}", + "", + "euler161();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f40e1000cf542c50ff21", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 162: Hexadecimal numbers", + "tests": [ + { + "text": "euler162() should return 3D58725572C62302.", + "testString": "assert.strictEqual(euler162(), 3D58725572C62302, 'euler162() should return 3D58725572C62302.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In the hexadecimal number system numbers are represented using 16 different digits:", + "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F", + "The hexadecimal number AF when written in the decimal number system equals 10x16+15=175.", + "In the 3-digit hexadecimal numbers 10A, 1A0, A10, and A01 the digits 0,1 and A are all present.", + "Like numbers written in base ten we write hexadecimal numbers without leading zeroes.", + "How many hexadecimal numbers containing at most sixteen hexadecimal digits exist with all of the digits 0,1, and A present at least once?", + "Give your answer as a hexadecimal number.", + "(A,B,C,D,E and F in upper case, without any leading or trailing code that marks the number as hexadecimal and without leading zeroes , e.g. 1A3F and not: 1a3f and not 0x1a3f and not $1A3F and not #1A3F and not 0000001A3F)" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler162() {", + " // Good luck!", + " return true;", + "}", + "", + "euler162();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f40f1000cf542c50ff22", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 163: Cross-hatched triangles", + "tests": [ + { + "text": "euler163() should return 343047.", + "testString": "assert.strictEqual(euler163(), 343047, 'euler163() should return 343047.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider an equilateral triangle in which straight lines are drawn from each vertex to the middle of the opposite side, such as in the size 1 triangle in the sketch below.", + "", + "Sixteen triangles of either different shape or size or orientation or location can now be observed in that triangle. Using size 1 triangles as building blocks, larger triangles can be formed, such as the size 2 triangle in the above sketch. One-hundred and four triangles of either different shape or size or orientation or location can now be observed in that size 2 triangle.", + "It can be observed that the size 2 triangle contains 4 size 1 triangle building blocks. A size 3 triangle would contain 9 size 1 triangle building blocks and a size n triangle would thus contain n2 size 1 triangle building blocks.", + "If we denote T(n) as the number of triangles present in a triangle of size n, then", + "T(1) = 16", + "T(2) = 104", + "Find T(36)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler163() {", + " // Good luck!", + " return true;", + "}", + "", + "euler163();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4111000cf542c50ff23", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 164: Numbers for which no three consecutive digits have a sum greater than a given value", + "tests": [ + { + "text": "euler164() should return 378158756814587.", + "testString": "assert.strictEqual(euler164(), 378158756814587, 'euler164() should return 378158756814587.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "How many 20 digit numbers n (without any leading zero) exist such that no three consecutive digits of n have a sum greater than 9?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler164() {", + " // Good luck!", + " return true;", + "}", + "", + "euler164();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4111000cf542c50ff24", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 165: Intersections", + "tests": [ + { + "text": "euler165() should return 2868868.", + "testString": "assert.strictEqual(euler165(), 2868868, 'euler165() should return 2868868.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A segment is uniquely defined by its two endpoints. By considering two line segments in plane geometry there are three possibilities: ", + "the segments have zero points, one point, or infinitely many points in common.", + "Moreover when two segments have exactly one point in common it might be the case that that common point is an endpoint of either one of the segments or of both. If a common point of two segments is not an endpoint of either of the segments it is an interior point of both segments.", + "We will call a common point T of two segments L1 and L2 a true intersection point of L1 and L2 if T is the only common point of L1 and L2 and T is an interior point of both segments.", + "", + "Consider the three segments L1, L2, and L3:", + "L1: (27, 44) to (12, 32)", + "L2: (46, 53) to (17, 62)", + "L3: (46, 70) to (22, 40)", + "It can be verified that line segments L2 and L3 have a true intersection point. We note that as the one of the end points of L3: (22,40) lies on L1 this is not considered to be a true point of intersection. L1 and L2 have no common point. So among the three line segments, we find one true intersection point.", + "Now let us do the same for 5000 line segments. To this end, we generate 20000 numbers using the so-called \"Blum Blum Shub\" pseudo-random number generator.", + "s0 = 290797", + "sn+1 = sn×sn (modulo 50515093)", + "tn = sn (modulo 500)", + "To create each line segment, we use four consecutive numbers tn. That is, the first line segment is given by:", + "(t1, t2) to (t3, t4)", + "The first four numbers computed according to the above generator should be: 27, 144, 12 and 232. The first segment would thus be (27,144) to (12,232).", + "How many distinct true intersection points are found among the 5000 line segments?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler165() {", + " // Good luck!", + " return true;", + "}", + "", + "euler165();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4131000cf542c50ff25", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 166: Criss Cross", + "tests": [ + { + "text": "euler166() should return 7130034.", + "testString": "assert.strictEqual(euler166(), 7130034, 'euler166() should return 7130034.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A 4x4 grid is filled with digits d, 0 ≤ d ≤ 9.", + "", + "It can be seen that in the grid", + "", + "", + "6 3 3 0", + "5 0 4 3", + "0 7 1 4", + "1 2 4 5", + "", + "the sum of each row and each column has the value 12. Moreover the sum of each diagonal is also 12.", + "", + "In how many ways can you fill a 4x4 grid with the digits d, 0 ≤ d ≤ 9 so that each row, each column, and both diagonals have the same sum?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler166() {", + " // Good luck!", + " return true;", + "}", + "", + "euler166();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4141000cf542c50ff26", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 167: Investigating Ulam sequences", + "tests": [ + { + "text": "euler167() should return 3916160068885.", + "testString": "assert.strictEqual(euler167(), 3916160068885, 'euler167() should return 3916160068885.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For two positive integers a and b, the Ulam sequence U(a,b) is defined by U(a,b)1 = a, U(a,b)2 = b and for k > 2,", + "U(a,b)k is the smallest integer greater than U(a,b)(k-1) which can be written in exactly one way as the sum of two distinct previous members of U(a,b).", + "For example, the sequence U(1,2) begins with", + "1, 2, 3 = 1 + 2, 4 = 1 + 3, 6 = 2 + 4, 8 = 2 + 6, 11 = 3 + 8;", + "5 does not belong to it because 5 = 1 + 4 = 2 + 3 has two representations as the sum of two previous members, likewise 7 = 1 + 6 = 3 + 4.", + "Find ∑U(2,2n+1)k for 2 ≤ n ≤10, where k = 1011." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler167() {", + " // Good luck!", + " return true;", + "}", + "", + "euler167();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4151000cf542c50ff27", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 168: Number Rotations", + "tests": [ + { + "text": "euler168() should return 59206.", + "testString": "assert.strictEqual(euler168(), 59206, 'euler168() should return 59206.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the number 142857. We can right-rotate this number by moving the last digit (7) to the front of it, giving us 714285.", + "It can be verified that 714285=5×142857.", + "This demonstrates an unusual property of 142857: it is a divisor of its right-rotation.", + "Find the last 5 digits of the sum of all integers n, 10 < n < 10100, that have this property." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler168() {", + " // Good luck!", + " return true;", + "}", + "", + "euler168();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4151000cf542c50ff28", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 169: Exploring the number of different ways a number can be expressed as a sum of powers of 2", + "tests": [ + { + "text": "euler169() should return 178653872807.", + "testString": "assert.strictEqual(euler169(), 178653872807, 'euler169() should return 178653872807.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Define f(0)=1 and f(n) to be the number of different ways n can be expressed as a sum of integer powers of 2 using each power no more than twice.", + "For example, f(10)=5 since there are five different ways to express 10:", + "1 + 1 + 8", + "1 + 1 + 4 + 41 + 1 + 2 + 2 + 4", + "2 + 4 + 4", + "2 + 8", + "What is f(1025)?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler169() {", + " // Good luck!", + " return true;", + "}", + "", + "euler169();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4161000cf542c50ff29", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 170: Find the largest 0 to 9 pandigital that can be formed by concatenating products", + "tests": [ + { + "text": "euler170() should return 9857164023.", + "testString": "assert.strictEqual(euler170(), 9857164023, 'euler170() should return 9857164023.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Take the number 6 and multiply it by each of 1273 and 9854:", + "", + "6 × 1273 = 7638", + "6 × 9854 = 59124", + "", + "By concatenating these products we get the 1 to 9 pandigital 763859124. We will call 763859124 the \"concatenated product of 6 and (1273,9854)\". Notice too, that the concatenation of the input numbers, 612739854, is also 1 to 9 pandigital.", + "", + "The same can be done for 0 to 9 pandigital numbers.", + "", + "What is the largest 0 to 9 pandigital 10-digit concatenated product of an integer with two or more other integers, such that the concatenation of the input numbers is also a 0 to 9 pandigital 10-digit number?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler170() {", + " // Good luck!", + " return true;", + "}", + "", + "euler170();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4181000cf542c50ff2a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 171: Finding numbers for which the sum of the squares of the digits is a square", + "tests": [ + { + "text": "euler171() should return 142989277.", + "testString": "assert.strictEqual(euler171(), 142989277, 'euler171() should return 142989277.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a positive integer n, let f(n) be the sum of the squares of the digits (in base 10) of n, e.g.", + "f(3) = 32 = 9,", + "f(25) = 22 + 52 = 4 + 25 = 29,", + "f(442) = 42 + 42 + 22 = 16 + 16 + 4 = 36", + "Find the last nine digits of the sum of all n, 0 < n < 1020, such that f(n) is a perfect square." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler171() {", + " // Good luck!", + " return true;", + "}", + "", + "euler171();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4181000cf542c50ff2b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 172: Investigating numbers with few repeated digits", + "tests": [ + { + "text": "euler172() should return 227485267000992000.", + "testString": "assert.strictEqual(euler172(), 227485267000992000, 'euler172() should return 227485267000992000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "How many 18-digit numbers n (without leading zeros) are there such that no digit occurs more than three times in n?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler172() {", + " // Good luck!", + " return true;", + "}", + "", + "euler172();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f41a1000cf542c50ff2c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 173: Using up to one million tiles how many different \"hollow\" square laminae can be formed?", + "tests": [ + { + "text": "euler173() should return 1572729.", + "testString": "assert.strictEqual(euler173(), 1572729, 'euler173() should return 1572729.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We shall define a square lamina to be a square outline with a square \"hole\" so that the shape possesses vertical and horizontal symmetry. For example, using exactly thirty-two square tiles we can form two different square laminae:", + "", + "", + "With one-hundred tiles, and not necessarily using all of the tiles at one time, it is possible to form forty-one different square laminae.", + "Using up to one million tiles how many different square laminae can be formed?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler173() {", + " // Good luck!", + " return true;", + "}", + "", + "euler173();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f41a1000cf542c50ff2d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 174: Counting the number of \"hollow\" square laminae that can form one, two, three, ... distinct arrangements", + "tests": [ + { + "text": "euler174() should return 209566.", + "testString": "assert.strictEqual(euler174(), 209566, 'euler174() should return 209566.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We shall define a square lamina to be a square outline with a square \"hole\" so that the shape possesses vertical and horizontal symmetry.", + "Given eight tiles it is possible to form a lamina in only one way: 3x3 square with a 1x1 hole in the middle. However, using thirty-two tiles it is possible to form two distinct laminae.", + "", + "", + "If t represents the number of tiles used, we shall say that t = 8 is type L(1) and t = 32 is type L(2).", + "Let N(n) be the number of t ≤ 1000000 such that t is type L(n); for example, N(15) = 832.", + "What is ∑ N(n) for 1 ≤ n ≤ 10?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler174() {", + " // Good luck!", + " return true;", + "}", + "", + "euler174();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f41c1000cf542c50ff2e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 175: Fractions involving the number of different ways a number can be expressed as a sum of powers of 2", + "tests": [ + { + "text": "euler175() should return 1, 13717420, 8.", + "testString": "assert.strictEqual(euler175(), 1, 13717420, 8, 'euler175() should return 1, 13717420, 8.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Define f(0)=1 and f(n) to be the number of ways to write n as a sum of powers of 2 where no power occurs more than twice. ", + "", + "For example, f(10)=5 since there are five different ways to express 10:10 = 8+2 = 8+1+1 = 4+4+2 = 4+2+2+1+1 = 4+4+1+1", + "", + "It can be shown that for every fraction p/q (p>0, q>0) there exists at least one integer n such that f(n)/f(n-1)=p/q.", + "For instance, the smallest n for which f(n)/f(n-1)=13/17 is 241.", + "The binary expansion of 241 is 11110001.", + "Reading this binary number from the most significant bit to the least significant bit there are 4 one's, 3 zeroes and 1 one. We shall call the string 4,3,1 the Shortened Binary Expansion of 241.", + "Find the Shortened Binary Expansion of the smallest n for which f(n)/f(n-1)=123456789/987654321.", + "Give your answer as comma separated integers, without any whitespaces." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler175() {", + " // Good luck!", + " return true;", + "}", + "", + "euler175();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f41c1000cf542c50ff2f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 176: Right-angled triangles that share a cathetus", + "tests": [ + { + "text": "euler176() should return 96818198400000.", + "testString": "assert.strictEqual(euler176(), 96818198400000, 'euler176() should return 96818198400000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The four right-angled triangles with sides (9,12,15), (12,16,20), (5,12,13) and (12,35,37) all have one of the shorter sides (catheti) equal to 12. It can be shown that no other integer sided right-angled triangle exists with one of the catheti equal to 12.", + "Find the smallest integer that can be the length of a cathetus of exactly 47547 different integer sided right-angled triangles." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler176() {", + " // Good luck!", + " return true;", + "}", + "", + "euler176();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f41e1000cf542c50ff30", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 177: Integer angled Quadrilaterals", + "tests": [ + { + "text": "euler177() should return 129325.", + "testString": "assert.strictEqual(euler177(), 129325, 'euler177() should return 129325.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let ABCD be a convex quadrilateral, with diagonals AC and BD. At each vertex the diagonal makes an angle with each of the two sides, creating eight corner angles.", + "", + "For example, at vertex A, the two angles are CAD, CAB.", + "We call such a quadrilateral for which all eight corner angles have integer values when measured in degrees an \"integer angled quadrilateral\". An example of an integer angled quadrilateral is a square, where all eight corner angles are 45°. Another example is given by DAC = 20°, BAC = 60°, ABD = 50°, CBD = 30°, BCA = 40°, DCA = 30°, CDB = 80°, ADB = 50°.", + "What is the total number of non-similar integer angled quadrilaterals?", + "Note: In your calculations you may assume that a calculated angle is integral if it is within a tolerance of 10-9 of an integer value." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler177() {", + " // Good luck!", + " return true;", + "}", + "", + "euler177();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f41e1000cf542c50ff31", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 178: Step Numbers", + "tests": [ + { + "text": "euler178() should return 126461847755.", + "testString": "assert.strictEqual(euler178(), 126461847755, 'euler178() should return 126461847755.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the number 45656. ", + "It can be seen that each pair of consecutive digits of 45656 has a difference of one.", + "A number for which every pair of consecutive digits has a difference of one is called a step number.", + "A pandigital number contains every decimal digit from 0 to 9 at least once.", + "", + "How many pandigital step numbers less than 1040 are there?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler178() {", + " // Good luck!", + " return true;", + "}", + "", + "euler178();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f41f1000cf542c50ff32", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 179: Consecutive positive divisors", + "tests": [ + { + "text": "euler179() should return 986262.", + "testString": "assert.strictEqual(euler179(), 986262, 'euler179() should return 986262.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Find the number of integers 1 < n < 107, for which n and n + 1 have the same number of positive divisors. For example, 14 has the positive divisors 1, 2, 7, 14 while 15 has 1, 3, 5, 15." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler179() {", + " // Good luck!", + " return true;", + "}", + "", + "euler179();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4201000cf542c50ff33", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 180: Rational zeros of a function of three variables", + "tests": [ + { + "text": "euler180() should return 285196020571078980.", + "testString": "assert.strictEqual(euler180(), 285196020571078980, 'euler180() should return 285196020571078980.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For any integer n, consider the three functions", + "f1,n(x,y,z) = xn+1 + yn+1 − zn+1f2,n(x,y,z) = (xy + yz + zx)*(xn-1 + yn-1 − zn-1)f3,n(x,y,z) = xyz*(xn-2 + yn-2 − zn-2)", + "and their combination", + "fn(x,y,z) = f1,n(x,y,z) + f2,n(x,y,z) − f3,n(x,y,z)", + "We call (x,y,z) a golden triple of order k if x, y, and z are all rational numbers of the form a / b with", + "0 < a < b ≤ k and there is (at least) one integer n, so that fn(x,y,z) = 0.", + "Let s(x,y,z) = x + y + z.", + "Let t = u / v be the sum of all distinct s(x,y,z) for all golden triples (x,y,z) of order 35. All the s(x,y,z) and t must be in reduced form.", + "Find u + v." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler180() {", + " // Good luck!", + " return true;", + "}", + "", + "euler180();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4231000cf542c50ff34", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 181: Investigating in how many ways objects of two different colours can be grouped", + "tests": [ + { + "text": "euler181() should return 83735848679360670.", + "testString": "assert.strictEqual(euler181(), 83735848679360670, 'euler181() should return 83735848679360670.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Having three black objects B and one white object W they can be grouped in 7 ways like this:", + "(BBBW)(B,BBW)(B,B,BW)(B,B,B,W)", + "(B,BB,W)(BBB,W)(BB,BW)", + "In how many ways can sixty black objects B and forty white objects W be thus grouped?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler181() {", + " // Good luck!", + " return true;", + "}", + "", + "euler181();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4231000cf542c50ff35", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 182: RSA encryption", + "tests": [ + { + "text": "euler182() should return 399788195976.", + "testString": "assert.strictEqual(euler182(), 399788195976, 'euler182() should return 399788195976.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The RSA encryption is based on the following procedure:", + "Generate two distinct primes p and q.Compute n=pq and φ=(p-1)(q-1).", + "Find an integer e, 1euler183() should return 48861552.", + "testString": "assert.strictEqual(euler183(), 48861552, 'euler183() should return 48861552.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let N be a positive integer and let N be split into k equal parts, r = N/k, so that N = r + r + ... + r.", + "Let P be the product of these parts, P = r × r × ... × r = rk.", + "", + "For example, if 11 is split into five equal parts, 11 = 2.2 + 2.2 + 2.2 + 2.2 + 2.2, then P = 2.25 = 51.53632.", + "", + "Let M(N) = Pmax for a given value of N.", + "", + "It turns out that the maximum for N = 11 is found by splitting eleven into four equal parts which leads to Pmax = (11/4)4; that is, M(11) = 14641/256 = 57.19140625, which is a terminating decimal.", + "", + "However, for N = 8 the maximum is achieved by splitting it into three equal parts, so M(8) = 512/27, which is a non-terminating decimal.", + "", + "Let D(N) = N if M(N) is a non-terminating decimal and D(N) = -N if M(N) is a terminating decimal.", + "", + "For example, ΣD(N) for 5 ≤ N ≤ 100 is 2438.", + "", + "Find ΣD(N) for 5 ≤ N ≤ 10000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler183() {", + " // Good luck!", + " return true;", + "}", + "", + "euler183();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4241000cf542c50ff37", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 184: Triangles containing the origin", + "tests": [ + { + "text": "euler184() should return 1725323624056.", + "testString": "assert.strictEqual(euler184(), 1725323624056, 'euler184() should return 1725323624056.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the set Ir of points (x,y) with integer co-ordinates in the interior of the circle with radius r, centered at the origin, i.e. x2 + y2 < r2.", + "For a radius of 2, I2 contains the nine points (0,0), (1,0), (1,1), (0,1), (-1,1), (-1,0), (-1,-1), (0,-1) and (1,-1). There are eight triangles having all three vertices in I2 which contain the origin in the interior. Two of them are shown below, the others are obtained from these by rotation.", + "", + "", + "For a radius of 3, there are 360 triangles containing the origin in the interior and having all vertices in I3 and for I5 the number is 10600.", + "", + "How many triangles are there containing the origin in the interior and having all three vertices in I105?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler184() {", + " // Good luck!", + " return true;", + "}", + "", + "euler184();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4251000cf542c50ff38", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 185: Number Mind", + "tests": [ + { + "text": "euler185() should return 4640261571849533.", + "testString": "assert.strictEqual(euler185(), 4640261571849533, 'euler185() should return 4640261571849533.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The game Number Mind is a variant of the well known game Master Mind.", + "Instead of coloured pegs, you have to guess a secret sequence of digits. After each guess you're only told in how many places you've guessed the correct digit. So, if the sequence was 1234 and you guessed 2036, you'd be told that you have one correct digit; however, you would NOT be told that you also have another digit in the wrong place.", + "", + "For instance, given the following guesses for a 5-digit secret sequence,", + "90342 ;2 correct", + "70794 ;0 correct", + "39458 ;2 correct", + "34109 ;1 correct", + "51545 ;2 correct", + "12531 ;1 correct", + "The correct sequence 39542 is unique.", + "", + "Based on the following guesses,", + "", + "5616185650518293 ;2 correct", + "3847439647293047 ;1 correct", + "5855462940810587 ;3 correct", + "9742855507068353 ;3 correct", + "4296849643607543 ;3 correct", + "3174248439465858 ;1 correct", + "4513559094146117 ;2 correct", + "7890971548908067 ;3 correct", + "8157356344118483 ;1 correct", + "2615250744386899 ;2 correct", + "8690095851526254 ;3 correct", + "6375711915077050 ;1 correct", + "6913859173121360 ;1 correct", + "6442889055042768 ;2 correct", + "2321386104303845 ;0 correct", + "2326509471271448 ;2 correct", + "5251583379644322 ;2 correct", + "1748270476758276 ;3 correct", + "4895722652190306 ;1 correct", + "3041631117224635 ;3 correct", + "1841236454324589 ;3 correct", + "2659862637316867 ;2 correct", + "", + "Find the unique 16-digit secret sequence." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler185() {", + " // Good luck!", + " return true;", + "}", + "", + "euler185();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4281000cf542c50ff39", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 186: Connectedness of a network", + "tests": [ + { + "text": "euler186() should return 2325629.", + "testString": "assert.strictEqual(euler186(), 2325629, 'euler186() should return 2325629.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Here are the records from a busy telephone system with one million users:", + "", + "RecNrCallerCalled120000710005326001835004393600863701497.........", + "The telephone number of the caller and the called number in record n are Caller(n) = S2n-1 and Called(n) = S2n where S1,2,3,... come from the \"Lagged Fibonacci Generator\":", + "", + "For 1 ≤ k ≤ 55, Sk = [100003 - 200003k + 300007k3] (modulo 1000000)", + "For 56 ≤ k, Sk = [Sk-24 + Sk-55] (modulo 1000000)", + "", + "If Caller(n) = Called(n) then the user is assumed to have misdialled and the call fails; otherwise the call is successful.", + "", + "From the start of the records, we say that any pair of users X and Y are friends if X calls Y or vice-versa. Similarly, X is a friend of a friend of Z if X is a friend of Y and Y is a friend of Z; and so on for longer chains.", + "", + "The Prime Minister's phone number is 524287. After how many successful calls, not counting misdials, will 99% of the users (including the PM) be a friend, or a friend of a friend etc., of the Prime Minister?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler186() {", + " // Good luck!", + " return true;", + "}", + "", + "euler186();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4291000cf542c50ff3a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 187: Semiprimes", + "tests": [ + { + "text": "euler187() should return 17427258.", + "testString": "assert.strictEqual(euler187(), 17427258, 'euler187() should return 17427258.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A composite is a number containing at least two prime factors. For example, 15 = 3 × 5; 9 = 3 × 3; 12 = 2 × 2 × 3.", + "", + "There are ten composites below thirty containing precisely two, not necessarily distinct, prime factors:", + "4, 6, 9, 10, 14, 15, 21, 22, 25, 26.", + "", + "How many composite integers, n < 108, have precisely two, not necessarily distinct, prime factors?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler187() {", + " // Good luck!", + " return true;", + "}", + "", + "euler187();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4291000cf542c50ff3b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 188: The hyperexponentiation of a number", + "tests": [ + { + "text": "euler188() should return 95962097.", + "testString": "assert.strictEqual(euler188(), 95962097, 'euler188() should return 95962097.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The hyperexponentiation or tetration of a number a by a positive integer b, denoted by a↑↑b or ba, is recursively defined by:", + "a↑↑1 = a,", + "a↑↑(k+1) = a(a↑↑k).", + "", + "Thus we have e.g. 3↑↑2 = 33 = 27, hence 3↑↑3 = 327 = 7625597484987 and 3↑↑4 is roughly 103.6383346400240996*10^12.", + "Find the last 8 digits of 1777↑↑1855." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler188() {", + " // Good luck!", + " return true;", + "}", + "", + "euler188();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4291000cf542c50ff3c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 189: Tri-colouring a triangular grid", + "tests": [ + { + "text": "euler189() should return 10834893628237824.", + "testString": "assert.strictEqual(euler189(), 10834893628237824, 'euler189() should return 10834893628237824.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the following configuration of 64 triangles:", + "", + "", + "", + "We wish to colour the interior of each triangle with one of three colours: red, green or blue, so that no two neighbouring triangles have the same colour. Such a colouring shall be called valid. Here, two triangles are said to be neighbouring if they share an edge.", + "Note: if they only share a vertex, then they are not neighbours. ", + "", + "For example, here is a valid colouring of the above grid:", + "", + "", + "A colouring C' which is obtained from a colouring C by rotation or reflection is considered distinct from C unless the two are identical.", + "", + "How many distinct valid colourings are there for the above configuration?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler189() {", + " // Good luck!", + " return true;", + "}", + "", + "euler189();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f42b1000cf542c50ff3d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 190: Maximising a weighted product", + "tests": [ + { + "text": "euler190() should return 371048281.", + "testString": "assert.strictEqual(euler190(), 371048281, 'euler190() should return 371048281.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let Sm = (x1, x2, ... , xm) be the m-tuple of positive real numbers with x1 + x2 + ... + xm = m for which Pm = x1 * x22 * ... * xmm is maximised.", + "", + "For example, it can be verified that [P10] = 4112 ([ ] is the integer part function).", + "", + "Find Σ[Pm] for 2 ≤ m ≤ 15." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler190() {", + " // Good luck!", + " return true;", + "}", + "", + "euler190();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f42b1000cf542c50ff3e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 191: Prize Strings", + "tests": [ + { + "text": "euler191() should return 1918080160.", + "testString": "assert.strictEqual(euler191(), 1918080160, 'euler191() should return 1918080160.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A particular school offers cash rewards to children with good attendance and punctuality. If they are absent for three consecutive days or late on more than one occasion then they forfeit their prize.", + "", + "During an n-day period a trinary string is formed for each child consisting of L's (late), O's (on time), and A's (absent).", + "", + "Although there are eighty-one trinary strings for a 4-day period that can be formed, exactly forty-three strings would lead to a prize:", + "", + "OOOO OOOA OOOL OOAO OOAA OOAL OOLO OOLA OAOO OAOA", + "OAOL OAAO OAAL OALO OALA OLOO OLOA OLAO OLAA AOOO", + "AOOA AOOL AOAO AOAA AOAL AOLO AOLA AAOO AAOA AAOL", + "AALO AALA ALOO ALOA ALAO ALAA LOOO LOOA LOAO LOAA", + "LAOO LAOA LAAO", + "", + "How many \"prize\" strings exist over a 30-day period?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler191() {", + " // Good luck!", + " return true;", + "}", + "", + "euler191();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f42c1000cf542c50ff3f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 192: Best Approximations", + "tests": [ + { + "text": "euler192() should return 57060635927998344.", + "testString": "assert.strictEqual(euler192(), 57060635927998344, 'euler192() should return 57060635927998344.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let x be a real number.", + "A best approximation to x for the denominator bound d is a rational number r/s in reduced form, with s ≤ d, such that any rational number which is closer to x than r/s has a denominator larger than d:", + "", + "|p/q-x| < |r/s-x| ⇒ q > d", + "", + "For example, the best approximation to √13 for the denominator bound 20 is 18/5 and the best approximation to √13 for the denominator bound 30 is 101/28.", + "", + "Find the sum of all denominators of the best approximations to √n for the denominator bound 1012, where n is not a perfect square and 1 < n ≤ 100000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler192() {", + " // Good luck!", + " return true;", + "}", + "", + "euler192();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f42f1000cf542c50ff41", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 193: Squarefree Numbers", + "tests": [ + { + "text": "euler193() should return 684465067343069.", + "testString": "assert.strictEqual(euler193(), 684465067343069, 'euler193() should return 684465067343069.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A positive integer n is called squarefree, if no square of a prime divides n, thus 1, 2, 3, 5, 6, 7, 10, 11 are squarefree, but not 4, 8, 9, 12.", + "", + "How many squarefree numbers are there below 250?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler193() {", + " // Good luck!", + " return true;", + "}", + "", + "euler193();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f42f1000cf542c50ff40", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 194: Coloured Configurations", + "tests": [ + { + "text": "euler194() should return 61190912.", + "testString": "assert.strictEqual(euler194(), 61190912, 'euler194() should return 61190912.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider graphs built with the units A: ", + "and B: , where the units are glued along", + "the vertical edges as in the graph .", + "", + "A configuration of type (a,b,c) is a graph thus built of a units A and b units B, where the graph's vertices are coloured using up to c colours, so that no two adjacent vertices have the same colour.", + "The compound graph above is an example of a configuration of type (2,2,6), in fact of type (2,2,c) for all c ≥ 4.", + "", + "Let N(a,b,c) be the number of configurations of type (a,b,c).", + "For example, N(1,0,3) = 24, N(0,2,4) = 92928 and N(2,2,3) = 20736.", + "", + "Find the last 8 digits of N(25,75,1984)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler194() {", + " // Good luck!", + " return true;", + "}", + "", + "euler194();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4311000cf542c50ff43", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 195: Inscribed circles of triangles with one angle of 60 degrees", + "tests": [ + { + "text": "euler195() should return 75085391.", + "testString": "assert.strictEqual(euler195(), 75085391, 'euler195() should return 75085391.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let's call an integer sided triangle with exactly one angle of 60 degrees a 60-degree triangle.", + "Let r be the radius of the inscribed circle of such a 60-degree triangle.", + "There are 1234 60-degree triangles for which r ≤ 100.", + "Let T(n) be the number of 60-degree triangles for which r ≤ n, so", + " T(100) = 1234,  T(1000) = 22767, and  T(10000) = 359912.", + "", + "Find T(1053779)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler195() {", + " // Good luck!", + " return true;", + "}", + "", + "euler195();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4301000cf542c50ff42", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 196: Prime triplets", + "tests": [ + { + "text": "euler196() should return 322303240771079940.", + "testString": "assert.strictEqual(euler196(), 322303240771079940, 'euler196() should return 322303240771079940.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Build a triangle from all positive integers in the following way:", + "", + " 1", + " 2  3", + " 4  5  6", + " 7  8  9 1011 12 13 14 15", + "16 17 18 19 20 21", + "22 23 24 25 26 27 2829 30 31 32 33 34 35 3637 38 39 40 41 42 43 44 45", + "46 47 48 49 50 51 52 53 54 55", + "56 57 58 59 60 61 62 63 64 65 66", + ". . .", + "", + "Each positive integer has up to eight neighbours in the triangle.", + "", + "A set of three primes is called a prime triplet if one of the three primes has the other two as neighbours in the triangle.", + "", + "For example, in the second row, the prime numbers 2 and 3 are elements of some prime triplet.", + "", + "If row 8 is considered, it contains two primes which are elements of some prime triplet, i.e. 29 and 31.", + "If row 9 is considered, it contains only one prime which is an element of some prime triplet: 37.", + "", + "Define S(n) as the sum of the primes in row n which are elements of any prime triplet.", + "Then S(8)=60 and S(9)=37.", + "", + "You are given that S(10000)=950007619.", + "", + "Find  S(5678027) + S(7208785)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler196() {", + " // Good luck!", + " return true;", + "}", + "", + "euler196();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4311000cf542c50ff44", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 197: Investigating the behaviour of a recursively defined sequence", + "tests": [ + { + "text": "euler197() should return 1.710637717.", + "testString": "assert.strictEqual(euler197(), 1.710637717, 'euler197() should return 1.710637717.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given is the function f(x) = ⌊230.403243784-x2⌋ × 10-9 ( ⌊ ⌋ is the floor-function),", + "the sequence un is defined by u0 = -1 and un+1 = f(un).", + "", + "Find un + un+1 for n = 1012.", + "Give your answer with 9 digits after the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler197() {", + " // Good luck!", + " return true;", + "}", + "", + "euler197();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4331000cf542c50ff45", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 198: Ambiguous Numbers", + "tests": [ + { + "text": "euler198() should return 52374425.", + "testString": "assert.strictEqual(euler198(), 52374425, 'euler198() should return 52374425.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A best approximation to a real number x for the denominator bound d is a rational number r/s (in reduced form) with s ≤ d, so that any rational number p/q which is closer to x than r/s has q > d.", + "", + "Usually the best approximation to a real number is uniquely determined for all denominator bounds. However, there are some exceptions, e.g. 9/40 has the two best approximations 1/4 and 1/5 for the denominator bound 6.", + "We shall call a real number x ambiguous, if there is at least one denominator bound for which x possesses two best approximations. Clearly, an ambiguous number is necessarily rational.", + "", + "How many ambiguous numbers x = p/q,", + "0 < x < 1/100, are there whose denominator q does not exceed 108?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler198() {", + " // Good luck!", + " return true;", + "}", + "", + "euler198();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4341000cf542c50ff46", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 199: Iterative Circle Packing", + "tests": [ + { + "text": "euler199() should return 0.00396087.", + "testString": "assert.strictEqual(euler199(), 0.00396087, 'euler199() should return 0.00396087.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Three circles of equal radius are placed inside a larger circle such that each pair of circles is tangent to one another and the inner circles do not overlap. There are four uncovered \"gaps\" which are to be filled iteratively with more tangent circles.", + "", + "", + "", + "At each iteration, a maximally sized circle is placed in each gap, which creates more gaps for the next iteration. After 3 iterations (pictured), there are 108 gaps and the fraction of the area which is not covered by circles is 0.06790342, rounded to eight decimal places.", + "", + "", + "What fraction of the area is not covered by circles after 10 iterations?", + "Give your answer rounded to eight decimal places using the format x.xxxxxxxx ." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler199() {", + " // Good luck!", + " return true;", + "}", + "", + "euler199();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4351000cf542c50ff47", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 200: Find the 200th prime-proof sqube containing the contiguous sub-string \"200\"", + "tests": [ + { + "text": "euler200() should return 229161792008.", + "testString": "assert.strictEqual(euler200(), 229161792008, 'euler200() should return 229161792008.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We shall define a sqube to be a number of the form, p2q3, where p and q are distinct primes.", + "For example, 200 = 5223 or 120072949 = 232613.", + "", + "The first five squbes are 72, 108, 200, 392, and 500.", + "", + "Interestingly, 200 is also the first number for which you cannot change any single digit to make a prime; we shall call such numbers, prime-proof. The next prime-proof sqube which contains the contiguous sub-string \"200\" is 1992008.", + "", + "Find the 200th prime-proof sqube containing the contiguous sub-string \"200\"." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler200() {", + " // Good luck!", + " return true;", + "}", + "", + "euler200();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4361000cf542c50ff48", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 201: Subsets with a unique sum", + "tests": [ + { + "text": "euler201() should return 115039000.", + "testString": "assert.strictEqual(euler201(), 115039000, 'euler201() should return 115039000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For any set A of numbers, let sum(A) be the sum of the elements of A.", + "Consider the set B = {1,3,6,8,10,11}. There are 20 subsets of B containing three elements, and their sums are:", + "", + "", + "sum({1,3,6}) = 10,", + "sum({1,3,8}) = 12,", + "sum({1,3,10}) = 14,", + "sum({1,3,11}) = 15,", + "sum({1,6,8}) = 15,", + "sum({1,6,10}) = 17,", + "sum({1,6,11}) = 18,", + "sum({1,8,10}) = 19,", + "sum({1,8,11}) = 20,", + "sum({1,10,11}) = 22,", + "sum({3,6,8}) = 17,", + "sum({3,6,10}) = 19,", + "sum({3,6,11}) = 20,", + "sum({3,8,10}) = 21,", + "sum({3,8,11}) = 22,", + "sum({3,10,11}) = 24,", + "sum({6,8,10}) = 24,", + "sum({6,8,11}) = 25,", + "sum({6,10,11}) = 27,", + "sum({8,10,11}) = 29.", + "", + "Some of these sums occur more than once, others are unique.", + "For a set A, let U(A,k) be the set of unique sums of k-element subsets of A, in our example we find U(B,3) = {10,12,14,18,21,25,27,29} and sum(U(B,3)) = 156.", + "", + "Now consider the 100-element set S = {12, 22, ... , 1002}.", + "S has 100891344545564193334812497256 50-element subsets.", + "", + "Determine the sum of all integers which are the sum of exactly one of the 50-element subsets of S, i.e. find sum(U(S,50))." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler201() {", + " // Good luck!", + " return true;", + "}", + "", + "euler201();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4371000cf542c50ff49", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 202: Laserbeam", + "tests": [ + { + "text": "euler202() should return 1209002624.", + "testString": "assert.strictEqual(euler202(), 1209002624, 'euler202() should return 1209002624.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Three mirrors are arranged in the shape of an equilateral triangle, with their reflective surfaces pointing inwards. There is an infinitesimal gap at each vertex of the triangle through which a laser beam may pass.", + "", + "Label the vertices A, B and C. There are 2 ways in which a laser beam may enter vertex C, bounce off 11 surfaces, then exit through the same vertex: one way is shown below; the other is the reverse of that.", + "", + "", + " ", + "", + "There are 80840 ways in which a laser beam may enter vertex C, bounce off 1000001 surfaces, then exit through the same vertex.", + "", + "In how many ways can a laser beam enter at vertex C, bounce off 12017639147 surfaces, then exit through the same vertex?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler202() {", + " // Good luck!", + " return true;", + "}", + "", + "euler202();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4381000cf542c50ff4a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 203: Squarefree Binomial Coefficients", + "tests": [ + { + "text": "euler203() should return 34029210557338.", + "testString": "assert.strictEqual(euler203(), 34029210557338, 'euler203() should return 34029210557338.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The binomial coefficients nCk can be arranged in triangular form, Pascal's triangle, like this:", + "", + "", + "111121133114641151010511615201561172135352171", + ".........", + "", + "", + "It can be seen that the first eight rows of Pascal's triangle contain twelve distinct numbers: 1, 2, 3, 4, 5, 6, 7, 10, 15, 20, 21 and 35.", + "", + "A positive integer n is called squarefree if no square of a prime divides n.", + "Of the twelve distinct numbers in the first eight rows of Pascal's triangle, all except 4 and 20 are squarefree.", + "The sum of the distinct squarefree numbers in the first eight rows is 105.", + "", + "Find the sum of the distinct squarefree numbers in the first 51 rows of Pascal's triangle." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler203() {", + " // Good luck!", + " return true;", + "}", + "", + "euler203();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4381000cf542c50ff4b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 204: Generalised Hamming Numbers", + "tests": [ + { + "text": "euler204() should return 2944730.", + "testString": "assert.strictEqual(euler204(), 2944730, 'euler204() should return 2944730.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A Hamming number is a positive number which has no prime factor larger than 5.", + "So the first few Hamming numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15.", + "There are 1105 Hamming numbers not exceeding 108.", + "", + "We will call a positive number a generalised Hamming number of type n, if it has no prime factor larger than n.", + "Hence the Hamming numbers are the generalised Hamming numbers of type 5.", + "", + "How many generalised Hamming numbers of type 100 are there which don't exceed 109?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler204() {", + " // Good luck!", + " return true;", + "}", + "", + "euler204();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4391000cf542c50ff4c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 205: Dice Game", + "tests": [ + { + "text": "euler205() should return 0.5731441.", + "testString": "assert.strictEqual(euler205(), 0.5731441, 'euler205() should return 0.5731441.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Peter has nine four-sided (pyramidal) dice, each with faces numbered 1, 2, 3, 4.", + "Colin has six six-sided (cubic) dice, each with faces numbered 1, 2, 3, 4, 5, 6.", + "", + "Peter and Colin roll their dice and compare totals: the highest total wins. The result is a draw if the totals are equal.", + "", + "What is the probability that Pyramidal Pete beats Cubic Colin? Give your answer rounded to seven decimal places in the form 0.abcdefg" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler205() {", + " // Good luck!", + " return true;", + "}", + "", + "euler205();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f43a1000cf542c50ff4d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 206: Concealed Square", + "tests": [ + { + "text": "euler206() should return 1389019170.", + "testString": "assert.strictEqual(euler206(), 1389019170, 'euler206() should return 1389019170.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Find the unique positive integer whose square has the form 1_2_3_4_5_6_7_8_9_0, where each “_” is a single digit." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler206() {", + " // Good luck!", + " return true;", + "}", + "", + "euler206();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f43c1000cf542c50ff4e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 207: Integer partition equations", + "tests": [ + { + "text": "euler207() should return 44043947822.", + "testString": "assert.strictEqual(euler207(), 44043947822, 'euler207() should return 44043947822.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For some positive integers k, there exists an integer partition of the form   4t = 2t + k,", + "where 4t, 2t, and k are all positive integers and t is a real number.", + "", + "The first two such partitions are 41 = 21 + 2 and 41.5849625... = 21.5849625... + 6.", + "", + "Partitions where t is also an integer are called perfect. ", + "For any m ≥ 1 let P(m) be the proportion of such partitions that are perfect with k ≤ m.", + "Thus P(6) = 1/2.", + "", + "In the following table are listed some values of P(m)", + "   P(5) = 1/1", + "   P(10) = 1/2", + "   P(15) = 2/3", + "   P(20) = 1/2", + "   P(25) = 1/2", + "   P(30) = 2/5", + "   ...", + "   P(180) = 1/4", + "   P(185) = 3/13", + "", + "", + "Find the smallest m for which P(m) < 1/12345" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler207() {", + " // Good luck!", + " return true;", + "}", + "", + "euler207();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f43f1000cf542c50ff51", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 208: Robot Walks", + "tests": [ + { + "text": "euler208() should return 331951449665644800.", + "testString": "assert.strictEqual(euler208(), 331951449665644800, 'euler208() should return 331951449665644800.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A robot moves in a series of one-fifth circular arcs (72°), with a free choice of a clockwise or an anticlockwise arc for each step, but no turning on the spot.", + "", + "One of 70932 possible closed paths of 25 arcs starting northward is", + "", + "", + "", + "Given that the robot starts facing North, how many journeys of 70 arcs in length can it take that return it, after the final arc, to its starting position?", + "(Any arc may be traversed multiple times.)" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler208() {", + " // Good luck!", + " return true;", + "}", + "", + "euler208();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f43e1000cf542c50ff4f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 209: Circular Logic", + "tests": [ + { + "text": "euler209() should return 15964587728784.", + "testString": "assert.strictEqual(euler209(), 15964587728784, 'euler209() should return 15964587728784.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A k-input binary truth table is a map from k input bits", + "(binary digits, 0 [false] or 1 [true]) to 1 output bit. For example, the 2-input binary truth tables for the logical AND and XOR functions are:", + "", + "x", + "y", + "x AND y000010100111x", + "y", + "x XOR y000011101110How many 6-input binary truth tables, τ, satisfy the formula", + "", + "τ(a, b, c, d, e, f) AND τ(b, c, d, e, f, a XOR (b AND c)) = 0", + "for all 6-bit inputs (a, b, c, d, e, f)?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler209() {", + " // Good luck!", + " return true;", + "}", + "", + "euler209();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f43e1000cf542c50ff50", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 210: Obtuse Angled Triangles", + "tests": [ + { + "text": "euler210() should return 1598174770174689500.", + "testString": "assert.strictEqual(euler210(), 1598174770174689500, 'euler210() should return 1598174770174689500.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the set S(r) of points (x,y) with integer coordinates satisfying |x| + |y| ≤ r. ", + "Let O be the point (0,0) and C the point (r/4,r/4). ", + "Let N(r) be the number of points B in S(r), so that the triangle OBC has an obtuse angle, i.e. the largest angle α satisfies 90°<α<180°.", + "So, for example, N(4)=24 and N(8)=100.", + "", + "What is N(1,000,000,000)?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler210() {", + " // Good luck!", + " return true;", + "}", + "", + "euler210();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f43f1000cf542c50ff52", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 211: Divisor Square Sum", + "tests": [ + { + "text": "euler211() should return 1922364685.", + "testString": "assert.strictEqual(euler211(), 1922364685, 'euler211() should return 1922364685.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a positive integer n, let σ2(n) be the sum of the squares of its divisors. For example,", + "σ2(10) = 1 + 4 + 25 + 100 = 130.", + "Find the sum of all n, 0 < n < 64,000,000 such that σ2(n) is a perfect square." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler211() {", + " // Good luck!", + " return true;", + "}", + "", + "euler211();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4411000cf542c50ff53", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 212: Combined Volume of Cuboids", + "tests": [ + { + "text": "euler212() should return 328968937309.", + "testString": "assert.strictEqual(euler212(), 328968937309, 'euler212() should return 328968937309.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An axis-aligned cuboid, specified by parameters { (x0,y0,z0), (dx,dy,dz) }, consists of all points (X,Y,Z) such that x0 ≤ X ≤ x0+dx, y0 ≤ Y ≤ y0+dy and z0 ≤ Z ≤ z0+dz. The volume of the cuboid is the product, dx × dy × dz. The combined volume of a collection of cuboids is the volume of their union and will be less than the sum of the individual volumes if any cuboids overlap.", + "", + "Let C1,...,C50000 be a collection of 50000 axis-aligned cuboids such that Cn has parameters", + "", + "x0 = S6n-5 modulo 10000y0 = S6n-4 modulo 10000z0 = S6n-3 modulo 10000dx = 1 + (S6n-2 modulo 399)dy = 1 + (S6n-1 modulo 399)dz = 1 + (S6n modulo 399)", + "", + "where S1,...,S300000 come from the \"Lagged Fibonacci Generator\":", + "", + "For 1 ≤ k ≤ 55, Sk = [100003 - 200003k + 300007k3]   (modulo 1000000)For 56 ≤ k, Sk = [Sk-24 + Sk-55]   (modulo 1000000)", + "", + "Thus, C1 has parameters {(7,53,183),(94,369,56)}, C2 has parameters {(2383,3563,5079),(42,212,344)}, and so on.", + "", + "The combined volume of the first 100 cuboids, C1,...,C100, is 723581599.", + "", + "What is the combined volume of all 50000 cuboids, C1,...,C50000 ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler212() {", + " // Good luck!", + " return true;", + "}", + "", + "euler212();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4411000cf542c50ff54", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 213: Flea Circus", + "tests": [ + { + "text": "euler213() should return 330.721154.", + "testString": "assert.strictEqual(euler213(), 330.721154, 'euler213() should return 330.721154.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A 30×30 grid of squares contains 900 fleas, initially one flea per square.", + "When a bell is rung, each flea jumps to an adjacent square at random (usually 4 possibilities, except for fleas on the edge of the grid or at the corners).", + "", + "What is the expected number of unoccupied squares after 50 rings of the bell? Give your answer rounded to six decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler213() {", + " // Good luck!", + " return true;", + "}", + "", + "euler213();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4421000cf542c50ff55", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 214: Totient Chains", + "tests": [ + { + "text": "euler214() should return 1677366278943.", + "testString": "assert.strictEqual(euler214(), 1677366278943, 'euler214() should return 1677366278943.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let φ be Euler's totient function, i.e. for a natural number n,", + "φ(n) is the number of k, 1 ≤ k ≤ n, for which gcd(k,n) = 1.", + "", + "By iterating φ, each positive integer generates a decreasing chain of numbers ending in 1.", + "E.g. if we start with 5 the sequence 5,4,2,1 is generated.", + "Here is a listing of all chains with length 4:", + "", + "", + "5,4,2,1", + "7,6,2,1", + "8,4,2,1", + "9,6,2,1", + "10,4,2,1", + "12,4,2,1", + "14,6,2,1", + "18,6,2,1", + "", + "Only two of these chains start with a prime, their sum is 12.", + "", + "What is the sum of all primes less than 40000000 which generate a chain of length 25?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler214() {", + " // Good luck!", + " return true;", + "}", + "", + "euler214();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4431000cf542c50ff56", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 215: Crack-free Walls", + "tests": [ + { + "text": "euler215() should return 806844323190414.", + "testString": "assert.strictEqual(euler215(), 806844323190414, 'euler215() should return 806844323190414.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the problem of building a wall out of 2×1 and 3×1 bricks (horizontal×vertical dimensions) such that, for extra strength, the gaps between horizontally-adjacent bricks never line up in consecutive layers, i.e. never form a \"running crack\".", + "", + "For example, the following 9×3 wall is not acceptable due to the running crack shown in red:", + "", + "", + "", + "", + "There are eight ways of forming a crack-free 9×3 wall, written W(9,3) = 8.", + "", + "Calculate W(32,10)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler215() {", + " // Good luck!", + " return true;", + "}", + "", + "euler215();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4451000cf542c50ff57", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 216: Investigating the primality of numbers of the form 2n2-1", + "tests": [ + { + "text": "euler216() should return 5437849.", + "testString": "assert.strictEqual(euler216(), 5437849, 'euler216() should return 5437849.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider numbers t(n) of the form t(n) = 2n2-1 with n > 1.", + "The first such numbers are 7, 17, 31, 49, 71, 97, 127 and 161.", + "It turns out that only 49 = 7*7 and 161 = 7*23 are not prime.", + "For n ≤ 10000 there are 2202 numbers t(n) that are prime.", + "", + "How many numbers t(n) are prime for n ≤ 50,000,000 ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler216() {", + " // Good luck!", + " return true;", + "}", + "", + "euler216();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4461000cf542c50ff58", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 217: Balanced Numbers", + "tests": [ + { + "text": "euler217() should return 6273134.", + "testString": "assert.strictEqual(euler217(), 6273134, 'euler217() should return 6273134.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A positive integer with k (decimal) digits is called balanced if its first ⌈k/2⌉ digits sum to the same value as its last ⌈k/2⌉ digits, where ⌈x⌉, pronounced ceiling of x, is the smallest integer ≥ x, thus ⌈π⌉ = 4 and ⌈5⌉ = 5.", + "So, for example, all palindromes are balanced, as is 13722.", + "Let T(n) be the sum of all balanced numbers less than 10n. ", + "Thus: T(1) = 45, T(2) = 540 and T(5) = 334795890. ", + "Find T(47) mod 315" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler217() {", + " // Good luck!", + " return true;", + "}", + "", + "euler217();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4461000cf542c50ff59", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 218: Perfect right-angled triangles", + "tests": [ + { + "text": "euler218() should return 0.", + "testString": "assert.strictEqual(euler218(), 0, 'euler218() should return 0.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the right angled triangle with sides a=7, b=24 and c=25.", + "The area of this triangle is 84, which is divisible by the perfect numbers 6 and 28.", + "Moreover it is a primitive right angled triangle as gcd(a,b)=1 and gcd(b,c)=1.", + "Also c is a perfect square.", + "", + "We will call a right angled triangle perfect if", + "-it is a primitive right angled triangle", + "-its hypotenuse is a perfect square", + "", + "We will call a right angled triangle super-perfect if", + "-it is a perfect right angled triangle and", + "-its area is a multiple of the perfect numbers 6 and 28.", + "", + "", + "How many perfect right-angled triangles with c≤1016 exist that are not super-perfect?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler218() {", + " // Good luck!", + " return true;", + "}", + "", + "euler218();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4481000cf542c50ff5a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 219: Skew-cost coding", + "tests": [ + { + "text": "euler219() should return 64564225042.", + "testString": "assert.strictEqual(euler219(), 64564225042, 'euler219() should return 64564225042.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let A and B be bit strings (sequences of 0's and 1's).", + "If A is equal to the leftmost length(A) bits of B, then A is said to be a prefix of B.", + "For example, 00110 is a prefix of 001101001, but not of 00111 or 100110.", + "", + "A prefix-free code of size n is a collection of n distinct bit strings such that no string is a prefix of any other. For example, this is a prefix-free code of size 6:", + "", + "0000, 0001, 001, 01, 10, 11", + "", + "Now suppose that it costs one penny to transmit a '0' bit, but four pence to transmit a '1'.", + "Then the total cost of the prefix-free code shown above is 35 pence, which happens to be the cheapest possible for the skewed pricing scheme in question.", + "In short, we write Cost(6) = 35.", + "", + "What is Cost(109) ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler219() {", + " // Good luck!", + " return true;", + "}", + "", + "euler219();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4481000cf542c50ff5b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 220: Heighway Dragon", + "tests": [ + { + "text": "euler220() should return 139776, 963904.", + "testString": "assert.strictEqual(euler220(), 139776, 963904, 'euler220() should return 139776, 963904.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let D0 be the two-letter string \"Fa\". For n≥1, derive Dn from Dn-1 by the string-rewriting rules:", + "", + "\"a\" → \"aRbFR\"", + "\"b\" → \"LFaLb\"", + "", + "Thus, D0 = \"Fa\", D1 = \"FaRbFR\", D2 = \"FaRbFRRLFaLbFR\", and so on.", + "", + "These strings can be interpreted as instructions to a computer graphics program, with \"F\" meaning \"draw forward one unit\", \"L\" meaning \"turn left 90 degrees\", \"R\" meaning \"turn right 90 degrees\", and \"a\" and \"b\" being ignored. The initial position of the computer cursor is (0,0), pointing up towards (0,1).", + "", + "Then Dn is an exotic drawing known as the Heighway Dragon of order n. For example, D10 is shown below; counting each \"F\" as one step, the highlighted spot at (18,16) is the position reached after 500 steps.", + "", + "", + "", + "", + "What is the position of the cursor after 1012 steps in D50 ?", + "Give your answer in the form x,y with no spaces." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler220() {", + " // Good luck!", + " return true;", + "}", + "", + "euler220();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4491000cf542c50ff5c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 221: Alexandrian Integers", + "tests": [ + { + "text": "euler221() should return 1884161251122450.", + "testString": "assert.strictEqual(euler221(), 1884161251122450, 'euler221() should return 1884161251122450.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We shall call a positive integer A an \"Alexandrian integer\", if there exist integers p, q, r such that:", + "", + "", + " A = p · q · r    and  ", + " ", + " ", + " 1A", + " =", + " ", + " 1p", + " +", + " ", + " 1q", + " +", + " ", + " 1r", + "For example, 630 is an Alexandrian integer (p = 5, q = −7, r = −18).", + "In fact, 630 is the 6th Alexandrian integer, the first 6 Alexandrian integers being: 6, 42, 120, 156, 420 and 630.", + "", + "Find the 150000th Alexandrian integer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler221() {", + " // Good luck!", + " return true;", + "}", + "", + "euler221();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f44b1000cf542c50ff5d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 222: Sphere Packing", + "tests": [ + { + "text": "euler222() should return 1590933.", + "testString": "assert.strictEqual(euler222(), 1590933, 'euler222() should return 1590933.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "What is the length of the shortest pipe, of internal radius 50mm, that can fully contain 21 balls of radii 30mm, 31mm, ..., 50mm?", + "", + "Give your answer in micrometres (10-6 m) rounded to the nearest integer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler222() {", + " // Good luck!", + " return true;", + "}", + "", + "euler222();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f44b1000cf542c50ff5e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 223: Almost right-angled triangles I", + "tests": [ + { + "text": "euler223() should return 61614848.", + "testString": "assert.strictEqual(euler223(), 61614848, 'euler223() should return 61614848.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let us call an integer sided triangle with sides a ≤ b ≤ c barely acute if the sides satisfy a2 + b2 = c2 + 1.", + "", + "How many barely acute triangles are there with perimeter ≤ 25,000,000?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler223() {", + " // Good luck!", + " return true;", + "}", + "", + "euler223();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f44e1000cf542c50ff5f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 224: Almost right-angled triangles II", + "tests": [ + { + "text": "euler224() should return 4137330.", + "testString": "assert.strictEqual(euler224(), 4137330, 'euler224() should return 4137330.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let us call an integer sided triangle with sides a ≤ b ≤ c barely obtuse if the sides satisfy a2 + b2 = c2 - 1.", + "", + "How many barely obtuse triangles are there with perimeter ≤ 75,000,000?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler224() {", + " // Good luck!", + " return true;", + "}", + "", + "euler224();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f44e1000cf542c50ff60", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 225: Tribonacci non-divisors", + "tests": [ + { + "text": "euler225() should return 2009.", + "testString": "assert.strictEqual(euler225(), 2009, 'euler225() should return 2009.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The sequence 1, 1, 1, 3, 5, 9, 17, 31, 57, 105, 193, 355, 653, 1201 ...", + "is defined by T1 = T2 = T3 = 1 and Tn = Tn-1 + Tn-2 + Tn-3.", + "", + "", + "It can be shown that 27 does not divide any terms of this sequence.In fact, 27 is the first odd number with this property.", + "", + "Find the 124th odd number that does not divide any terms of the above sequence." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler225() {", + " // Good luck!", + " return true;", + "}", + "", + "euler225();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4511000cf542c50ff62", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 226: A Scoop of Blancmange", + "tests": [ + { + "text": "euler226() should return 0.11316017.", + "testString": "assert.strictEqual(euler226(), 0.11316017, 'euler226() should return 0.11316017.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The blancmange curve is the set of points (x,y) such that 0 ≤ x ≤ 1 and ,where s(x) = the distance from x to the nearest integer.", + "", + "The area under the blancmange curve is equal to ½, shown in pink in the diagram below.", + "", + "", + "", + "", + "Let C be the circle with centre (¼,½) and radius ¼, shown in black in the diagram.", + "", + "What area under the blancmange curve is enclosed by C?Give your answer rounded to eight decimal places in the form 0.abcdefgh" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler226() {", + " // Good luck!", + " return true;", + "}", + "", + "euler226();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f44f1000cf542c50ff61", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 227: The Chase", + "tests": [ + { + "text": "euler227() should return 3780.618622.", + "testString": "assert.strictEqual(euler227(), 3780.618622, 'euler227() should return 3780.618622.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "\"The Chase\" is a game played with two dice and an even number of players.", + "", + "The players sit around a table; the game begins with two opposite players having one die each. On each turn, the two players with a die roll it.", + "If a player rolls a 1, he passes the die to his neighbour on the left; if he rolls a 6, he passes the die to his neighbour on the right; otherwise, he keeps the die for the next turn.", + "The game ends when one player has both dice after they have been rolled and passed; that player has then lost.", + "", + "In a game with 100 players, what is the expected number of turns the game lasts?", + "Give your answer rounded to ten significant digits." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler227() {", + " // Good luck!", + " return true;", + "}", + "", + "euler227();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4511000cf542c50ff63", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 228: Minkowski Sums", + "tests": [ + { + "text": "euler228() should return 86226.", + "testString": "assert.strictEqual(euler228(), 86226, 'euler228() should return 86226.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let Sn be the regular n-sided polygon – or shape – whose vertices ", + "", + "vk (k = 1,2,…,n) have coordinates:", + "", + " xk   =  ", + " cos( 2k-1/n ×180° )", + " ", + " yk   =  ", + " sin( 2k-1/n ×180° )", + " Each Sn is to be interpreted as a filled shape consisting of all points on the perimeter and in the interior.", + "", + "The Minkowski sum, S+T, of two shapes S and T is the result of ", + "", + "adding every point in S to every point in T, where point addition is performed coordinate-wise: ", + "", + "(u, v) + (x, y) = (u+x, v+y).", + "", + "For example, the sum of S3 and S4 is the six-sided shape shown in pink below:", + "", + "", + "", + "", + "How many sides does S1864 + S1865 + … + S1909 have?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler228() {", + " // Good luck!", + " return true;", + "}", + "", + "euler228();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4521000cf542c50ff64", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 229: Four Representations using Squares", + "tests": [ + { + "text": "euler229() should return 11325263.", + "testString": "assert.strictEqual(euler229(), 11325263, 'euler229() should return 11325263.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the number 3600. It is very special, because", + "", + "3600 = 482 +     362", + "3600 = 202 + 2×402", + "3600 = 302 + 3×302", + "3600 = 452 + 7×152", + "", + "Similarly, we find that 88201 = 992 + 2802 = 2872 + 2×542 = 2832 + 3×522 = 1972 + 7×842.", + "", + "In 1747, Euler proved which numbers are representable as a sum of two squares.", + "We are interested in the numbers n which admit representations of all of the following four types:", + "", + "n = a12 +   b12n = a22 + 2 b22n = a32 + 3 b32n = a72 + 7 b72,", + "", + "where the ak and bk are positive integers.", + "", + "There are 75373 such numbers that do not exceed 107.", + "", + "How many such numbers are there that do not exceed 2×109?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler229() {", + " // Good luck!", + " return true;", + "}", + "", + "euler229();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4531000cf542c50ff65", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 230: Fibonacci Words", + "tests": [ + { + "text": "euler230() should return 850481152593119200.", + "testString": "assert.strictEqual(euler230(), 850481152593119200, 'euler230() should return 850481152593119200.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For any two strings of digits, A and B, we define FA,B to be the sequence (A,B,AB,BAB,ABBAB,...) in which each term is the concatenation of the previous two.", + "", + "Further, we define DA,B(n) to be the nth digit in the first term of FA,B that contains at least n digits.", + "", + "Example:", + "", + "Let A=1415926535, B=8979323846. We wish to find DA,B(35), say.", + "", + "The first few terms of FA,B are:", + "1415926535", + "8979323846", + "14159265358979323846", + "897932384614159265358979323846", + "14159265358979323846897932384614159265358979323846", + "", + "Then DA,B(35) is the 35th digit in the fifth term, which is 9.", + "", + "Now we use for A the first 100 digits of π behind the decimal point:", + "14159265358979323846264338327950288419716939937510 ", + "58209749445923078164062862089986280348253421170679 ", + "", + "and for B the next hundred digits:", + "", + "82148086513282306647093844609550582231725359408128 ", + "48111745028410270193852110555964462294895493038196 .", + "", + "Find ∑n = 0,1,...,17   10n× DA,B((127+19n)×7n) ." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler230() {", + " // Good luck!", + " return true;", + "}", + "", + "euler230();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4531000cf542c50ff66", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 231: The prime factorisation of binomial coefficients", + "tests": [ + { + "text": "euler231() should return 7526965179680.", + "testString": "assert.strictEqual(euler231(), 7526965179680, 'euler231() should return 7526965179680.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The binomial coefficient 10C3 = 120.", + "120 = 23 × 3 × 5 = 2 × 2 × 2 × 3 × 5, and 2 + 2 + 2 + 3 + 5 = 14.", + "So the sum of the terms in the prime factorisation of 10C3 is 14.", + "", + "Find the sum of the terms in the prime factorisation of 20000000C15000000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler231() {", + " // Good luck!", + " return true;", + "}", + "", + "euler231();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4551000cf542c50ff67", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 232: The Race", + "tests": [ + { + "text": "euler232() should return 0.83648556.", + "testString": "assert.strictEqual(euler232(), 0.83648556, 'euler232() should return 0.83648556.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Two players share an unbiased coin and take it in turns to play \"The Race\". On Player 1's turn, he tosses the coin once: if it comes up Heads, he scores one point; if it comes up Tails, he scores nothing. On Player 2's turn, she chooses a positive integer T and tosses the coin T times: if it comes up all Heads, she scores 2T-1 points; otherwise, she scores nothing. Player 1 goes first. The winner is the first to 100 or more points.", + "", + "On each turn Player 2 selects the number, T, of coin tosses that maximises the probability of her winning.", + "", + "What is the probability that Player 2 wins?", + "", + "Give your answer rounded to eight decimal places in the form 0.abcdefgh ." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler232() {", + " // Good luck!", + " return true;", + "}", + "", + "euler232();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4551000cf542c50ff68", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 233: Lattice points on a circle", + "tests": [ + { + "text": "euler233() should return 271204031455541300.", + "testString": "assert.strictEqual(euler233(), 271204031455541300, 'euler233() should return 271204031455541300.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let f(N) be the number of points with integer coordinates that are on a circle passing through (0,0), (N,0),(0,N), and (N,N).", + "It can be shown that f(10000) = 36.", + "", + "What is the sum of all positive integers N ≤ 1011 such that f(N) = 420 ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler233() {", + " // Good luck!", + " return true;", + "}", + "", + "euler233();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4571000cf542c50ff69", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 234: Semidivisible numbers", + "tests": [ + { + "text": "euler234() should return 1259187438574927000.", + "testString": "assert.strictEqual(euler234(), 1259187438574927000, 'euler234() should return 1259187438574927000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For an integer n ≥ 4, we define the lower prime square root of n, denoted by lps(n), as the largest prime ≤ √n and the upper prime square root of n, ups(n), as the smallest prime ≥ √n.", + "So, for example, lps(4) = 2 = ups(4), lps(1000) = 31, ups(1000) = 37.", + "Let us call an integer n ≥ 4 semidivisible, if one of lps(n) and ups(n) divides n, but not both.", + "", + "The sum of the semidivisible numbers not exceeding 15 is 30, the numbers are 8, 10 and 12. 15 is not semidivisible because it is a multiple of both lps(15) = 3 and ups(15) = 5.", + "As a further example, the sum of the 92 semidivisible numbers up to 1000 is 34825.", + "", + "What is the sum of all semidivisible numbers not exceeding 999966663333 ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler234() {", + " // Good luck!", + " return true;", + "}", + "", + "euler234();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4571000cf542c50ff6a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 235: An Arithmetic Geometric sequence", + "tests": [ + { + "text": "euler235() should return 1.002322108633.", + "testString": "assert.strictEqual(euler235(), 1.002322108633, 'euler235() should return 1.002322108633.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given is the arithmetic-geometric sequence u(k) = (900-3k)rk-1.", + "Let s(n) = Σk=1...nu(k).", + "", + "", + "Find the value of r for which s(5000) = -600,000,000,000.", + "", + "", + "Give your answer rounded to 12 places behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler235() {", + " // Good luck!", + " return true;", + "}", + "", + "euler235();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4591000cf542c50ff6b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 236: Luxury Hampers", + "tests": [ + { + "text": "euler236() should return 123 / 59.", + "testString": "assert.strictEqual(euler236(), 123 / 59, 'euler236() should return 123 / 59.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Suppliers 'A' and 'B' provided the following numbers of products for the luxury hamper market:", + "", + "Product'A''B'Beluga Caviar5248640Christmas Cake13121888Gammon Joint26243776Vintage Port57603776Champagne Truffles39365664", + "", + "Although the suppliers try very hard to ship their goods in perfect condition, there is inevitably some spoilage - i.e. products gone bad.", + "", + "The suppliers compare their performance using two types of statistic:The five per-product spoilage rates for each supplier are equal to the number of products gone bad divided by the number of products supplied, for each of the five products in turn.", + " The overall spoilage rate for each supplier is equal to the total number of products gone bad divided by the total number of products provided by that supplier.To their surprise, the suppliers found that each of the five per-product spoilage rates was worse (higher) for 'B' than for 'A' by the same factor (ratio of spoilage rates), m>1; and yet, paradoxically, the overall spoilage rate was worse for 'A' than for 'B', also by a factor of m.", + "", + "There are thirty-five m>1 for which this surprising result could have occurred, the smallest of which is 1476/1475.", + "", + "What's the largest possible value of m?", + "Give your answer as a fraction reduced to its lowest terms, in the form u/v." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler236() {", + " // Good luck!", + " return true;", + "}", + "", + "euler236();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4591000cf542c50ff6c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 237: Tours on a 4 x n playing board", + "tests": [ + { + "text": "euler237() should return 15836928.", + "testString": "assert.strictEqual(euler237(), 15836928, 'euler237() should return 15836928.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let T(n) be the number of tours over a 4 × n playing board such that:", + "The tour starts in the top left corner.", + "The tour consists of moves that are up, down, left, or right one square.", + "The tour visits each square exactly once.", + "The tour ends in the bottom left corner.", + "The diagram shows one tour over a 4 × 10 board:", + "", + "", + "", + "", + "T(10) is 2329. What is T(1012) modulo 108?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler237() {", + " // Good luck!", + " return true;", + "}", + "", + "euler237();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f45b1000cf542c50ff6d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 238: Infinite string tour", + "tests": [ + { + "text": "euler238() should return 9922545104535660.", + "testString": "assert.strictEqual(euler238(), 9922545104535660, 'euler238() should return 9922545104535660.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Create a sequence of numbers using the \"Blum Blum Shub\" pseudo-random number generator:", + "", + "s0", + " =", + " 14025256", + " sn+1", + " =", + " sn2 mod 20300713", + " ", + "", + "Concatenate these numbers  s0s1s2… to create a string w of infinite length.", + "Then, w = 14025256741014958470038053646…", + "", + "For a positive integer k, if no substring of w exists with a sum of digits equal to k, p(k) is defined to be zero. If at least one substring of w exists with a sum of digits equal to k, we define p(k) = z, where z is the starting position of the earliest such substring.", + "", + "For instance:", + "", + "The substrings 1, 14, 1402, … ", + "with respective sums of digits equal to 1, 5, 7, …", + "start at position 1, hence p(1) = p(5) = p(7) = … = 1.", + "", + "The substrings 4, 402, 4025, …", + "with respective sums of digits equal to 4, 6, 11, …", + "start at position 2, hence p(4) = p(6) = p(11) = … = 2.", + "", + "The substrings 02, 0252, …", + "with respective sums of digits equal to 2, 9, …", + "start at position 3, hence p(2) = p(9) = … = 3.", + "", + "Note that substring 025 starting at position 3, has a sum of digits equal to 7, but there was an earlier substring (starting at position 1) with a sum of digits equal to 7, so p(7) = 1, not 3.", + "", + "We can verify that, for 0 < k ≤ 103, ∑ p(k) = 4742.", + "", + "Find ∑ p(k), for 0 < k ≤ 2·1015." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler238() {", + " // Good luck!", + " return true;", + "}", + "", + "euler238();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f45c1000cf542c50ff6e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 239: Twenty-two Foolish Primes", + "tests": [ + { + "text": "euler239() should return 0.001887854841.", + "testString": "assert.strictEqual(euler239(), 0.001887854841, 'euler239() should return 0.001887854841.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A set of disks numbered 1 through 100 are placed in a line in random order.", + "", + "What is the probability that we have a partial derangement such that exactly 22 prime number discs are found away from their natural positions?", + "(Any number of non-prime disks may also be found in or out of their natural positions.)", + "", + "Give your answer rounded to 12 places behind the decimal point in the form 0.abcdefghijkl." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler239() {", + " // Good luck!", + " return true;", + "}", + "", + "euler239();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f45d1000cf542c50ff6f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 240: Top Dice", + "tests": [ + { + "text": "euler240() should return 7448717393364182000.", + "testString": "assert.strictEqual(euler240(), 7448717393364182000, 'euler240() should return 7448717393364182000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "There are 1111 ways in which five 6-sided dice (sides numbered 1 to 6) can be rolled so that the top three sum to 15. Some examples are:", + "", + "", + "D1,D2,D3,D4,D5 = 4,3,6,3,5", + "", + "D1,D2,D3,D4,D5 = 4,3,3,5,6", + "", + "D1,D2,D3,D4,D5 = 3,3,3,6,6", + "", + "D1,D2,D3,D4,D5 = 6,6,3,3,3", + "", + "In how many ways can twenty 12-sided dice (sides numbered 1 to 12) be rolled so that the top ten sum to 70?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler240() {", + " // Good luck!", + " return true;", + "}", + "", + "euler240();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f45d1000cf542c50ff70", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 241: Perfection Quotients", + "tests": [ + { + "text": "euler241() should return 482316491800641150.", + "testString": "assert.strictEqual(euler241(), 482316491800641150, 'euler241() should return 482316491800641150.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a positive integer n, let σ(n) be the sum of all divisors of n, so e.g. σ(6) = 1 + 2 + 3 + 6 = 12.", + "", + "", + "A perfect number, as you probably know, is a number with σ(n) = 2n.", + "", + "Let us define the perfection quotient of a positive integer asp(n)= ", + "σ(n)n", + ".", + "Find the sum of all positive integers n ≤ 1018 for which p(n) has the form k + 1⁄2, where k is an integer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler241() {", + " // Good luck!", + " return true;", + "}", + "", + "euler241();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f45f1000cf542c50ff71", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 242: Odd Triplets", + "tests": [ + { + "text": "euler242() should return 997104142249036700.", + "testString": "assert.strictEqual(euler242(), 997104142249036700, 'euler242() should return 997104142249036700.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given the set {1,2,...,n}, we define f(n,k) as the number of its k-element subsets with an odd sum of elements. For example, f(5,3) = 4, since the set {1,2,3,4,5} has four 3-element subsets having an odd sum of elements, i.e.: {1,2,4}, {1,3,5}, {2,3,4} and {2,4,5}.", + "", + "When all three values n, k and f(n,k) are odd, we say that they make ", + "an odd-triplet [n,k,f(n,k)].", + "", + "There are exactly five odd-triplets with n ≤ 10, namely:", + "[1,1,f(1,1) = 1], [5,1,f(5,1) = 3], [5,5,f(5,5) = 1], [9,1,f(9,1) = 5] and [9,9,f(9,9) = 1].", + "", + "How many odd-triplets are there with n ≤ 1012 ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler242() {", + " // Good luck!", + " return true;", + "}", + "", + "euler242();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4601000cf542c50ff73", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 243: Resilience", + "tests": [ + { + "text": "euler243() should return 892371480.", + "testString": "assert.strictEqual(euler243(), 892371480, 'euler243() should return 892371480.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A positive fraction whose numerator is less than its denominator is called a proper fraction.", + "For any denominator, d, there will be d−1 proper fractions; for example, with d = 12:1/12 , 2/12 , 3/12 , 4/12 , 5/12 , 6/12 , 7/12 , 8/12 , 9/12 , 10/12 , 11/12 .", + "", + "", + "We shall call a fraction that cannot be cancelled down a resilient fraction.", + "Furthermore we shall define the resilience of a denominator, R(d), to be the ratio of its proper fractions that are resilient; for example, R(12) = 4/11 .", + "In fact, d = 12 is the smallest denominator having a resilience R(d) < 4/10 .", + "", + "Find the smallest denominator d, having a resilience R(d) < 15499/94744 ." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler243() {", + " // Good luck!", + " return true;", + "}", + "", + "euler243();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4601000cf542c50ff72", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 244: Sliders", + "tests": [ + { + "text": "euler244() should return 96356848.", + "testString": "assert.strictEqual(euler244(), 96356848, 'euler244() should return 96356848.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "You probably know the game Fifteen Puzzle. Here, instead of numbered tiles, we have seven red tiles and eight blue tiles.", + "A move is denoted by the uppercase initial of the direction (Left, Right, Up, Down) in which the tile is slid, e.g. starting from configuration (S), by the sequence LULUR we reach the configuration (E):", + "", + "(S), (E)", + "", + "", + "For each path, its checksum is calculated by (pseudocode):", + "", + "checksum = 0", + "checksum = (checksum × 243 + m1) mod 100 000 007", + "checksum = (checksum × 243 + m2) mod 100 000 007", + "   …", + "checksum = (checksum × 243 + mn) mod 100 000 007", + "where mk is the ASCII value of the kth letter in the move sequence and the ASCII values for the moves are:", + "", + "", + "L76R82U85D68", + "", + "For the sequence LULUR given above, the checksum would be 19761398.", + "Now, starting from configuration (S),", + "find all shortest ways to reach configuration (T).", + "", + "(S), (T)", + "", + "", + "What is the sum of all checksums for the paths having the minimal length?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler244() {", + " // Good luck!", + " return true;", + "}", + "", + "euler244();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4621000cf542c50ff74", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 245: Coresilience", + "tests": [ + { + "text": "euler245() should return 288084712410001.", + "testString": "assert.strictEqual(euler245(), 288084712410001, 'euler245() should return 288084712410001.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We shall call a fraction that cannot be cancelled down a resilient fraction. Furthermore we shall define the resilience of a denominator, R(d), to be the ratio of its proper fractions that are resilient; for example, R(12) = 4⁄11.", + "", + "The resilience of a number d > 1 is then", + "φ(d)d − 1", + ", where φ is Euler's totient function.", + "We further define the coresilience of a number n > 1 as C(n)= ", + "n − φ(n)n − 1.", + "The coresilience of a prime p is C(p)", + "= ", + "1p − 1.", + "Find the sum of all composite integers 1 < n ≤ 2×1011, for which C(n) is a unit fraction." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler245() {", + " // Good luck!", + " return true;", + "}", + "", + "euler245();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4621000cf542c50ff75", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 246: Tangents to an ellipse", + "tests": [ + { + "text": "euler246() should return 810834388.", + "testString": "assert.strictEqual(euler246(), 810834388, 'euler246() should return 810834388.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A definition for an ellipse is:", + "Given a circle c with centre M and radius r and a point G such that d(G,M)euler247() should return 782252.", + "testString": "assert.strictEqual(euler247(), 782252, 'euler247() should return 782252.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the region constrained by 1 ≤ x and 0 ≤ y ≤ 1/x.", + "", + "Let S1 be the largest square that can fit under the curve.", + "Let S2 be the largest square that fits in the remaining area, and so on. ", + "Let the index of Sn be the pair (left, below) indicating the number of squares to the left of Sn and the number of squares below Sn.", + "", + "", + "", + "", + "The diagram shows some such squares labelled by number. ", + "S2 has one square to its left and none below, so the index of S2 is (1,0).", + "It can be seen that the index of S32 is (1,1) as is the index of S50. ", + "50 is the largest n for which the index of Sn is (1,1).", + "", + "", + "What is the largest n for which the index of Sn is (3,3)?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler247() {", + " // Good luck!", + " return true;", + "}", + "", + "euler247();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4651000cf542c50ff77", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 248: Numbers for which Euler’s totient function equals 13!", + "tests": [ + { + "text": "euler248() should return 23507044290.", + "testString": "assert.strictEqual(euler248(), 23507044290, 'euler248() should return 23507044290.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The first number n for which φ(n)=13! is 6227180929.", + "Find the 150,000th such number." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler248() {", + " // Good luck!", + " return true;", + "}", + "", + "euler248();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4671000cf542c50ff79", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 249: Prime Subset Sums", + "tests": [ + { + "text": "euler249() should return 9275262564250418.", + "testString": "assert.strictEqual(euler249(), 9275262564250418, 'euler249() should return 9275262564250418.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let S = {2, 3, 5, ..., 4999} be the set of prime numbers less than 5000.", + "Find the number of subsets of S, the sum of whose elements is a prime number.", + "Enter the rightmost 16 digits as your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler249() {", + " // Good luck!", + " return true;", + "}", + "", + "euler249();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4661000cf542c50ff78", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 250: 250250", + "tests": [ + { + "text": "euler250() should return 1425480602091519.", + "testString": "assert.strictEqual(euler250(), 1425480602091519, 'euler250() should return 1425480602091519.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Find the number of non-empty subsets of {11, 22, 33,..., 250250250250}, the sum of whose elements is divisible by 250. Enter the rightmost 16 digits as your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler250() {", + " // Good luck!", + " return true;", + "}", + "", + "euler250();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4671000cf542c50ff7a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 251: Cardano Triplets", + "tests": [ + { + "text": "euler251() should return 18946051.", + "testString": "assert.strictEqual(euler251(), 18946051, 'euler251() should return 18946051.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A triplet of positive integers (a,b,c) is called a Cardano Triplet if it satisfies the condition:", + "", + "", + "", + "For example, (2,1,5) is a Cardano Triplet.", + "", + "", + "There exist 149 Cardano Triplets for which a+b+c ≤ 1000.", + "", + "", + "Find how many Cardano Triplets exist such that a+b+c ≤ 110,000,000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler251() {", + " // Good luck!", + " return true;", + "}", + "", + "euler251();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4691000cf542c50ff7b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 252: Convex Holes", + "tests": [ + { + "text": "euler252() should return 104924.", + "testString": "assert.strictEqual(euler252(), 104924, 'euler252() should return 104924.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given a set of points on a plane, we define a convex hole to be a convex polygon having as vertices any of the given points and not containing any of the given points in its interior (in addition to the vertices, other given points may lie on the perimeter of the polygon). ", + "", + "", + "As an example, the image below shows a set of twenty points and a few such convex holes. ", + "The convex hole shown as a red heptagon has an area equal to 1049694.5 square units, which is the highest possible area for a convex hole on the given set of points.", + "", + "", + "", + "", + "For our example, we used the first 20 points (T2k−1, T2k), for k = 1,2,…,20, produced with the pseudo-random number generator:", + "", + "S0", + " = ", + " 290797 ", + " Sn+1", + " = ", + " Sn2 mod 50515093", + " Tn", + " = ", + " ( Sn mod 2000 ) − 1000 ", + " ", + "", + "", + "i.e. (527, 144), (−488, 732), (−454, −947), …", + "", + "", + "What is the maximum area for a convex hole on the set containing the first 500 points in the pseudo-random sequence? Specify your answer including one digit after the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler252() {", + " // Good luck!", + " return true;", + "}", + "", + "euler252();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4691000cf542c50ff7c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 253: Tidying up", + "tests": [ + { + "text": "euler253() should return 11.492847.", + "testString": "assert.strictEqual(euler253(), 11.492847, 'euler253() should return 11.492847.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A small child has a “number caterpillar” consisting of forty jigsaw pieces, each with one number on it, which, when connected together in a line, reveal the numbers 1 to 40 in order.", + "", + "Every night, the child's father has to pick up the pieces of the caterpillar that have been scattered across the play room. He picks up the pieces at random and places them in the correct order. As the caterpillar is built up in this way, it forms distinct segments that gradually merge together. The number of segments starts at zero (no pieces placed), generally increases up to about eleven or twelve, then tends to drop again before finishing at a single segment (all pieces placed).", + "", + "For example:", + "", + "Piece Placed", + "Segments So Far121422936434554354……", + "", + "Let M be the maximum number of segments encountered during a random tidy-up of the caterpillar.", + "For a caterpillar of ten pieces, the number of possibilities for each M is", + "", + "M", + "Possibilities1512      2250912      31815264      41418112      5144000      ", + "", + "so the most likely value of M is 3 and the average value is 385643⁄113400 = 3.400732, rounded to six decimal places.", + "", + "The most likely value of M for a forty-piece caterpillar is 11; but what is the average value of M?", + "Give your answer rounded to six decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler253() {", + " // Good luck!", + " return true;", + "}", + "", + "euler253();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f46b1000cf542c50ff7d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 254: Sums of Digit Factorials", + "tests": [ + { + "text": "euler254() should return 8184523820510.", + "testString": "assert.strictEqual(euler254(), 8184523820510, 'euler254() should return 8184523820510.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Define f(n) as the sum of the factorials of the digits of n. For example, f(342) = 3! + 4! + 2! = 32.", + "", + "Define sf(n) as the sum of the digits of f(n). So sf(342) = 3 + 2 = 5.", + "", + "Define g(i) to be the smallest positive integer n such that sf(n) = i. Though sf(342) is 5, sf(25) is also 5, and it can be verified that g(5) is 25.", + "", + "Define sg(i) as the sum of the digits of g(i). So sg(5) = 2 + 5 = 7.", + "", + "Further, it can be verified that g(20) is 267 and ∑ sg(i) for 1 ≤ i ≤ 20 is 156.", + "", + "What is ∑ sg(i) for 1 ≤ i ≤ 150?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler254() {", + " // Good luck!", + " return true;", + "}", + "", + "euler254();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f46d1000cf542c50ff7f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 255: Rounded Square Roots", + "tests": [ + { + "text": "euler255() should return 4.447401118.", + "testString": "assert.strictEqual(euler255(), 4.447401118, 'euler255() should return 4.447401118.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We define the rounded-square-root of a positive integer n as the square root of n rounded to the nearest integer.", + "", + "The following procedure (essentially Heron's method adapted to integer arithmetic) finds the rounded-square-root of n:", + "Let d be the number of digits of the number n.", + "If d is odd, set x0 = 2×10(d-1)⁄2.", + "If d is even, set x0 = 7×10(d-2)⁄2.", + "Repeat:", + "", + "", + "", + "", + "until xk+1 = xk.", + "", + "As an example, let us find the rounded-square-root of n = 4321.n has 4 digits, so x0 = 7×10(4-2)⁄2 = 70.", + "Since x2 = x1, we stop here.", + "So, after just two iterations, we have found that the rounded-square-root of 4321 is 66 (the actual square root is 65.7343137…).", + "", + "The number of iterations required when using this method is surprisingly low.", + "For example, we can find the rounded-square-root of a 5-digit integer (10,000 ≤ n ≤ 99,999) with an average of 3.2102888889 iterations (the average value was rounded to 10 decimal places).", + "", + "Using the procedure described above, what is the average number of iterations required to find the rounded-square-root of a 14-digit number (1013 ≤ n < 1014)?", + "Give your answer rounded to 10 decimal places.", + "", + "Note: The symbols ⌊x⌋ and ⌈x⌉ represent the floor function and ceiling function respectively." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler255() {", + " // Good luck!", + " return true;", + "}", + "", + "euler255();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f46c1000cf542c50ff7e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 256: Tatami-Free Rooms", + "tests": [ + { + "text": "euler256() should return 85765680.", + "testString": "assert.strictEqual(euler256(), 85765680, 'euler256() should return 85765680.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Tatami are rectangular mats, used to completely cover the floor of a room, without overlap.", + "", + "Assuming that the only type of available tatami has dimensions 1×2, there are obviously some limitations for the shape and size of the rooms that can be covered.", + "", + "For this problem, we consider only rectangular rooms with integer dimensions a, b and even size s = a·b.", + "We use the term 'size' to denote the floor surface area of the room, and — without loss of generality — we add the condition a ≤ b.", + "", + "There is one rule to follow when laying out tatami: there must be no points where corners of four different mats meet.", + "For example, consider the two arrangements below for a 4×4 room:", + "", + "", + "", + "The arrangement on the left is acceptable, whereas the one on the right is not: a red \"X\" in the middle, marks the point where four tatami meet.", + "", + "Because of this rule, certain even-sized rooms cannot be covered with tatami: we call them tatami-free rooms.", + "Further, we define T(s) as the number of tatami-free rooms of size s.", + "", + "The smallest tatami-free room has size s = 70 and dimensions 7×10.", + "All the other rooms of size s = 70 can be covered with tatami; they are: 1×70, 2×35 and 5×14.", + "Hence, T(70) = 1.", + "", + "Similarly, we can verify that T(1320) = 5 because there are exactly 5 tatami-free rooms of size s = 1320:", + "20×66, 22×60, 24×55, 30×44 and 33×40.", + "In fact, s = 1320 is the smallest room-size s for which T(s) = 5.", + "", + "Find the smallest room-size s for which T(s) = 200." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler256() {", + " // Good luck!", + " return true;", + "}", + "", + "euler256();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f46e1000cf542c50ff80", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 257: Angular Bisectors", + "tests": [ + { + "text": "euler257() should return 139012411.", + "testString": "assert.strictEqual(euler257(), 139012411, 'euler257() should return 139012411.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given is an integer sided triangle ABC with sides a ≤ b ≤ c. ", + "(AB = c, BC = a and AC = b).", + "The angular bisectors of the triangle intersect the sides at points E, F and G (see picture below).", + "", + "", + "", + "", + "The segments EF, EG and FG partition the triangle ABC into four smaller triangles: AEG, BFE, CGF and EFG.", + "It can be proven that for each of these four triangles the ratio area(ABC)/area(subtriangle) is rational.", + "However, there exist triangles for which some or all of these ratios are integral.", + "", + "", + "How many triangles ABC with perimeter≤100,000,000 exist so that the ratio area(ABC)/area(AEG) is integral?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler257() {", + " // Good luck!", + " return true;", + "}", + "", + "euler257();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f46e1000cf542c50ff81", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 258: A lagged Fibonacci sequence", + "tests": [ + { + "text": "euler258() should return 12747994.", + "testString": "assert.strictEqual(euler258(), 12747994, 'euler258() should return 12747994.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A sequence is defined as:", + "", + "gk = 1, for 0 ≤ k ≤ 1999", + "gk = gk-2000 + gk-1999, for k ≥ 2000.", + "Find gk mod 20092010 for k = 1018." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler258() {", + " // Good luck!", + " return true;", + "}", + "", + "euler258();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4701000cf542c50ff82", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 259: Reachable Numbers", + "tests": [ + { + "text": "euler259() should return 20101196798.", + "testString": "assert.strictEqual(euler259(), 20101196798, 'euler259() should return 20101196798.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A positive integer will be called reachable if it can result from an arithmetic expression obeying the following rules:", + "", + "Uses the digits 1 through 9, in that order and exactly once each.", + "Any successive digits can be concatenated (for example, using the digits 2, 3 and 4 we obtain the number 234).", + "Only the four usual binary arithmetic operations (addition, subtraction, multiplication and division) are allowed.", + "Each operation can be used any number of times, or not at all.", + "Unary minus is not allowed.", + "Any number of (possibly nested) parentheses may be used to define the order of operations.", + "For example, 42 is reachable, since (1/23) * ((4*5)-6) * (78-9) = 42.", + "", + "What is the sum of all positive reachable integers?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler259() {", + " // Good luck!", + " return true;", + "}", + "", + "euler259();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4701000cf542c50ff83", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 260: Stone Game", + "tests": [ + { + "text": "euler260() should return 167542057.", + "testString": "assert.strictEqual(euler260(), 167542057, 'euler260() should return 167542057.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A game is played with three piles of stones and two players.", + "At her turn, a player removes one or more stones from the piles. However, if she takes stones from more than one pile, she must remove the same number of stones from each of the selected piles.", + "", + "In other words, the player chooses some N>0 and removes:", + "N stones from any single pile; or", + "N stones from each of any two piles (2N total); or", + "N stones from each of the three piles (3N total).", + "The player taking the last stone(s) wins the game.", + "", + "A winning configuration is one where the first player can force a win.", + "For example, (0,0,13), (0,11,11) and (5,5,5) are winning configurations because the first player can immediately remove all stones.", + "", + "A losing configuration is one where the second player can force a win, no matter what the first player does. ", + "For example, (0,1,2) and (1,3,3) are losing configurations: any legal move leaves a winning configuration for the second player.", + "", + "Consider all losing configurations (xi,yi,zi) where xi ≤ yi ≤ zi ≤ 100.", + "We can verify that Σ(xi+yi+zi) = 173895 for these.", + "", + "Find Σ(xi+yi+zi) where (xi,yi,zi) ranges over the losing configurations", + "with xi ≤ yi ≤ zi ≤ 1000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler260() {", + " // Good luck!", + " return true;", + "}", + "", + "euler260();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4711000cf542c50ff84", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 261: Pivotal Square Sums", + "tests": [ + { + "text": "euler261() should return 238890850232021.", + "testString": "assert.strictEqual(euler261(), 238890850232021, 'euler261() should return 238890850232021.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let us call a positive integer k a square-pivot, if there is a pair of integers m > 0 and n ≥ k, such that the sum of the (m+1) consecutive squares up to k equals the sum of the m consecutive squares from (n+1) on:", + "", + "(k-m)2 + ... + k2 = (n+1)2 + ... + (n+m)2.", + "", + "Some small square-pivots are", + "4: 32 + 42", + " = 52", + "21: 202 + 212 = 292", + "24: 212 + 222 + 232 + 242 = 252 + 262 + 272", + "110: 1082 + 1092 + 1102 = 1332 + 1342Find the sum of all distinct square-pivots ≤ 1010." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler261() {", + " // Good luck!", + " return true;", + "}", + "", + "euler261();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4731000cf542c50ff85", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 262: Mountain Range", + "tests": [ + { + "text": "euler262() should return 2531.205.", + "testString": "assert.strictEqual(euler262(), 2531.205, 'euler262() should return 2531.205.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The following equation represents the continuous topography of a mountainous region, giving the elevation h at any point (x,y):", + "", + "", + "", + "", + "A mosquito intends to fly from A(200,200) to B(1400,1400), without leaving the area given by 0 ≤ x, y ≤ 1600.", + "", + "Because of the intervening mountains, it first rises straight up to a point A', having elevation f. Then, while remaining at the same elevation f, it flies around any obstacles until it arrives at a point B' directly above B.", + "", + "First, determine fmin which is the minimum constant elevation allowing such a trip from A to B, while remaining in the specified area.", + "Then, find the length of the shortest path between A' and B', while flying at that constant elevation fmin.", + "", + "Give that length as your answer, rounded to three decimal places.", + "", + "Note: For convenience, the elevation function shown above is repeated below, in a form suitable for most programming languages:", + "h=( 5000-0.005*(x*x+y*y+x*y)+12.5*(x+y) ) * exp( -abs(0.000001*(x*x+y*y)-0.0015*(x+y)+0.7) )" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler262() {", + " // Good luck!", + " return true;", + "}", + "", + "euler262();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4741000cf542c50ff86", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 263: An engineers' dream come true", + "tests": [ + { + "text": "euler263() should return 2039506520.", + "testString": "assert.strictEqual(euler263(), 2039506520, 'euler263() should return 2039506520.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the number 6. The divisors of 6 are: 1,2,3 and 6.", + "Every number from 1 up to and including 6 can be written as a sum of distinct divisors of 6:", + "1=1, 2=2, 3=1+2, 4=1+3, 5=2+3, 6=6.", + "A number n is called a practical number if every number from 1 up to and including n can be expressed as a sum of distinct divisors of n.", + "", + "", + "A pair of consecutive prime numbers with a difference of six is called a sexy pair (since \"sex\" is the Latin word for \"six\"). The first sexy pair is (23, 29).", + "", + "", + "We may occasionally find a triple-pair, which means three consecutive sexy prime pairs, such that the second member of each pair is the first member of the next pair.", + "", + "", + "We shall call a number n such that :", + "(n-9, n-3), (n-3,n+3), (n+3, n+9) form a triple-pair, and ", + "the numbers n-8, n-4, n, n+4 and n+8 are all practical,", + " ", + "an engineers’ paradise.", + "", + "", + "Find the sum of the first four engineers’ paradises." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler263() {", + " // Good luck!", + " return true;", + "}", + "", + "euler263();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4751000cf542c50ff87", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 264: Triangle Centres", + "tests": [ + { + "text": "euler264() should return 2816417.1055.", + "testString": "assert.strictEqual(euler264(), 2816417.1055, 'euler264() should return 2816417.1055.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider all the triangles having:", + "All their vertices on lattice points.", + "Circumcentre at the origin O.", + "Orthocentre at the point H(5, 0).", + "There are nine such triangles having a perimeter ≤ 50.", + "Listed and shown in ascending order of their perimeter, they are:", + "", + "A(-4, 3), B(5, 0), C(4, -3)", + "A(4, 3), B(5, 0), C(-4, -3)", + "A(-3, 4), B(5, 0), C(3, -4)", + "A(3, 4), B(5, 0), C(-3, -4)", + "A(0, 5), B(5, 0), C(0, -5)", + "A(1, 8), B(8, -1), C(-4, -7)", + "A(8, 1), B(1, -8), C(-4, 7)", + "A(2, 9), B(9, -2), C(-6, -7)", + "A(9, 2), B(2, -9), C(-6, 7)", + "", + "The sum of their perimeters, rounded to four decimal places, is 291.0089.", + "", + "Find all such triangles with a perimeter ≤ 105.", + "Enter as your answer the sum of their perimeters rounded to four decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler264() {", + " // Good luck!", + " return true;", + "}", + "", + "euler264();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4761000cf542c50ff88", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 265: Binary Circles", + "tests": [ + { + "text": "euler265() should return 209110240768.", + "testString": "assert.strictEqual(euler265(), 209110240768, 'euler265() should return 209110240768.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "2N binary digits can be placed in a circle so that all the N-digit clockwise subsequences are distinct.", + "", + "For N=3, two such circular arrangements are possible, ignoring rotations:", + "", + "", + "For the first arrangement, the 3-digit subsequences, in clockwise order, are: 000, 001, 010, 101, 011, 111, 110 and 100.", + "", + "Each circular arrangement can be encoded as a number by concatenating the binary digits starting with the subsequence of all zeros as the most significant bits and proceeding clockwise. The two arrangements for N=3 are thus represented as 23 and 29:", + "00010111 2 = 23", + "00011101 2 = 29", + "", + "Calling S(N) the sum of the unique numeric representations, we can see that S(3) = 23 + 29 = 52.", + "", + "Find S(5)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler265() {", + " // Good luck!", + " return true;", + "}", + "", + "euler265();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4771000cf542c50ff89", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 266: Pseudo Square Root", + "tests": [ + { + "text": "euler266() should return 1096883702440585.", + "testString": "assert.strictEqual(euler266(), 1096883702440585, 'euler266() should return 1096883702440585.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The divisors of 12 are: 1,2,3,4,6 and 12.", + "The largest divisor of 12 that does not exceed the square root of 12 is 3.", + "We shall call the largest divisor of an integer n that does not exceed the square root of n the pseudo square root (PSR) of n.", + "It can be seen that PSR(3102)=47.", + "", + "", + "Let p be the product of the primes below 190.", + "Find PSR(p) mod 1016." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler266() {", + " // Good luck!", + " return true;", + "}", + "", + "euler266();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4771000cf542c50ff8a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 267: Billionaire", + "tests": [ + { + "text": "euler267() should return 0.999992836187.", + "testString": "assert.strictEqual(euler267(), 0.999992836187, 'euler267() should return 0.999992836187.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "You are given a unique investment opportunity.", + "Starting with £1 of capital, you can choose a fixed proportion, f, of your capital to bet on a fair coin toss repeatedly for 1000 tosses.", + "Your return is double your bet for heads and you lose your bet for tails.", + "For example, if f = 1/4, for the first toss you bet £0.25, and if heads comes up you win £0.5 and so then have £1.5. You then bet £0.375 and if the second toss is tails, you have £1.125.", + "Choosing f to maximize your chances of having at least £1,000,000,000 after 1,000 flips, what is the chance that you become a billionaire?", + "All computations are assumed to be exact (no rounding), but give your answer rounded to 12 digits behind the decimal point in the form 0.abcdefghijkl." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler267() {", + " // Good luck!", + " return true;", + "}", + "", + "euler267();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4791000cf542c50ff8b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 268: Counting numbers with at least four distinct prime factors less than 100", + "tests": [ + { + "text": "euler268() should return 785478606870985.", + "testString": "assert.strictEqual(euler268(), 785478606870985, 'euler268() should return 785478606870985.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It can be verified that there are 23 positive integers less than 1000 that are divisible by at least four distinct primes less than 100.", + "", + "Find how many positive integers less than 1016 are divisible by at least four distinct primes less than 100." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler268() {", + " // Good luck!", + " return true;", + "}", + "", + "euler268();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4791000cf542c50ff8c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 269: Polynomials with at least one integer root", + "tests": [ + { + "text": "euler269() should return 1311109198529286.", + "testString": "assert.strictEqual(euler269(), 1311109198529286, 'euler269() should return 1311109198529286.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A root or zero of a polynomial P(x) is a solution to the equation P(x) = 0. ", + "Define Pn as the polynomial whose coefficients are the digits of n.", + "For example, P5703(x) = 5x3 + 7x2 + 3.", + "", + "We can see that:Pn(0) is the last digit of n,", + "Pn(1) is the sum of the digits of n,", + "Pn(10) is n itself.Define Z(k) as the number of positive integers, n, not exceeding k for which the polynomial Pn has at least one integer root.", + "", + "It can be verified that Z(100 000) is 14696.", + "", + "What is Z(1016)?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler269() {", + " // Good luck!", + " return true;", + "}", + "", + "euler269();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f47c1000cf542c50ff8e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 270: Cutting Squares", + "tests": [ + { + "text": "euler270() should return 82282080.", + "testString": "assert.strictEqual(euler270(), 82282080, 'euler270() should return 82282080.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A square piece of paper with integer dimensions N×N is placed with a corner at the origin and two of its sides along the x- and y-axes. Then, we cut it up respecting the following rules:", + "We only make straight cuts between two points lying on different sides of the square, and having integer coordinates.", + "Two cuts cannot cross, but several cuts can meet at the same border point.", + "Proceed until no more legal cuts can be made.", + "Counting any reflections or rotations as distinct, we call C(N) the number of ways to cut an N×N square. For example, C(1) = 2 and C(2) = 30 (shown below).", + "", + "", + "What is C(30) mod 108 ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler270() {", + " // Good luck!", + " return true;", + "}", + "", + "euler270();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f47b1000cf542c50ff8d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 271: Modular Cubes, part 1", + "tests": [ + { + "text": "euler271() should return 4617456485273130000.", + "testString": "assert.strictEqual(euler271(), 4617456485273130000, 'euler271() should return 4617456485273130000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a positive number n, define S(n) as the sum of the integers x, for which 1euler272() should return 8495585919506151000.", + "testString": "assert.strictEqual(euler272(), 8495585919506151000, 'euler272() should return 8495585919506151000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a positive number n, define C(n) as the number of the integers x, for which 1euler273() should return 2032447591196869000.", + "testString": "assert.strictEqual(euler273(), 2032447591196869000, 'euler273() should return 2032447591196869000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider equations of the form: a2 + b2 = N, 0 ≤ a ≤ b, a, b and N integer.", + "", + "For N=65 there are two solutions:", + "a=1, b=8 and a=4, b=7.", + "We call S(N) the sum of the values of a of all solutions of a2 + b2 = N, 0 ≤ a ≤ b, a, b and N integer.", + "Thus S(65) = 1 + 4 = 5.", + "Find ∑S(N), for all squarefree N only divisible by primes of the form 4k+1 with 4k+1 < 150." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler273() {", + " // Good luck!", + " return true;", + "}", + "", + "euler273();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f47f1000cf542c50ff91", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 274: Divisibility Multipliers", + "tests": [ + { + "text": "euler274() should return 1601912348822.", + "testString": "assert.strictEqual(euler274(), 1601912348822, 'euler274() should return 1601912348822.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For each integer p > 1 coprime to 10 there is a positive divisibility multiplier m < p which preserves divisibility by p for the following function on any positive integer, n:", + "", + "f(n) = (all but the last digit of n) + (the last digit of n) * m", + "", + "That is, if m is the divisibility multiplier for p, then f(n) is divisible by p if and only if n is divisible by p.", + "", + "(When n is much larger than p, f(n) will be less than n and repeated application of f provides a multiplicative divisibility test for p.)", + "", + "For example, the divisibility multiplier for 113 is 34.", + "", + "f(76275) = 7627 + 5 * 34 = 7797 : 76275 and 7797 are both divisible by 113f(12345) = 1234 + 5 * 34 = 1404 : 12345 and 1404 are both not divisible by 113", + "", + "The sum of the divisibility multipliers for the primes that are coprime to 10 and less than 1000 is 39517. What is the sum of the divisibility multipliers for the primes that are coprime to 10 and less than 107?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler274() {", + " // Good luck!", + " return true;", + "}", + "", + "euler274();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4801000cf542c50ff92", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 275: Balanced Sculptures", + "tests": [ + { + "text": "euler275() should return 15030564.", + "testString": "assert.strictEqual(euler275(), 15030564, 'euler275() should return 15030564.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let us define a balanced sculpture of order n as follows:", + "A polyomino made up of n+1 tiles known as the blocks (n tiles) and the plinth (remaining tile);", + "the plinth has its centre at position (x = 0, y = 0);", + "the blocks have y-coordinates greater than zero (so the plinth is the unique lowest tile);", + "the centre of mass of all the blocks, combined, has x-coordinate equal to zero.", + "When counting the sculptures, any arrangements which are simply reflections about the y-axis, are not counted as distinct. For example, the 18 balanced sculptures of order 6 are shown below; note that each pair of mirror images (about the y-axis) is counted as one sculpture:", + "", + "", + "There are 964 balanced sculptures of order 10 and 360505 of order 15.How many balanced sculptures are there of order 18?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler275() {", + " // Good luck!", + " return true;", + "}", + "", + "euler275();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4801000cf542c50ff93", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 276: Primitive Triangles", + "tests": [ + { + "text": "euler276() should return 5777137137739633000.", + "testString": "assert.strictEqual(euler276(), 5777137137739633000, 'euler276() should return 5777137137739633000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the triangles with integer sides a, b and c with a ≤ b ≤ c.", + "An integer sided triangle (a,b,c) is called primitive if gcd(a,b,c)=1. ", + "How many primitive integer sided triangles exist with a perimeter not exceeding 10 000 000?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler276() {", + " // Good luck!", + " return true;", + "}", + "", + "euler276();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4811000cf542c50ff94", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 277: A Modified Collatz sequence", + "tests": [ + { + "text": "euler277() should return 1125977393124310.", + "testString": "assert.strictEqual(euler277(), 1125977393124310, 'euler277() should return 1125977393124310.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A modified Collatz sequence of integers is obtained from a starting value a1 in the following way:", + "", + "an+1 = an/3 if an is divisible by 3. We shall denote this as a large downward step, \"D\".", + "", + "an+1 = (4an + 2)/3 if an divided by 3 gives a remainder of 1. We shall denote this as an upward step, \"U\".", + "", + "", + "an+1 = (2an - 1)/3 if an divided by 3 gives a remainder of 2. We shall denote this as a small downward step, \"d\".", + "", + "", + "", + "", + "The sequence terminates when some an = 1.", + "", + "", + "Given any integer, we can list out the sequence of steps.", + "For instance if a1=231, then the sequence {an}={231,77,51,17,11,7,10,14,9,3,1} corresponds to the steps \"DdDddUUdDD\".", + "", + "", + "Of course, there are other sequences that begin with that same sequence \"DdDddUUdDD....\".", + "For instance, if a1=1004064, then the sequence is DdDddUUdDDDdUDUUUdDdUUDDDUdDD.", + "In fact, 1004064 is the smallest possible a1 > 106 that begins with the sequence DdDddUUdDD.", + "", + "", + "What is the smallest a1 > 1015 that begins with the sequence \"UDDDUdddDDUDDddDdDddDDUDDdUUDd\"?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler277() {", + " // Good luck!", + " return true;", + "}", + "", + "euler277();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4831000cf542c50ff95", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 278: Linear Combinations of Semiprimes", + "tests": [ + { + "text": "euler278() should return 1228215747273908500.", + "testString": "assert.strictEqual(euler278(), 1228215747273908500, 'euler278() should return 1228215747273908500.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given the values of integers 1 < a1 < a2 <... < an, consider the linear combinationq1a1 + q2a2 + ... + qnan = b, using only integer values qk ≥ 0. ", + "", + "", + "Note that for a given set of ak, it may be that not all values of b are possible.", + "For instance, if a1 = 5 and a2 = 7, there are no q1 ≥ 0 and q2 ≥ 0 such that b could be ", + "1, 2, 3, 4, 6, 8, 9, 11, 13, 16, 18 or 23.", + "", + "In fact, 23 is the largest impossible value of b for a1 = 5 and a2 = 7. We therefore call f(5, 7) = 23. Similarly, it can be shown that f(6, 10, 15)=29 and f(14, 22, 77) = 195.", + "", + "", + "Find ∑ f(p*q,p*r,q*r), where p, q and r are prime numbers and p < q < r < 5000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler278() {", + " // Good luck!", + " return true;", + "}", + "", + "euler278();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4841000cf542c50ff96", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 279: Triangles with integral sides and an integral angle", + "tests": [ + { + "text": "euler279() should return 416577688.", + "testString": "assert.strictEqual(euler279(), 416577688, 'euler279() should return 416577688.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "How many triangles are there with integral sides, at least one integral angle (measured in degrees), and a perimeter that does not exceed 108?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler279() {", + " // Good luck!", + " return true;", + "}", + "", + "euler279();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4841000cf542c50ff97", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 280: Ant and seeds", + "tests": [ + { + "text": "euler280() should return 430.088247.", + "testString": "assert.strictEqual(euler280(), 430.088247, 'euler280() should return 430.088247.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A laborious ant walks randomly on a 5x5 grid. The walk starts from the central square. At each step, the ant moves to an adjacent square at random, without leaving the grid; thus there are 2, 3 or 4 possible moves at each step depending on the ant's position.", + "", + "At the start of the walk, a seed is placed on each square of the lower row. When the ant isn't carrying a seed and reaches a square of the lower row containing a seed, it will start to carry the seed. The ant will drop the seed on the first empty square of the upper row it eventually reaches.", + "", + "What's the expected number of steps until all seeds have been dropped in the top row? ", + "Give your answer rounded to 6 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler280() {", + " // Good luck!", + " return true;", + "}", + "", + "euler280();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4861000cf542c50ff98", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 281: Pizza Toppings", + "tests": [ + { + "text": "euler281() should return 1485776387445623.", + "testString": "assert.strictEqual(euler281(), 1485776387445623, 'euler281() should return 1485776387445623.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "You are given a pizza (perfect circle) that has been cut into m·n equal pieces and you want to have exactly one topping on each slice.", + "", + "Let f(m,n) denote the number of ways you can have toppings on the pizza with m different toppings (m ≥ 2), using each topping on exactly n slices (n ≥ 1). Reflections are considered distinct, rotations are not. ", + "", + "Thus, for instance, f(2,1) = 1, f(2,2) = f(3,1) = 2 and f(3,2) = 16. f(3,2) is shown below:", + "", + "", + "", + "Find the sum of all f(m,n) such that f(m,n) ≤ 1015." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler281() {", + " // Good luck!", + " return true;", + "}", + "", + "euler281();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4861000cf542c50ff99", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 282: The Ackermann function", + "tests": [ + { + "text": "euler282() should return 1098988351.", + "testString": "assert.strictEqual(euler282(), 1098988351, 'euler282() should return 1098988351.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For non-negative integers m, n, the Ackermann function A(m, n) is defined as follows:", + "", + "", + "", + "For example A(1, 0) = 2, A(2, 2) = 7 and A(3, 4) = 125.", + "", + "", + "Find A(n, n) and give your answer mod 148." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler282() {", + " // Good luck!", + " return true;", + "}", + "", + "euler282();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4881000cf542c50ff9a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 283: Integer sided triangles for which the area/perimeter ratio is integral", + "tests": [ + { + "text": "euler283() should return 28038042525570324.", + "testString": "assert.strictEqual(euler283(), 28038042525570324, 'euler283() should return 28038042525570324.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the triangle with sides 6, 8 and 10. It can be seen that the perimeter and the area are both equal to 24. ", + "So the area/perimeter ratio is equal to 1.", + "Consider also the triangle with sides 13, 14 and 15. The perimeter equals 42 while the area is equal to 84. ", + "So for this triangle the area/perimeter ratio is equal to 2.", + "", + "", + "Find the sum of the perimeters of all integer sided triangles for which the area/perimeter ratios are equal to positive integers not exceeding 1000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler283() {", + " // Good luck!", + " return true;", + "}", + "", + "euler283();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4891000cf542c50ff9b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 284: Steady Squares", + "tests": [ + { + "text": "euler284() should return 5a411d7b.", + "testString": "assert.strictEqual(euler284(), 5a411d7b, 'euler284() should return 5a411d7b.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The 3-digit number 376 in the decimal numbering system is an example of numbers with the special property that its square ends with the same digits: 3762 = 141376. Let's call a number with this property a steady square.", + "", + "Steady squares can also be observed in other numbering systems. In the base 14 numbering system, the 3-digit number c37 is also a steady square: c372 = aa0c37, and the sum of its digits is c+3+7=18 in the same numbering system. The letters a, b, c and d are used for the 10, 11, 12 and 13 digits respectively, in a manner similar to the hexadecimal numbering system.", + "", + "For 1 ≤ n ≤ 9, the sum of the digits of all the n-digit steady squares in the base 14 numbering system is 2d8 (582 decimal). Steady squares with leading 0's are not allowed.", + "", + "Find the sum of the digits of all the n-digit steady squares in the base 14 numbering system for", + "1 ≤ n ≤ 10000 (decimal) and give your answer in the base 14 system using lower case letters where necessary." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler284() {", + " // Good luck!", + " return true;", + "}", + "", + "euler284();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f48a1000cf542c50ff9c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 285: Pythagorean odds", + "tests": [ + { + "text": "euler285() should return 157055.80999.", + "testString": "assert.strictEqual(euler285(), 157055.80999, 'euler285() should return 157055.80999.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Albert chooses a positive integer k, then two real numbers a, b are randomly chosen in the interval [0,1] with uniform distribution.", + "The square root of the sum (k·a+1)2 + (k·b+1)2 is then computed and rounded to the nearest integer. If the result is equal to k, he scores k points; otherwise he scores nothing.", + "", + "For example, if k = 6, a = 0.2 and b = 0.85, then (k·a+1)2 + (k·b+1)2 = 42.05.", + "The square root of 42.05 is 6.484... and when rounded to the nearest integer, it becomes 6.", + "This is equal to k, so he scores 6 points.", + "", + "It can be shown that if he plays 10 turns with k = 1, k = 2, ..., k = 10, the expected value of his total score, rounded to five decimal places, is 10.20914.", + "", + "If he plays 105 turns with k = 1, k = 2, k = 3, ..., k = 105, what is the expected value of his total score, rounded to five decimal places?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler285() {", + " // Good luck!", + " return true;", + "}", + "", + "euler285();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f48a1000cf542c50ff9d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 286: Scoring probabilities", + "tests": [ + { + "text": "euler286() should return 52.6494571953.", + "testString": "assert.strictEqual(euler286(), 52.6494571953, 'euler286() should return 52.6494571953.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Barbara is a mathematician and a basketball player. She has found that the probability of scoring a point when shooting from a distance x is exactly (1 - x/q), where q is a real constant greater than 50.", + "", + "During each practice run, she takes shots from distances x = 1, x = 2, ..., x = 50 and, according to her records, she has precisely a 2 % chance to score a total of exactly 20 points.", + "", + "Find q and give your answer rounded to 10 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler286() {", + " // Good luck!", + " return true;", + "}", + "", + "euler286();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f48b1000cf542c50ff9e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 287: Quadtree encoding (a simple compression algorithm)", + "tests": [ + { + "text": "euler287() should return 313135496.", + "testString": "assert.strictEqual(euler287(), 313135496, 'euler287() should return 313135496.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The quadtree encoding allows us to describe a 2N×2N black and white image as a sequence of bits (0 and 1). Those sequences are to be read from left to right like this:", + "the first bit deals with the complete 2N×2N region;", + "\"0\" denotes a split:", + "the current 2n×2n region is divided into 4 sub-regions of dimension 2n-1×2n-1,", + "the next bits contains the description of the top left, top right, bottom left and bottom right sub-regions - in that order;", + "\"10\" indicates that the current region contains only black pixels;", + "\"11\" indicates that the current region contains only white pixels.Consider the following 4×4 image (colored marks denote places where a split can occur):", + "", + "This image can be described by several sequences, for example :", + "\"001010101001011111011010101010\", of length 30, or", + "\"0100101111101110\", of length 16, which is the minimal sequence for this image.", + "", + "For a positive integer N, define DN as the 2N×2N image with the following coloring scheme:", + "the pixel with coordinates x = 0, y = 0 corresponds to the bottom left pixel,", + "if (x - 2N-1)2 + (y - 2N-1)2 ≤ 22N-2 then the pixel is black,", + "otherwise the pixel is white.What is the length of the minimal sequence describing D24 ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler287() {", + " // Good luck!", + " return true;", + "}", + "", + "euler287();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f48d1000cf542c50ff9f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 288: An enormous factorial", + "tests": [ + { + "text": "euler288() should return 605857431263982000.", + "testString": "assert.strictEqual(euler288(), 605857431263982000, 'euler288() should return 605857431263982000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For any prime p the number N(p,q) is defined by", + "N(p,q) = ∑n=0 to q Tn*pn with Tn generated by the following random number generator:", + "", + "S0 = 290797", + "Sn+1 = Sn2 mod 50515093", + "Tn = Sn mod p", + "", + "", + "Let Nfac(p,q) be the factorial of N(p,q).", + "Let NF(p,q) be the number of factors p in Nfac(p,q).", + "", + "", + "You are given that NF(3,10000) mod 320=624955285.", + "", + "", + "Find NF(61,107) mod 6110" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler288() {", + " // Good luck!", + " return true;", + "}", + "", + "euler288();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f48d1000cf542c50ffa0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 289: Eulerian Cycles", + "tests": [ + { + "text": "euler289() should return 6567944538.", + "testString": "assert.strictEqual(euler289(), 6567944538, 'euler289() should return 6567944538.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let C(x,y) be a circle passing through the points (x, y), (x, y+1), (x+1, y) and (x+1, y+1).", + "", + "For positive integers m and n, let E(m,n) be a configuration which consists of the m·n circles:", + "{ C(x,y): 0 ≤ x < m, 0 ≤ y < n, x and y are integers }", + "", + "An Eulerian cycle on E(m,n) is a closed path that passes through each arc exactly once.", + "Many such paths are possible on E(m,n), but we are only interested in those which are not self-crossing: ", + "A non-crossing path just touches itself at lattice points, but it never crosses itself.", + "", + "The image below shows E(3,3) and an example of an Eulerian non-crossing path.", + "", + "Let L(m,n) be the number of Eulerian non-crossing paths on E(m,n).", + "For example, L(1,2) = 2, L(2,2) = 37 and L(3,3) = 104290.", + "", + "Find L(6,10) mod 1010." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler289() {", + " // Good luck!", + " return true;", + "}", + "", + "euler289();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f48f1000cf542c50ffa1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 290: Digital Signature", + "tests": [ + { + "text": "euler290() should return 20444710234716470.", + "testString": "assert.strictEqual(euler290(), 20444710234716470, 'euler290() should return 20444710234716470.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "How many integers 0 ≤ n < 1018 have the property that the sum of the digits of n equals the sum of digits of 137n?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler290() {", + " // Good luck!", + " return true;", + "}", + "", + "euler290();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f48f1000cf542c50ffa2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 291: Panaitopol Primes", + "tests": [ + { + "text": "euler291() should return 4037526.", + "testString": "assert.strictEqual(euler291(), 4037526, 'euler291() should return 4037526.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A prime number p is called a Panaitopol prime if for some positive integersx and y.", + "", + "", + "Find how many Panaitopol primes are less than 5×1015." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler291() {", + " // Good luck!", + " return true;", + "}", + "", + "euler291();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4911000cf542c50ffa3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 292: Pythagorean Polygons", + "tests": [ + { + "text": "euler292() should return 3600060866.", + "testString": "assert.strictEqual(euler292(), 3600060866, 'euler292() should return 3600060866.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We shall define a pythagorean polygon to be a convex polygon with the following properties:there are at least three vertices,", + "no three vertices are aligned,", + "each vertex has integer coordinates,", + "each edge has integer length.For a given integer n, define P(n) as the number of distinct pythagorean polygons for which the perimeter is ≤ n.", + "Pythagorean polygons should be considered distinct as long as none is a translation of another.", + "", + "You are given that P(4) = 1, P(30) = 3655 and P(60) = 891045.", + "Find P(120)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler292() {", + " // Good luck!", + " return true;", + "}", + "", + "euler292();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4931000cf542c50ffa4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 293: Pseudo-Fortunate Numbers", + "tests": [ + { + "text": "euler293() should return 2209.", + "testString": "assert.strictEqual(euler293(), 2209, 'euler293() should return 2209.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An even positive integer N will be called admissible, if it is a power of 2 or its distinct prime factors are consecutive primes.", + "The first twelve admissible numbers are 2,4,6,8,12,16,18,24,30,32,36,48.", + "", + "", + "If N is admissible, the smallest integer M > 1 such that N+M is prime, will be called the pseudo-Fortunate number for N.", + "", + "", + "For example, N=630 is admissible since it is even and its distinct prime factors are the consecutive primes 2,3,5 and 7. ", + "The next prime number after 631 is 641; hence, the pseudo-Fortunate number for 630 is M=11.", + "It can also be seen that the pseudo-Fortunate number for 16 is 3.", + "", + "", + "Find the sum of all distinct pseudo-Fortunate numbers for admissible numbers N less than 109." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler293() {", + " // Good luck!", + " return true;", + "}", + "", + "euler293();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4931000cf542c50ffa5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 294: Sum of digits - experience #23", + "tests": [ + { + "text": "euler294() should return 789184709.", + "testString": "assert.strictEqual(euler294(), 789184709, 'euler294() should return 789184709.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a positive integer k, define d(k) as the sum of the digits of k in its usual decimal representation.", + "Thus d(42) = 4+2 = 6.", + "", + "", + "For a positive integer n, define S(n) as the number of positive integers k < 10n with the following properties :", + "k is divisible by 23 and", + "d(k) = 23.", + "", + "You are given that S(9) = 263626 and S(42) = 6377168878570056.", + "", + "", + "Find S(1112) and give your answer mod 109." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler294() {", + " // Good luck!", + " return true;", + "}", + "", + "euler294();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4931000cf542c50ffa6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 295: Lenticular holes", + "tests": [ + { + "text": "euler295() should return 4884650818.", + "testString": "assert.strictEqual(euler295(), 4884650818, 'euler295() should return 4884650818.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We call the convex area enclosed by two circles a lenticular hole if:", + "The centres of both circles are on lattice points.", + "The two circles intersect at two distinct lattice points.", + "The interior of the convex area enclosed by both circles does not contain any lattice points.", + "", + "Consider the circles:", + "C0: x2+y2=25", + "C1: (x+4)2+(y-4)2=1", + "C2: (x-12)2+(y-4)2=65", + "", + "", + "The circles C0, C1 and C2 are drawn in the picture below.", + "", + "", + "C0 and C1 form a lenticular hole, as well as C0 and C2.", + "", + "We call an ordered pair of positive real numbers (r1, r2) a lenticular pair if there exist two circles with radii r1 and r2 that form a lenticular hole.", + "We can verify that (1, 5) and (5, √65) are the lenticular pairs of the example above.", + "", + "Let L(N) be the number of distinct lenticular pairs (r1, r2) for which 0 < r1 ≤ r2 ≤ N.", + "We can verify that L(10) = 30 and L(100) = 3442.", + "", + "Find L(100 000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler295() {", + " // Good luck!", + " return true;", + "}", + "", + "euler295();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4941000cf542c50ffa7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 296: Angular Bisector and Tangent", + "tests": [ + { + "text": "euler296() should return 1137208419.", + "testString": "assert.strictEqual(euler296(), 1137208419, 'euler296() should return 1137208419.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given is an integer sided triangle ABC with BC ≤ AC ≤ AB.k is the angular bisector of angle ACB.m is the tangent at C to the circumscribed circle of ABC.n is a line parallel to m through B.", + "The intersection of n and k is called E.", + "", + "", + "", + "How many triangles ABC with a perimeter not exceeding 100 000 exist such that BE has integral length?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler296() {", + " // Good luck!", + " return true;", + "}", + "", + "euler296();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4951000cf542c50ffa8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 297: Zeckendorf Representation", + "tests": [ + { + "text": "euler297() should return 2252639041804718000.", + "testString": "assert.strictEqual(euler297(), 2252639041804718000, 'euler297() should return 2252639041804718000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Each new term in the Fibonacci sequence is generated by adding the previous two terms.", + "Starting with 1 and 2, the first 10 terms will be: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89.", + "", + "Every positive integer can be uniquely written as a sum of nonconsecutive terms of the Fibonacci sequence. For example, 100 = 3 + 8 + 89.", + "Such a sum is called the Zeckendorf representation of the number.", + "", + "For any integer n>0, let z(n) be the number of terms in the Zeckendorf representation of n.", + "Thus, z(5) = 1, z(14) = 2, z(100) = 3 etc.", + "Also, for 0euler298() should return 1.76882294.", + "testString": "assert.strictEqual(euler298(), 1.76882294, 'euler298() should return 1.76882294.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Larry and Robin play a memory game involving of a sequence of random numbers between 1 and 10, inclusive, that are called out one at a time. Each player can remember up to 5 previous numbers. When the called number is in a player's memory, that player is awarded a point. If it's not, the player adds the called number to his memory, removing another number if his memory is full.", + "", + "Both players start with empty memories. Both players always add new missed numbers to their memory but use a different strategy in deciding which number to remove:", + "Larry's strategy is to remove the number that hasn't been called in the longest time.", + "Robin's strategy is to remove the number that's been in the memory the longest time.", + "", + "Example game:Turn", + " Callednumber", + " Larry'smemory", + " Larry'sscore", + " Robin'smemory", + " Robin'sscore", + "1", + " 1", + " 1", + " 0", + " 1", + " 0", + "2", + " 2", + " 1,2", + " 0", + " 1,2", + " 0", + "3", + " 4", + " 1,2,4", + " 0", + " 1,2,4", + " 0", + "4", + " 6", + " 1,2,4,6", + " 0", + " 1,2,4,6", + " 0", + "5", + " 1", + " 1,2,4,6", + " 1", + " 1,2,4,6", + " 1", + "6", + " 8", + " 1,2,4,6,8", + " 1", + " 1,2,4,6,8", + " 1", + "7", + " 10", + " 1,4,6,8,10", + " 1", + " 2,4,6,8,10", + " 1", + "8", + " 2", + " 1,2,6,8,10", + " 1", + " 2,4,6,8,10", + " 2", + "9", + " 4", + " 1,2,4,8,10", + " 1", + " 2,4,6,8,10", + " 3", + "10", + " 1", + " 1,2,4,8,10", + " 2", + " 1,4,6,8,10", + " 3", + "", + "", + "Denoting Larry's score by L and Robin's score by R, what is the expected value of |L-R| after 50 turns? Give your answer rounded to eight decimal places using the format x.xxxxxxxx ." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler298() {", + " // Good luck!", + " return true;", + "}", + "", + "euler298();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4971000cf542c50ffaa", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 299: Three similar triangles", + "tests": [ + { + "text": "euler299() should return 549936643.", + "testString": "assert.strictEqual(euler299(), 549936643, 'euler299() should return 549936643.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Four points with integer coordinates are selected:A(a, 0), B(b, 0), C(0, c) and D(0, d), ", + "with 0 < a < b and 0 < c < d.", + "Point P, also with integer coordinates, is chosen on the line AC so that the three triangles ABP, CDP and BDP are all similar.", + "", + "It is easy to prove that the three triangles can be similar, only if a=c.", + "", + "So, given that a=c, we are looking for triplets (a,b,d) such that at least one point P (with integer coordinates) exists on AC, making the three triangles ABP, CDP and BDP all similar.", + "", + "For example, if (a,b,d)=(2,3,4), it can be easily verified that point P(1,1) satisfies the above condition. ", + "Note that the triplets (2,3,4) and (2,4,3) are considered as distinct, although point P(1,1) is common for both.", + "", + "If b+d < 100, there are 92 distinct triplets (a,b,d) such that point P exists.", + "If b+d < 100 000, there are 320471 distinct triplets (a,b,d) such that point P exists.", + "If b+d < 100 000 000, how many distinct triplets (a,b,d) are there such that point P exists?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler299() {", + " // Good luck!", + " return true;", + "}", + "", + "euler299();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f49a1000cf542c50ffac", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 300: Protein folding", + "tests": [ + { + "text": "euler300() should return 8.0540771484375.", + "testString": "assert.strictEqual(euler300(), 8.0540771484375, 'euler300() should return 8.0540771484375.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In a very simplified form, we can consider proteins as strings consisting of hydrophobic (H) and polar (P) elements, e.g. HHPPHHHPHHPH. ", + "For this problem, the orientation of a protein is important; e.g. HPP is considered distinct from PPH. Thus, there are 2n distinct proteins consisting of n elements.", + "", + "When one encounters these strings in nature, they are always folded in such a way that the number of H-H contact points is as large as possible, since this is energetically advantageous.", + "As a result, the H-elements tend to accumulate in the inner part, with the P-elements on the outside.", + "Natural proteins are folded in three dimensions of course, but we will only consider protein folding in two dimensions.", + "", + "The figure below shows two possible ways that our example protein could be folded (H-H contact points are shown with red dots).", + "", + "", + "", + "The folding on the left has only six H-H contact points, thus it would never occur naturally.", + "On the other hand, the folding on the right has nine H-H contact points, which is optimal for this string.", + "", + "Assuming that H and P elements are equally likely to occur in any position along the string, the average number of H-H contact points in an optimal folding of a random protein string of length 8 turns out to be 850 / 28=3.3203125.", + "", + "What is the average number of H-H contact points in an optimal folding of a random protein string of length 15?", + "Give your answer using as many decimal places as necessary for an exact result." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler300() {", + " // Good luck!", + " return true;", + "}", + "", + "euler300();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4991000cf542c50ffab", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 301: Nim", + "tests": [ + { + "text": "euler301() should return 2178309.", + "testString": "assert.strictEqual(euler301(), 2178309, 'euler301() should return 2178309.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Nim is a game played with heaps of stones, where two players take it in turn to remove any number of stones from any heap until no stones remain.", + "", + "We'll consider the three-heap normal-play version of Nim, which works as follows:", + "- At the start of the game there are three heaps of stones.", + "- On his turn the player removes any positive number of stones from any single heap.", + "- The first player unable to move (because no stones remain) loses.", + "", + " If (n1,n2,n3) indicates a Nim position consisting of heaps of size n1, n2 and n3 then there is a simple function X(n1,n2,n3) — that you may look up or attempt to deduce for yourself — that returns:", + "zero if, with perfect strategy, the player about to move will eventually lose; or", + "non-zero if, with perfect strategy, the player about to move will eventually win.For example X(1,2,3) = 0 because, no matter what the current player does, his opponent can respond with a move that leaves two heaps of equal size, at which point every move by the current player can be mirrored by his opponent until no stones remain; so the current player loses. To illustrate:", + "- current player moves to (1,2,1)", + "- opponent moves to (1,0,1)", + "- current player moves to (0,0,1)", + "- opponent moves to (0,0,0), and so wins.", + "", + "For how many positive integers n ≤ 230 does X(n,2n,3n) = 0 ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler301() {", + " // Good luck!", + " return true;", + "}", + "", + "euler301();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f49b1000cf542c50ffad", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 302: Strong Achilles Numbers", + "tests": [ + { + "text": "euler302() should return 1170060.", + "testString": "assert.strictEqual(euler302(), 1170060, 'euler302() should return 1170060.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A positive integer n is powerful if p2 is a divisor of n for every prime factor p in n.", + "", + "", + "A positive integer n is a perfect power if n can be expressed as a power of another positive integer.", + "", + "", + "A positive integer n is an Achilles number if n is powerful but not a perfect power. For example, 864 and 1800 are Achilles numbers: 864 = 25·33 and 1800 = 23·32·52.", + "", + "", + "We shall call a positive integer S a Strong Achilles number if both S and φ(S) are Achilles numbers.1", + "For example, 864 is a Strong Achilles number: φ(864) = 288 = 25·32. However, 1800 isn't a Strong Achilles number because: φ(1800) = 480 = 25·31·51.", + "", + "There are 7 Strong Achilles numbers below 104 and 656 below 108.", + "", + "", + "How many Strong Achilles numbers are there below 1018?", + "", + "", + "1 φ denotes Euler's totient function." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler302() {", + " // Good luck!", + " return true;", + "}", + "", + "euler302();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f49b1000cf542c50ffae", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 303: Multiples with small digits", + "tests": [ + { + "text": "euler303() should return 1111981904675169.", + "testString": "assert.strictEqual(euler303(), 1111981904675169, 'euler303() should return 1111981904675169.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a positive integer n, define f(n) as the least positive multiple of n that, written in base 10, uses only digits ≤ 2.", + "Thus f(2)=2, f(3)=12, f(7)=21, f(42)=210, f(89)=1121222.", + "Also, .", + "", + "Find ." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler303() {", + " // Good luck!", + " return true;", + "}", + "", + "euler303();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f49d1000cf542c50ffaf", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 304: Primonacci", + "tests": [ + { + "text": "euler304() should return 283988410192.", + "testString": "assert.strictEqual(euler304(), 283988410192, 'euler304() should return 283988410192.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For any positive integer n the function next_prime(n) returns the smallest prime p such that p>n.", + "", + "", + "The sequence a(n) is defined by:", + "a(1)=next_prime(1014) and a(n)=next_prime(a(n-1)) for n>1.", + "", + "", + "The fibonacci sequence f(n) is defined by:", + "f(0)=0, f(1)=1 and f(n)=f(n-1)+f(n-2) for n>1.", + "", + "", + "The sequence b(n) is defined as f(a(n)).", + "", + "", + "Find ∑b(n) for 1≤n≤100 000. ", + "Give your answer mod 1234567891011." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler304() {", + " // Good luck!", + " return true;", + "}", + "", + "euler304();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f49d1000cf542c50ffb0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 305: Reflexive Position", + "tests": [ + { + "text": "euler305() should return 18174995535140.", + "testString": "assert.strictEqual(euler305(), 18174995535140, 'euler305() should return 18174995535140.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let's call S the (infinite) string that is made by concatenating the consecutive positive integers (starting from 1) written down in base 10. ", + "Thus, S = 1234567891011121314151617181920212223242...", + "", + "", + "It's easy to see that any number will show up an infinite number of times in S.", + "", + "", + "Let's call f(n) the starting position of the nth occurrence of n in S. ", + "For example, f(1)=1, f(5)=81, f(12)=271 and f(7780)=111111365.", + "", + "", + "Find ∑f(3k) for 1≤k≤13." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler305() {", + " // Good luck!", + " return true;", + "}", + "", + "euler305();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f49f1000cf542c50ffb1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 306: Paper-strip Game", + "tests": [ + { + "text": "euler306() should return 852938.", + "testString": "assert.strictEqual(euler306(), 852938, 'euler306() should return 852938.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The following game is a classic example of Combinatorial Game Theory:", + "", + "Two players start with a strip of n white squares and they take alternate turns.", + "On each turn, a player picks two contiguous white squares and paints them black.", + "The first player who cannot make a move loses.", + "", + "If n = 1, there are no valid moves, so the first player loses automatically.", + "If n = 2, there is only one valid move, after which the second player loses.", + "If n = 3, there are two valid moves, but both leave a situation where the second player loses.", + "If n = 4, there are three valid moves for the first player; she can win the game by painting the two middle squares.", + "If n = 5, there are four valid moves for the first player (shown below in red); but no matter what she does, the second player (blue) wins.", + "", + "", + "", + "So, for 1 ≤ n ≤ 5, there are 3 values of n for which the first player can force a win.", + "Similarly, for 1 ≤ n ≤ 50, there are 40 values of n for which the first player can force a win.", + "", + "For 1 ≤ n ≤ 1 000 000, how many values of n are there for which the first player can force a win?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler306() {", + " // Good luck!", + " return true;", + "}", + "", + "euler306();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4a01000cf542c50ffb2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 307: Chip Defects", + "tests": [ + { + "text": "euler307() should return 0.7311720251.", + "testString": "assert.strictEqual(euler307(), 0.7311720251, 'euler307() should return 0.7311720251.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "k defects are randomly distributed amongst n integrated-circuit chips produced by a factory (any number of defects may be found on a chip and each defect is independent of the other defects).", + "", + "", + "Let p(k,n) represent the probability that there is a chip with at least 3 defects.", + "For instance p(3,7) ≈ 0.0204081633.", + "", + "", + "Find p(20 000, 1 000 000) and give your answer rounded to 10 decimal places in the form 0.abcdefghij" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler307() {", + " // Good luck!", + " return true;", + "}", + "", + "euler307();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4a11000cf542c50ffb3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 308: An amazing Prime-generating Automaton", + "tests": [ + { + "text": "euler308() should return 1539669807660924.", + "testString": "assert.strictEqual(euler308(), 1539669807660924, 'euler308() should return 1539669807660924.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A program written in the programming language Fractran consists of a list of fractions.", + "", + "The internal state of the Fractran Virtual Machine is a positive integer, which is initially set to a seed value. Each iteration of a Fractran program multiplies the state integer by the first fraction in the list which will leave it an integer.", + "", + "For example, one of the Fractran programs that John Horton Conway wrote for prime-generation consists of the following 14 fractions:1791", + ",", + "7885", + ",", + "1951", + ",", + "2338", + ",", + "2933", + ",", + "7729", + ",", + "9523", + ",", + "7719", + ",", + "117", + ",", + "1113", + ",", + "1311", + ",", + "152", + ",", + "17", + ",", + "551", + ".", + "Starting with the seed integer 2, successive iterations of the program produce the sequence:", + "15, 825, 725, 1925, 2275, 425, ..., 68, 4, 30, ..., 136, 8, 60, ..., 544, 32, 240, ...", + "", + "The powers of 2 that appear in this sequence are 22, 23, 25, ...", + "It can be shown that all the powers of 2 in this sequence have prime exponents and that all the primes appear as exponents of powers of 2, in proper order!", + "", + "If someone uses the above Fractran program to solve Project Euler Problem 7 (find the 10001st prime), how many iterations would be needed until the program produces 210001st prime ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler308() {", + " // Good luck!", + " return true;", + "}", + "", + "euler308();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4a11000cf542c50ffb4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 309: Integer Ladders", + "tests": [ + { + "text": "euler309() should return 210139.", + "testString": "assert.strictEqual(euler309(), 210139, 'euler309() should return 210139.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In the classic \"Crossing Ladders\" problem, we are given the lengths x and y of two ladders resting on the opposite walls of a narrow, level street. We are also given the height h above the street where the two ladders cross and we are asked to find the width of the street (w).", + "", + "", + "", + "Here, we are only concerned with instances where all four variables are positive integers.", + "For example, if x = 70, y = 119 and h = 30, we can calculate that w = 56.", + "", + "In fact, for integer values x, y, h and 0 < x < y < 200, there are only five triplets (x,y,h) producing integer solutions for w:", + "(70, 119, 30), (74, 182, 21), (87, 105, 35), (100, 116, 35) and (119, 175, 40).", + "", + "For integer values x, y, h and 0 < x < y < 1 000 000, how many triplets (x,y,h) produce integer solutions for w?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler309() {", + " // Good luck!", + " return true;", + "}", + "", + "euler309();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4a21000cf542c50ffb5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 310: Nim Square", + "tests": [ + { + "text": "euler310() should return 2586528661783.", + "testString": "assert.strictEqual(euler310(), 2586528661783, 'euler310() should return 2586528661783.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Alice and Bob play the game Nim Square.", + "Nim Square is just like ordinary three-heap normal play Nim, but the players may only remove a square number of stones from a heap.", + "The number of stones in the three heaps is represented by the ordered triple (a,b,c).", + "If 0≤a≤b≤c≤29 then the number of losing positions for the next player is 1160.", + "", + "", + "Find the number of losing positions for the next player if 0≤a≤b≤c≤100 000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler310() {", + " // Good luck!", + " return true;", + "}", + "", + "euler310();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4a31000cf542c50ffb6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 311: Biclinic Integral Quadrilaterals", + "tests": [ + { + "text": "euler311() should return 2466018557.", + "testString": "assert.strictEqual(euler311(), 2466018557, 'euler311() should return 2466018557.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "ABCD is a convex, integer sided quadrilateral with 1 ≤ AB < BC < CD < AD.", + "BD has integer length. O is the midpoint of BD. AO has integer length.", + "We'll call ABCD a biclinic integral quadrilateral if AO = CO ≤ BO = DO.", + "", + "For example, the following quadrilateral is a biclinic integral quadrilateral:", + "AB = 19, BC = 29, CD = 37, AD = 43, BD = 48 and AO = CO = 23.", + "", + "", + "", + "", + "Let B(N) be the number of distinct biclinic integral quadrilaterals ABCD that satisfy AB2+BC2+CD2+AD2 ≤ N.", + "We can verify that B(10 000) = 49 and B(1 000 000) = 38239.", + "", + "", + "Find B(10 000 000 000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler311() {", + " // Good luck!", + " return true;", + "}", + "", + "euler311();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4a51000cf542c50ffb7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 312: Cyclic paths on Sierpiński graphs", + "tests": [ + { + "text": "euler312() should return 324681947.", + "testString": "assert.strictEqual(euler312(), 324681947, 'euler312() should return 324681947.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "- A Sierpiński graph of order-1 (S1) is an equilateral triangle.", + "- Sn+1 is obtained from Sn by positioning three copies of Sn so that every pair of copies has one common corner.", + "", + "", + "", + "", + "Let C(n) be the number of cycles that pass exactly once through all the vertices of Sn.", + "For example, C(3) = 8 because eight such cycles can be drawn on S3, as shown below:", + "", + "", + "", + "", + "It can also be verified that :", + "C(1) = C(2) = 1", + "C(5) = 71328803586048", + "C(10 000) mod 108 = 37652224", + "C(10 000) mod 138 = 617720485", + "", + "Find C(C(C(10 000))) mod 138." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler312() {", + " // Good luck!", + " return true;", + "}", + "", + "euler312();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4a61000cf542c50ffb8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 313: Sliding game", + "tests": [ + { + "text": "euler313() should return 2057774861813004.", + "testString": "assert.strictEqual(euler313(), 2057774861813004, 'euler313() should return 2057774861813004.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In a sliding game a counter may slide horizontally or vertically into an empty space. The objective of the game is to move the red counter from the top left corner of a grid to the bottom right corner; the space always starts in the bottom right corner. For example, the following sequence of pictures show how the game can be completed in five moves on a 2 by 2 grid.", + "", + "", + "", + "Let S(m,n) represent the minimum number of moves to complete the game on an m by n grid. For example, it can be verified that S(5,4) = 25.", + "", + "", + "", + "There are exactly 5482 grids for which S(m,n) = p2, where p < 100 is prime.", + "", + "How many grids does S(m,n) = p2, where p < 106 is prime?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler313() {", + " // Good luck!", + " return true;", + "}", + "", + "euler313();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4a71000cf542c50ffb9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 314: The Mouse on the Moon", + "tests": [ + { + "text": "euler314() should return 132.52756426.", + "testString": "assert.strictEqual(euler314(), 132.52756426, 'euler314() should return 132.52756426.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The moon has been opened up, and land can be obtained for free, but there is a catch. You have to build a wall around the land that you stake out, and building a wall on the moon is expensive. Every country has been allotted a 500 m by 500 m square area, but they will possess only that area which they wall in. 251001 posts have been placed in a rectangular grid with 1 meter spacing. The wall must be a closed series of straight lines, each line running from post to post.", + "", + "", + "The bigger countries of course have built a 2000 m wall enclosing the entire 250 000 m2 area. The Duchy of Grand Fenwick, has a tighter budget, and has asked you (their Royal Programmer) to compute what shape would get best maximum enclosed-area/wall-length ratio.", + "", + "", + "You have done some preliminary calculations on a sheet of paper.", + "For a 2000 meter wall enclosing the 250 000 m2 area the", + "enclosed-area/wall-length ratio is 125.", + "Although not allowed , but to get an idea if this is anything better: if you place a circle inside the square area touching the four sides the area will be equal to π*2502 m2 and the perimeter will be π*500 m, so the enclosed-area/wall-length ratio will also be 125.", + "", + "", + "However, if you cut off from the square four triangles with sides 75 m, 75 m and 75√2 m the total area becomes 238750 m2 and the perimeter becomes 1400+300√2 m. So this gives an enclosed-area/wall-length ratio of 130.87, which is significantly better.", + "", + "", + "", + "Find the maximum enclosed-area/wall-length ratio.", + "Give your answer rounded to 8 places behind the decimal point in the form abc.defghijk." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler314() {", + " // Good luck!", + " return true;", + "}", + "", + "euler314();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4a71000cf542c50ffba", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 315: Digital root clocks", + "tests": [ + { + "text": "euler315() should return 13625242.", + "testString": "assert.strictEqual(euler315(), 13625242, 'euler315() should return 13625242.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Sam and Max are asked to transform two digital clocks into two \"digital root\" clocks.", + "A digital root clock is a digital clock that calculates digital roots step by step.", + "", + "When a clock is fed a number, it will show it and then it will start the calculation, showing all the intermediate values until it gets to the result.", + "For example, if the clock is fed the number 137, it will show: \"137\" → \"11\" → \"2\" and then it will go black, waiting for the next number.", + "", + "Every digital number consists of some light segments: three horizontal (top, middle, bottom) and four vertical (top-left, top-right, bottom-left, bottom-right).", + "Number \"1\" is made of vertical top-right and bottom-right, number \"4\" is made by middle horizontal and vertical top-left, top-right and bottom-right. Number \"8\" lights them all.", + "", + "The clocks consume energy only when segments are turned on/off.", + "To turn on a \"2\" will cost 5 transitions, while a \"7\" will cost only 4 transitions.", + "", + "Sam and Max built two different clocks.", + "", + "Sam's clock is fed e.g. number 137: the clock shows \"137\", then the panel is turned off, then the next number (\"11\") is turned on, then the panel is turned off again and finally the last number (\"2\") is turned on and, after some time, off.", + "For the example, with number 137, Sam's clock requires:\"137\"", + ":", + "(2 + 5 + 4) × 2 = 22 transitions (\"137\" on/off).", + "\"11\"", + ":", + "(2 + 2) × 2 = 8 transitions (\"11\" on/off).", + "\"2\"", + ":", + "(5) × 2 = 10 transitions (\"2\" on/off).", + "", + "For a grand total of 40 transitions.", + "", + "Max's clock works differently. Instead of turning off the whole panel, it is smart enough to turn off only those segments that won't be needed for the next number.", + "For number 137, Max's clock requires:\"137\"", + ":", + "2 + 5 + 4 = 11 transitions (\"137\" on)", + "7 transitions (to turn off the segments that are not needed for number \"11\").", + "\"11\"", + ":", + "0 transitions (number \"11\" is already turned on correctly)", + "3 transitions (to turn off the first \"1\" and the bottom part of the second \"1\"; ", + "the top part is common with number \"2\").", + "\"2\"", + ":", + "4 transitions (to turn on the remaining segments in order to get a \"2\")", + "5 transitions (to turn off number \"2\").", + "", + "For a grand total of 30 transitions.", + "", + "Of course, Max's clock consumes less power than Sam's one.", + "The two clocks are fed all the prime numbers between A = 107 and B = 2×107. ", + "Find the difference between the total number of transitions needed by Sam's clock and that needed by Max's one." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler315() {", + " // Good luck!", + " return true;", + "}", + "", + "euler315();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4a81000cf542c50ffbb", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 316: Numbers in decimal expansions", + "tests": [ + { + "text": "euler316() should return 542934735751917760.", + "testString": "assert.strictEqual(euler316(), 542934735751917760, 'euler316() should return 542934735751917760.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let p = p1 p2 p3 ... be an infinite sequence of random digits, selected from {0,1,2,3,4,5,6,7,8,9} with equal probability.", + "It can be seen that p corresponds to the real number 0.p1 p2 p3 .... ", + "It can also be seen that choosing a random real number from the interval [0,1) is equivalent to choosing an infinite sequence of random digits selected from {0,1,2,3,4,5,6,7,8,9} with equal probability.", + "", + "For any positive integer n with d decimal digits, let k be the smallest index such that pk, pk+1, ...pk+d-1 are the decimal digits of n, in the same order.", + "Also, let g(n) be the expected value of k; it can be proven that g(n) is always finite and, interestingly, always an integer number.", + "", + "For example, if n = 535, then", + "for p = 31415926535897...., we get k = 9", + "for p = 355287143650049560000490848764084685354..., we get k = 36", + "etc and we find that g(535) = 1008.", + "", + "Given that , find ", + "", + "Note: represents the floor function." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler316() {", + " // Good luck!", + " return true;", + "}", + "", + "euler316();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4aa1000cf542c50ffbc", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 317: Firecracker", + "tests": [ + { + "text": "euler317() should return 1856532.8455.", + "testString": "assert.strictEqual(euler317(), 1856532.8455, 'euler317() should return 1856532.8455.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A firecracker explodes at a height of 100 m above level ground. It breaks into a large number of very small fragments, which move in every direction; all of them have the same initial velocity of 20 m/s.", + "", + "", + "We assume that the fragments move without air resistance, in a uniform gravitational field with g=9.81 m/s2.", + "", + "", + "Find the volume (in m3) of the region through which the fragments move before reaching the ground. ", + "Give your answer rounded to four decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler317() {", + " // Good luck!", + " return true;", + "}", + "", + "euler317();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ab1000cf542c50ffbd", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 318: 2011 nines", + "tests": [ + { + "text": "euler318() should return 709313889.", + "testString": "assert.strictEqual(euler318(), 709313889, 'euler318() should return 709313889.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the real number √2+√3.", + "When we calculate the even powers of √2+√3", + "we get:", + "(√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...", + "", + "It looks like that the number of consecutive nines at the beginning of the fractional part of these powers is non-decreasing.", + "In fact it can be proven that the fractional part of (√2+√3)2n approaches 1 for large n.", + "", + "", + "Consider all real numbers of the form √p+√q with p and q positive integers and peuler319() should return 268457129.", + "testString": "assert.strictEqual(euler319(), 268457129, 'euler319() should return 268457129.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let x1, x2,..., xn be a sequence of length n such that:", + "x1 = 2", + "for all 1 < i ≤ n : xi-1 < xi", + "for all i and j with 1 ≤ i, j ≤ n : (xi) j < (xj + 1)i", + "", + "There are only five such sequences of length 2, namely:", + "{2,4}, {2,5}, {2,6}, {2,7} and {2,8}.", + "There are 293 such sequences of length 5; three examples are given below:", + "{2,5,11,25,55}, {2,6,14,36,88}, {2,8,22,64,181}.", + "", + "", + "Let t(n) denote the number of such sequences of length n.", + "You are given that t(10) = 86195 and t(20) = 5227991891.", + "", + "", + "Find t(1010) and give your answer modulo 109." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler319() {", + " // Good luck!", + " return true;", + "}", + "", + "euler319();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ae1000cf542c50ffbf", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 320: Factorials divisible by a huge integer", + "tests": [ + { + "text": "euler320() should return 278157919195482660.", + "testString": "assert.strictEqual(euler320(), 278157919195482660, 'euler320() should return 278157919195482660.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let N(i) be the smallest integer n such that n! is divisible by (i!)1234567890", + "", + "Let S(u)=∑N(i) for 10 ≤ i ≤ u.", + "", + "", + "S(1000)=614538266565663.", + "", + "", + "Find S(1 000 000) mod 1018." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler320() {", + " // Good luck!", + " return true;", + "}", + "", + "euler320();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ae1000cf542c50ffc0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 321: Swapping Counters", + "tests": [ + { + "text": "euler321() should return 2470433131948040.", + "testString": "assert.strictEqual(euler321(), 2470433131948040, 'euler321() should return 2470433131948040.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A horizontal row comprising of 2n + 1 squares has n red counters placed at one end and n blue counters at the other end, being separated by a single empty square in the centre. For example, when n = 3.", + "", + "", + "", + "A counter can move from one square to the next (slide) or can jump over another counter (hop) as long as the square next to that counter is unoccupied.", + "", + "", + "", + "Let M(n) represent the minimum number of moves/actions to completely reverse the positions of the coloured counters; that is, move all the red counters to the right and all the blue counters to the left.", + "It can be verified M(3) = 15, which also happens to be a triangle number.", + "", + "If we create a sequence based on the values of n for which M(n) is a triangle number then the first five terms would be:", + "1, 3, 10, 22, and 63, and their sum would be 99.", + "", + "Find the sum of the first forty terms of this sequence." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler321() {", + " // Good luck!", + " return true;", + "}", + "", + "euler321();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4af1000cf542c50ffc1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 322: Binomial coefficients divisible by 10", + "tests": [ + { + "text": "euler322() should return 999998760323314000.", + "testString": "assert.strictEqual(euler322(), 999998760323314000, 'euler322() should return 999998760323314000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let T(m, n) be the number of the binomial coefficients iCn that are divisible by 10 for n ≤ i < m(i, m and n are positive integers).", + "You are given that T(109, 107-10) = 989697000.", + "", + "", + "Find T(1018, 1012-10)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler322() {", + " // Good luck!", + " return true;", + "}", + "", + "euler322();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b01000cf542c50ffc2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 323: Bitwise-OR operations on random integers", + "tests": [ + { + "text": "euler323() should return 6.3551758451.", + "testString": "assert.strictEqual(euler323(), 6.3551758451, 'euler323() should return 6.3551758451.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let y0, y1, y2,... be a sequence of random unsigned 32 bit integers", + "(i.e. 0 ≤ yi < 232, every value equally likely).", + "For the sequence xi the following recursion is given:x0 = 0 and", + "xi = xi-1| yi-1, for i > 0. ( | is the bitwise-OR operator)", + "It can be seen that eventually there will be an index N such that xi = 232 -1 (a bit-pattern of all ones) for all i ≥ N.", + "", + "Find the expected value of N. ", + "Give your answer rounded to 10 digits after the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler323() {", + " // Good luck!", + " return true;", + "}", + "", + "euler323();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b11000cf542c50ffc3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 324: Building a tower", + "tests": [ + { + "text": "euler324() should return 96972774.", + "testString": "assert.strictEqual(euler324(), 96972774, 'euler324() should return 96972774.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let f(n) represent the number of ways one can fill a 3×3×n tower with blocks of 2×1×1. You're allowed to rotate the blocks in any way you like; however, rotations, reflections etc of the tower itself are counted as distinct.", + "For example (with q = 100000007) :f(2) = 229,f(4) = 117805,f(10) mod q = 96149360,f(103) mod q = 24806056,f(106) mod q = 30808124.", + "", + "Find f(1010000) mod 100000007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler324() {", + " // Good luck!", + " return true;", + "}", + "", + "euler324();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b11000cf542c50ffc4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 325: Stone Game II", + "tests": [ + { + "text": "euler325() should return 54672965.", + "testString": "assert.strictEqual(euler325(), 54672965, 'euler325() should return 54672965.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A game is played with two piles of stones and two players. At her turn, a player removes a number of stones from the larger pile. The number of stones she removes must be a positive multiple of the number of stones in the smaller pile.", + "", + "", + "", + "E.g., let the ordered pair(6,14) describe a configuration with 6 stones in the smaller pile and 14 stones in the larger pile, then the first player can remove 6 or 12 stones from the larger pile.", + "", + "", + "", + "The player taking all the stones from a pile wins the game.", + "", + "", + "", + "A winning configuration is one where the first player can force a win. For example, (1,5), (2,6) and (3,12) are winning configurations because the first player can immediately remove all stones in the second pile.", + "", + "", + "", + "A losing configuration is one where the second player can force a win, no matter what the first player does. For example, (2,3) and (3,4) are losing configurations: any legal move leaves a winning configuration for the second player.", + "", + "", + "", + "Define S(N) as the sum of (xi+yi) for all losing configurations (xi,yi), 0 < xi < yi ≤ N. We can verify that S(10) = 211 and S(104) = 230312207313.", + "", + "", + "", + "Find S(1016) mod 710." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler325() {", + " // Good luck!", + " return true;", + "}", + "", + "euler325();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b21000cf542c50ffc5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 326: Modulo Summations", + "tests": [ + { + "text": "euler326() should return 1966666166408794400.", + "testString": "assert.strictEqual(euler326(), 1966666166408794400, 'euler326() should return 1966666166408794400.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let an be a sequence recursively defined by: . ", + "", + "", + "So the first 10 elements of an are: 1,1,0,3,0,3,5,4,1,9.", + "", + "Let f(N,M) represent the number of pairs (p,q) such that: ", + "", + "", + "It can be seen that f(10,10)=4 with the pairs (3,3), (5,5), (7,9) and (9,10).", + "", + "", + "You are also given that f(104,103)=97158.", + "", + "Find f(1012,106)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler326() {", + " // Good luck!", + " return true;", + "}", + "", + "euler326();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b31000cf542c50ffc6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 327: Rooms of Doom", + "tests": [ + { + "text": "euler327() should return 34315549139516.", + "testString": "assert.strictEqual(euler327(), 34315549139516, 'euler327() should return 34315549139516.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A series of three rooms are connected to each other by automatic doors.", + "", + "", + "", + "Each door is operated by a security card. Once you enter a room the door automatically closes and that security card cannot be used again. A machine at the start will dispense an unlimited number of cards, but each room (including the starting room) contains scanners and if they detect that you are holding more than three security cards or if they detect an unattended security card on the floor, then all the doors will become permanently locked. However, each room contains a box where you may safely store any number of security cards for use at a later stage.", + "", + "If you simply tried to travel through the rooms one at a time then as you entered room 3 you would have used all three cards and would be trapped in that room forever!", + "", + "However, if you make use of the storage boxes, then escape is possible. For example, you could enter room 1 using your first card, place one card in the storage box, and use your third card to exit the room back to the start. Then after collecting three more cards from the dispensing machine you could use one to enter room 1 and collect the card you placed in the box a moment ago. You now have three cards again and will be able to travel through the remaining three doors. This method allows you to travel through all three rooms using six security cards in total.", + "", + "It is possible to travel through six rooms using a total of 123 security cards while carrying a maximum of 3 cards.", + "", + "Let C be the maximum number of cards which can be carried at any time.", + "Let R be the number of rooms to travel through.", + "Let M(C,R) be the minimum number of cards required from the dispensing machine to travel through R rooms carrying up to a maximum of C cards at any time.", + "", + "For example, M(3,6)=123 and M(4,6)=23.And, ΣM(C,6)=146 for 3 ≤ C ≤ 4.", + "", + "", + "You are given that ΣM(C,10)=10382 for 3 ≤ C ≤ 10.", + "", + "Find ΣM(C,30) for 3 ≤ C ≤ 40." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler327() {", + " // Good luck!", + " return true;", + "}", + "", + "euler327();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b41000cf542c50ffc7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 328: Lowest-cost Search", + "tests": [ + { + "text": "euler328() should return 260511850222.", + "testString": "assert.strictEqual(euler328(), 260511850222, 'euler328() should return 260511850222.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We are trying to find a hidden number selected from the set of integers {1, 2, ..., n} by asking questions. ", + "Each number (question) we ask, has a cost equal to the number asked and we get one of three possible answers: \"Your guess is lower than the hidden number\", or", + " \"Yes, that's it!\", or", + " \"Your guess is higher than the hidden number\".", + "Given the value of n, an optimal strategy minimizes the total cost (i.e. the sum of all the questions asked) for the worst possible case. E.g.", + "", + "If n=3, the best we can do is obviously to ask the number \"2\". The answer will immediately lead us to find the hidden number (at a total cost = 2).", + "", + "If n=8, we might decide to use a \"binary search\" type of strategy: Our first question would be \"4\" and if the hidden number is higher than 4 we will need one or two additional questions.", + "Let our second question be \"6\". If the hidden number is still higher than 6, we will need a third question in order to discriminate between 7 and 8.", + "Thus, our third question will be \"7\" and the total cost for this worst-case scenario will be 4+6+7=17.", + "", + "We can improve considerably the worst-case cost for n=8, by asking \"5\" as our first question.", + "If we are told that the hidden number is higher than 5, our second question will be \"7\", then we'll know for certain what the hidden number is (for a total cost of 5+7=12).", + "If we are told that the hidden number is lower than 5, our second question will be \"3\" and if the hidden number is lower than 3 our third question will be \"1\", giving a total cost of 5+3+1=9.", + "Since 12>9, the worst-case cost for this strategy is 12. That's better than what we achieved previously with the \"binary search\" strategy; it is also better than or equal to any other strategy.", + "So, in fact, we have just described an optimal strategy for n=8.", + "", + "Let C(n) be the worst-case cost achieved by an optimal strategy for n, as described above.", + "Thus C(1) = 0, C(2) = 1, C(3) = 2 and C(8) = 12.", + "Similarly, C(100) = 400 and C(n) = 17575.", + "", + "Find C(n)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler328() {", + " // Good luck!", + " return true;", + "}", + "", + "euler328();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b51000cf542c50ffc8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 329: Prime Frog", + "tests": [ + { + "text": "euler329() should return 199740353 / 29386561536000.", + "testString": "assert.strictEqual(euler329(), 199740353 / 29386561536000, 'euler329() should return 199740353 / 29386561536000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Susan has a prime frog.", + "Her frog is jumping around over 500 squares numbered 1 to 500.", + "He can only jump one square to the left or to the right, with equal probability, and he cannot jump outside the range [1;500].(if it lands at either end, it automatically jumps to the only available square on the next move.)", + "", + "", + "When he is on a square with a prime number on it, he croaks 'P' (PRIME) with probability 2/3 or 'N' (NOT PRIME) with probability 1/3 just before jumping to the next square.", + "When he is on a square with a number on it that is not a prime he croaks 'P' with probability 1/3 or 'N' with probability 2/3 just before jumping to the next square.", + "", + "", + "Given that the frog's starting position is random with the same probability for every square, and given that she listens to his first 15 croaks, what is the probability that she hears the sequence PPPPNNPPPNPPNPN?", + "", + "Give your answer as a fraction p/q in reduced form." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler329() {", + " // Good luck!", + " return true;", + "}", + "", + "euler329();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b71000cf542c50ffc9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 330: Euler's Number", + "tests": [ + { + "text": "euler330() should return 15955822.", + "testString": "assert.strictEqual(euler330(), 15955822, 'euler330() should return 15955822.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An infinite sequence of real numbers a(n) is defined for all integers n as follows:", + "", + "", + "For example,a(0) = ", + " 11!", + " +", + " 12!", + " +", + " 13!", + " + ... = e − 1 ", + "a(1) = ", + " e − 11!", + " +", + " 12!", + " +", + " 13!", + " + ... = 2e − 3 ", + "a(2) = ", + " 2e − 31!", + " +", + " e − 12!", + " +", + " 13!", + " + ... =", + " 72", + " e − 6 ", + "", + "with e = 2.7182818... being Euler's constant.", + "", + "", + "It can be shown that a(n) is of the form ", + " ", + " A(n) e + B(n)n!", + " for integers A(n) and B(n). ", + " ", + "For example a(10) = ", + " ", + " 328161643 e − 65269448610!", + " .", + "", + "Find A(109) + B(109) and give your answer mod 77 777 777." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler330() {", + " // Good luck!", + " return true;", + "}", + "", + "euler330();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b71000cf542c50ffca", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 331: Cross flips", + "tests": [ + { + "text": "euler331() should return 467178235146843500.", + "testString": "assert.strictEqual(euler331(), 467178235146843500, 'euler331() should return 467178235146843500.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "N×N disks are placed on a square game board. Each disk has a black side and white side.", + "", + "At each turn, you may choose a disk and flip all the disks in the same row and the same column as this disk: thus 2×N-1 disks are flipped. The game ends when all disks show their white side. The following example shows a game on a 5×5 board.", + "", + "", + "", + "It can be proven that 3 is the minimal number of turns to finish this game.", + "", + "The bottom left disk on the N×N board has coordinates (0,0);", + "the bottom right disk has coordinates (N-1,0) and the top left disk has coordinates (0,N-1). ", + "", + "Let CN be the following configuration of a board with N×N disks:", + "A disk at (x,y) satisfying , shows its black side; otherwise, it shows its white side. C5 is shown above.", + "", + "Let T(N) be the minimal number of turns to finish a game starting from configuration CN or 0 if configuration CN is unsolvable.", + "We have shown that T(5)=3. You are also given that T(10)=29 and T(1 000)=395253.", + "", + "Find ." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler331() {", + " // Good luck!", + " return true;", + "}", + "", + "euler331();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b91000cf542c50ffcb", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 332: Spherical triangles", + "tests": [ + { + "text": "euler332() should return 2717.751525.", + "testString": "assert.strictEqual(euler332(), 2717.751525, 'euler332() should return 2717.751525.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A spherical triangle is a figure formed on the surface of a sphere by three great circular arcs intersecting pairwise in three vertices.", + "", + "", + "", + "", + "Let C(r) be the sphere with the centre (0,0,0) and radius r.", + "Let Z(r) be the set of points on the surface of C(r) with integer coordinates.", + "Let T(r) be the set of spherical triangles with vertices in Z(r).", + "Degenerate spherical triangles, formed by three points on the same great arc, are not included in T(r).", + "Let A(r) be the area of the smallest spherical triangle in T(r).", + "", + "For example A(14) is 3.294040 rounded to six decimal places.", + "", + "Find A(r). Give your answer rounded to six decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler332() {", + " // Good luck!", + " return true;", + "}", + "", + "euler332();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4b91000cf542c50ffcc", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 333: Special partitions", + "tests": [ + { + "text": "euler333() should return 3053105.", + "testString": "assert.strictEqual(euler333(), 3053105, 'euler333() should return 3053105.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "All positive integers can be partitioned in such a way that each and every term of the partition can be expressed as 2ix3j, where i,j ≥ 0.", + "", + "Let's consider only those such partitions where none of the terms can divide any of the other terms.", + "For example, the partition of 17 = 2 + 6 + 9 = (21x30 + 21x31 + 20x32) would not be valid since 2 can divide 6. Neither would the partition 17 = 16 + 1 = (24x30 + 20x30) since 1 can divide 16. The only valid partition of 17 would be 8 + 9 = (23x30 + 20x32).", + "", + "Many integers have more than one valid partition, the first being 11 having the following two partitions.", + "11 = 2 + 9 = (21x30 + 20x32)", + "11 = 8 + 3 = (23x30 + 20x31)", + "", + "Let's define P(n) as the number of valid partitions of n. For example, P(11) = 2.", + "", + "Let's consider only the prime integers q which would have a single valid partition such as P(17).", + "", + "The sum of the primes q <100 such that P(q)=1 equals 233.", + "", + "Find the sum of the primes q <1000000 such that P(q)=1." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler333() {", + " // Good luck!", + " return true;", + "}", + "", + "euler333();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ba1000cf542c50ffcd", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 334: Spilling the beans", + "tests": [ + { + "text": "euler334() should return 150320021261690850.", + "testString": "assert.strictEqual(euler334(), 150320021261690850, 'euler334() should return 150320021261690850.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In Plato's heaven, there exist an infinite number of bowls in a straight line.", + "Each bowl either contains some or none of a finite number of beans.", + "A child plays a game, which allows only one kind of move: removing two beans from any bowl, and putting one in each of the two adjacent bowls. The game ends when each bowl contains either one or no beans.", + "", + "For example, consider two adjacent bowls containing 2 and 3 beans respectively, all other bowls being empty. The following eight moves will finish the game:", + "", + "", + "", + "You are given the following sequences:", + " t0 = 123456.", + " ", + "", + " ti = ", + " ", + " ", + " ", + " ", + " ", + " ti-12", + " ", + " ,", + " ", + " ", + " ", + " if ti-1 is even", + " ", + " ", + " ", + " ti-12", + " ", + " ", + " ", + " 926252, ", + " ", + " ", + " if ti-1 is odd", + " ", + " ", + "", + " ", + " ", + " where ⌊x⌋ is the floor function", + " ", + "", + " ", + " ", + " and is the bitwise XOR operator.", + " ", + "", + " bi = ( ti mod 211) + 1.", + " ", + "The first two terms of the last sequence are b1 = 289 and b2 = 145.", + "If we start with b1 and b2 beans in two adjacent bowls, 3419100 moves would be required to finish the game.", + "", + "Consider now 1500 adjacent bowls containing b1, b2,..., b1500 beans respectively, all other bowls being empty. Find how many moves it takes before the game ends." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler334() {", + " // Good luck!", + " return true;", + "}", + "", + "euler334();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4bd1000cf542c50ffce", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 335: Gathering the beans", + "tests": [ + { + "text": "euler335() should return 5032316.", + "testString": "assert.strictEqual(euler335(), 5032316, 'euler335() should return 5032316.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Whenever Peter feels bored, he places some bowls, containing one bean each, in a circle. After this, he takes all the beans out of a certain bowl and drops them one by one in the bowls going clockwise. He repeats this, starting from the bowl he dropped the last bean in, until the initial situation appears again. For example with 5 bowls he acts as follows:", + "", + "", + "", + "So with 5 bowls it takes Peter 15 moves to return to the initial situation.", + "", + "Let M(x) represent the number of moves required to return to the initial situation, starting with x bowls. Thus, M(5) = 15. It can also be verified that M(100) = 10920.", + "", + "Find M(2k+1). Give your answer modulo 79." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler335() {", + " // Good luck!", + " return true;", + "}", + "", + "euler335();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4bd1000cf542c50ffcf", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 336: Maximix Arrangements", + "tests": [ + { + "text": "euler336() should return CAGBIHEFJDK.", + "testString": "assert.strictEqual(euler336(), CAGBIHEFJDK, 'euler336() should return CAGBIHEFJDK.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A train is used to transport four carriages in the order: ABCD. However, sometimes when the train arrives to collect the carriages they are not in the correct order. ", + "To rearrange the carriages they are all shunted on to a large rotating turntable. After the carriages are uncoupled at a specific point the train moves off the turntable pulling the carriages still attached with it. The remaining carriages are rotated 180 degrees. All of the carriages are then rejoined and this process is repeated as often as necessary in order to obtain the least number of uses of the turntable.", + "Some arrangements, such as ADCB, can be solved easily: the carriages are separated between A and D, and after DCB are rotated the correct order has been achieved.", + "", + "However, Simple Simon, the train driver, is not known for his efficiency, so he always solves the problem by initially getting carriage A in the correct place, then carriage B, and so on.", + "", + "Using four carriages, the worst possible arrangements for Simon, which we shall call maximix arrangements, are DACB and DBAC; each requiring him five rotations (although, using the most efficient approach, they could be solved using just three rotations). The process he uses for DACB is shown below.", + "", + "", + "", + "", + "It can be verified that there are 24 maximix arrangements for six carriages, of which the tenth lexicographic maximix arrangement is DFAECB.", + "", + "Find the 2011th lexicographic maximix arrangement for eleven carriages." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler336() {", + " // Good luck!", + " return true;", + "}", + "", + "euler336();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4be1000cf542c50ffd0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 337: Totient Stairstep Sequences", + "tests": [ + { + "text": "euler337() should return 85068035.", + "testString": "assert.strictEqual(euler337(), 85068035, 'euler337() should return 85068035.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let {a1, a2,..., an} be an integer sequence of length n such that:", + "a1 = 6", + "for all 1 ≤ i < n : φ(ai) < φ(ai+1) < ai < ai+11", + "Let S(N) be the number of such sequences with an ≤ N.", + "For example, S(10) = 4: {6}, {6, 8}, {6, 8, 9} and {6, 10}.", + "We can verify that S(100) = 482073668 and S(10 000) mod 108 = 73808307.", + "", + "Find S(20 000 000) mod 108.", + "", + "1 φ denotes Euler's totient function." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler337() {", + " // Good luck!", + " return true;", + "}", + "", + "euler337();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4be1000cf542c50ffd1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 338: Cutting Rectangular Grid Paper", + "tests": [ + { + "text": "euler338() should return 15614292.", + "testString": "assert.strictEqual(euler338(), 15614292, 'euler338() should return 15614292.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A rectangular sheet of grid paper with integer dimensions w × h is given. Its grid spacing is 1.", + "When we cut the sheet along the grid lines into two pieces and rearrange those pieces without overlap, we can make new rectangles with different dimensions.", + "For example, from a sheet with dimensions 9 × 4 , we can make rectangles with dimensions 18 × 2, 12 × 3 and 6 × 6 by cutting and rearranging as below:", + "", + "", + "", + "", + "Similarly, from a sheet with dimensions 9 × 8 , we can make rectangles with dimensions 18 × 4 and 12 × 6 .", + "", + "For a pair w and h, let F(w,h) be the number of distinct rectangles that can be made from a sheet with dimensions w × h .", + "For example, F(2,1) = 0, F(2,2) = 1, F(9,4) = 3 and F(9,8) = 2. ", + "Note that rectangles congruent to the initial one are not counted in F(w,h).", + "Note also that rectangles with dimensions w × h and dimensions h × w are not considered distinct.", + "", + "For an integer N, let G(N) be the sum of F(w,h) for all pairs w and h which satisfy 0 < h ≤ w ≤ N.", + "We can verify that G(10) = 55, G(103) = 971745 and G(105) = 9992617687.", + "", + "Find G(1012). Give your answer modulo 108." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler338() {", + " // Good luck!", + " return true;", + "}", + "", + "euler338();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4c01000cf542c50ffd2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 339: Peredur fab Efrawg", + "tests": [ + { + "text": "euler339() should return 19823.542204.", + "testString": "assert.strictEqual(euler339(), 19823.542204, 'euler339() should return 19823.542204.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "\"And he came towards a valley, through which ran a river; and the borders of the valley were wooded, and on each side of the river were level meadows. And on one side of the river he saw a flock of white sheep, and on the other a flock of black sheep. And whenever one of the white sheep bleated, one of the black sheep would cross over and become white; and when one of the black sheep bleated, one of the white sheep would cross over and become black.\"en.wikisource.org", + "", + "", + "", + "Initially each flock consists of n sheep. Each sheep (regardless of colour) is equally likely to be the next sheep to bleat. After a sheep has bleated and a sheep from the other flock has crossed over, Peredur may remove a number of white sheep in order to maximize the expected final number of black sheep. Let E(n) be the expected final number of black sheep if Peredur uses an optimal strategy.", + "", + "", + "", + "You are given that E(5) = 6.871346 rounded to 6 places behind the decimal point.", + "Find E(10 000) and give your answer rounded to 6 places behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler339() {", + " // Good luck!", + " return true;", + "}", + "", + "euler339();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4c21000cf542c50ffd4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 340: Crazy Function", + "tests": [ + { + "text": "euler340() should return 291504964.", + "testString": "assert.strictEqual(euler340(), 291504964, 'euler340() should return 291504964.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For fixed integers a, b, c, define the crazy function F(n) as follows:", + "F(n) = n - c for all n > b ", + "F(n) = F(a + F(a + F(a + F(a + n)))) for all n ≤ b.", + "", + "", + "Also, define S(a, b, c) = .", + "", + "", + "For example, if a = 50, b = 2000 and c = 40, then F(0) = 3240 and F(2000) = 2040.", + "Also, S(50, 2000, 40) = 5204240.", + "", + "", + "Find the last 9 digits of S(217, 721, 127)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler340() {", + " // Good luck!", + " return true;", + "}", + "", + "euler340();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4c11000cf542c50ffd3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 341: Golomb's self-describing sequence", + "tests": [ + { + "text": "euler341() should return 56098610614277016.", + "testString": "assert.strictEqual(euler341(), 56098610614277016, 'euler341() should return 56098610614277016.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The Golomb's self-describing sequence {G(n)} is the only nondecreasing sequence of natural numbers such that n appears exactly G(n) times in the sequence. The values of G(n) for the first few n are", + "", + "", + "n123456789101112131415…G(n)122334445556666…", + "", + "You are given that G(103) = 86, G(106) = 6137.", + "You are also given that ΣG(n3) = 153506976 for 1 ≤ n < 103.", + "", + "Find ΣG(n3) for 1 ≤ n < 106." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler341() {", + " // Good luck!", + " return true;", + "}", + "", + "euler341();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4c31000cf542c50ffd5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 342: The totient of a square is a cube", + "tests": [ + { + "text": "euler342() should return 5943040885644.", + "testString": "assert.strictEqual(euler342(), 5943040885644, 'euler342() should return 5943040885644.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the number 50.", + "502 = 2500 = 22 × 54, so φ(2500) = 2 × 4 × 53 = 8 × 53 = 23 × 53. 1", + "So 2500 is a square and φ(2500) is a cube.", + "", + "", + "Find the sum of all numbers n, 1 < n < 1010 such that φ(n2) is a cube.", + "", + "", + "1 φ denotes Euler's totient function." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler342() {", + " // Good luck!", + " return true;", + "}", + "", + "euler342();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4c41000cf542c50ffd6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 343: Fractional Sequences", + "tests": [ + { + "text": "euler343() should return 269533451410884200.", + "testString": "assert.strictEqual(euler343(), 269533451410884200, 'euler343() should return 269533451410884200.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For any positive integer k, a finite sequence ai of fractions xi/yi is defined by:", + "a1 = 1/k and", + "ai = (xi-1+1)/(yi-1-1) reduced to lowest terms for i>1.", + "When ai reaches some integer n, the sequence stops. (That is, when yi=1.)", + "Define f(k) = n. ", + "For example, for k = 20:", + "", + "", + "", + "1/20 → 2/19 → 3/18 = 1/6 → 2/5 → 3/4 → 4/3 → 5/2 → 6/1 = 6", + "", + "", + "", + "So f(20) = 6.", + "", + "", + "", + "Also f(1) = 1, f(2) = 2, f(3) = 1 and Σf(k3) = 118937 for 1 ≤ k ≤ 100.", + "", + "", + "", + "Find Σf(k3) for 1 ≤ k ≤ 2×106." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler343() {", + " // Good luck!", + " return true;", + "}", + "", + "euler343();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4c51000cf542c50ffd7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 344: Silver dollar game", + "tests": [ + { + "text": "euler344() should return 65579304332.", + "testString": "assert.strictEqual(euler344(), 65579304332, 'euler344() should return 65579304332.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "One variant of N.G. de Bruijn's silver dollar game can be described as follows:", + "", + "On a strip of squares a number of coins are placed, at most one coin per square. Only one coin, called the silver dollar, has any value. Two players take turns making moves. At each turn a player must make either a regular or a special move.", + "", + "A regular move consists of selecting one coin and moving it one or more squares to the left. The coin cannot move out of the strip or jump on or over another coin.", + "", + "Alternatively, the player can choose to make the special move of pocketing the leftmost coin rather than making a regular move. If no regular moves are possible, the player is forced to pocket the leftmost coin.", + "", + "The winner is the player who pockets the silver dollar.", + "", + "", + "", + "", + "", + "A winning configuration is an arrangement of coins on the strip where the first player can force a win no matter what the second player does.", + "", + "Let W(n,c) be the number of winning configurations for a strip of n squares, c worthless coins and one silver dollar.", + "", + "You are given that W(10,2) = 324 and W(100,10) = 1514704946113500.", + "", + "Find W(1 000 000, 100) modulo the semiprime 1000 036 000 099 (= 1 000 003 · 1 000 033)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler344() {", + " // Good luck!", + " return true;", + "}", + "", + "euler344();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4c81000cf542c50ffda", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 345: Matrix Sum", + "tests": [ + { + "text": "euler345() should return 13938.", + "testString": "assert.strictEqual(euler345(), 13938, 'euler345() should return 13938.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We define the Matrix Sum of a matrix as the maximum sum of matrix elements with each element being the only one in his row and column. For example, the Matrix Sum of the matrix below equals 3315 ( = 863 + 383 + 343 + 959 + 767):", + "", + "", + "  7  53 183 439 863", + "497 383 563  79 973", + "287  63 343 169 583", + "627 343 773 959 943767 473 103 699 303", + "", + "", + "Find the Matrix Sum of:", + "", + "  7  53 183 439 863 497 383 563  79 973 287  63 343 169 583", + "627 343 773 959 943 767 473 103 699 303 957 703 583 639 913", + "447 283 463  29  23 487 463 993 119 883 327 493 423 159 743", + "217 623   3 399 853 407 103 983  89 463 290 516 212 462 350", + "960 376 682 962 300 780 486 502 912 800 250 346 172 812 350", + "870 456 192 162 593 473 915  45 989 873 823 965 425 329 803", + "973 965 905 919 133 673 665 235 509 613 673 815 165 992 326", + "322 148 972 962 286 255 941 541 265 323 925 281 601  95 973", + "445 721  11 525 473  65 511 164 138 672  18 428 154 448 848", + "414 456 310 312 798 104 566 520 302 248 694 976 430 392 198", + "184 829 373 181 631 101 969 613 840 740 778 458 284 760 390", + "821 461 843 513  17 901 711 993 293 157 274  94 192 156 574", + " 34 124   4 878 450 476 712 914 838 669 875 299 823 329 699", + "815 559 813 459 522 788 168 586 966 232 308 833 251 631 107", + "813 883 451 509 615  77 281 613 459 205 380 274 302  35 805" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler345() {", + " // Good luck!", + " return true;", + "}", + "", + "euler345();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4c71000cf542c50ffd8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 346: Strong Repunits", + "tests": [ + { + "text": "euler346() should return 336108797689259260.", + "testString": "assert.strictEqual(euler346(), 336108797689259260, 'euler346() should return 336108797689259260.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The number 7 is special, because 7 is 111 written in base 2, and 11 written in base 6 (i.e. 710 = 116 = 1112). In other words, 7 is a repunit in at least two bases b > 1. ", + "", + "", + "We shall call a positive integer with this property a strong repunit. It can be verified that there are 8 strong repunits below 50: {1,7,13,15,21,31,40,43}. Furthermore, the sum of all strong repunits below 1000 equals 15864.", + "", + "Find the sum of all strong repunits below 1012." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler346() {", + " // Good luck!", + " return true;", + "}", + "", + "euler346();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4c81000cf542c50ffd9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 347: Largest integer divisible by two primes", + "tests": [ + { + "text": "euler347() should return 11109800204052.", + "testString": "assert.strictEqual(euler347(), 11109800204052, 'euler347() should return 11109800204052.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The largest integer ≤ 100 that is only divisible by both the primes 2 and 3 is 96, as 96=32*3=25*3.", + "For two distinct primes p and q let M(p,q,N) be the largest positive integer ≤N only divisible", + "by both p and q and M(p,q,N)=0 if such a positive integer does not exist.", + "", + "", + "E.g. M(2,3,100)=96. ", + "M(3,5,100)=75 and not 90 because 90 is divisible by 2 ,3 and 5.", + "Also M(2,73,100)=0 because there does not exist a positive integer ≤ 100 that is divisible by both 2 and 73.", + "", + "", + "Let S(N) be the sum of all distinct M(p,q,N).", + "S(100)=2262.", + "", + "", + "Find S(10 000 000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler347() {", + " // Good luck!", + " return true;", + "}", + "", + "euler347();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4c81000cf542c50ffdb", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 348: Sum of a square and a cube", + "tests": [ + { + "text": "euler348() should return 1004195061.", + "testString": "assert.strictEqual(euler348(), 1004195061, 'euler348() should return 1004195061.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Many numbers can be expressed as the sum of a square and a cube. Some of them in more than one way.", + "", + "Consider the palindromic numbers that can be expressed as the sum of a square and a cube, both greater than 1, in exactly 4 different ways.", + "For example, 5229225 is a palindromic number and it can be expressed in exactly 4 different ways:", + "22852 + 203", + "22232 + 663", + "18102 + 1253", + "11972 + 1563", + " ", + "Find the sum of the five smallest such palindromic numbers." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler348() {", + " // Good luck!", + " return true;", + "}", + "", + "euler348();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ca1000cf542c50ffdc", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 349: Langton's ant", + "tests": [ + { + "text": "euler349() should return 115384615384614940.", + "testString": "assert.strictEqual(euler349(), 115384615384614940, 'euler349() should return 115384615384614940.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An ant moves on a regular grid of squares that are coloured either black or white. ", + "The ant is always oriented in one of the cardinal directions (left, right, up or down) and moves from square to adjacent square according to the following rules:", + "- if it is on a black square, it flips the color of the square to white, rotates 90 degrees counterclockwise and moves forward one square.", + "- if it is on a white square, it flips the color of the square to black, rotates 90 degrees clockwise and moves forward one square.", + "", + "Starting with a grid that is entirely white, how many squares are black after 1018 moves of the ant?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler349() {", + " // Good luck!", + " return true;", + "}", + "", + "euler349();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4cb1000cf542c50ffdd", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 350: Constraining the least greatest and the greatest least", + "tests": [ + { + "text": "euler350() should return 84664213.", + "testString": "assert.strictEqual(euler350(), 84664213, 'euler350() should return 84664213.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A list of size n is a sequence of n natural numbers. Examples are (2,4,6), (2,6,4), (10,6,15,6), and (11).", + "", + "The greatest common divisor, or gcd, of a list is the largest natural number that divides all entries of the list. Examples: gcd(2,6,4) = 2, gcd(10,6,15,6) = 1 and gcd(11) = 11.", + "", + "The least common multiple, or lcm, of a list is the smallest natural number divisible by each entry of the list. Examples: lcm(2,6,4) = 12, lcm(10,6,15,6) = 30 and lcm(11) = 11.", + "", + "Let f(G, L, N) be the number of lists of size N with gcd ≥ G and lcm ≤ L. For example:", + "", + "f(10, 100, 1) = 91.", + "f(10, 100, 2) = 327.", + "f(10, 100, 3) = 1135.", + "f(10, 100, 1000) mod 1014 = 3286053.", + "", + "Find f(106, 1012, 1018) mod 1014." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler350() {", + " // Good luck!", + " return true;", + "}", + "", + "euler350();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4cb1000cf542c50ffde", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 351: Hexagonal orchards", + "tests": [ + { + "text": "euler351() should return 11762187201804552.", + "testString": "assert.strictEqual(euler351(), 11762187201804552, 'euler351() should return 11762187201804552.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A hexagonal orchard of order n is a triangular lattice made up of points within a regular hexagon with side n. The following is an example of a hexagonal orchard of order 5:", + "", + "", + "", + "", + "", + "", + "Highlighted in green are the points which are hidden from the center by a point closer to it. It can be seen that for a hexagonal orchard of order 5, 30 points are hidden from the center.", + "", + "", + "", + "Let H(n) be the number of points hidden from the center in a hexagonal orchard of order n.", + "", + "", + "", + "H(5) = 30. H(10) = 138. H(1 000) = 1177848.", + "", + "", + "", + "Find H(100 000 000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler351() {", + " // Good luck!", + " return true;", + "}", + "", + "euler351();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4cd1000cf542c50ffdf", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 352: Blood tests", + "tests": [ + { + "text": "euler352() should return 378563.260589.", + "testString": "assert.strictEqual(euler352(), 378563.260589, 'euler352() should return 378563.260589.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Each one of the 25 sheep in a flock must be tested for a rare virus, known to affect 2% of the sheep population.", + "An accurate and extremely sensitive PCR test exists for blood samples, producing a clear positive / negative result, but it is very time-consuming and expensive.", + "", + "", + "", + "Because of the high cost, the vet-in-charge suggests that instead of performing 25 separate tests, the following procedure can be used instead:", + "The sheep are split into 5 groups of 5 sheep in each group. ", + "For each group, the 5 samples are mixed together and a single test is performed. Then,", + "If the result is negative, all the sheep in that group are deemed to be virus-free.", + "If the result is positive, 5 additional tests will be performed (a separate test for each animal) to determine the affected individual(s).", + "", + "Since the probability of infection for any specific animal is only 0.02, the first test (on the pooled samples) for each group will be:", + "Negative (and no more tests needed) with probability 0.985 = 0.9039207968.", + "Positive (5 additional tests needed) with probability 1 - 0.9039207968 = 0.0960792032.", + "", + "Thus, the expected number of tests for each group is 1 + 0.0960792032 × 5 = 1.480396016.", + "Consequently, all 5 groups can be screened using an average of only 1.480396016 × 5 = 7.40198008 tests, which represents a huge saving of more than 70% !", + "", + "", + "", + "Although the scheme we have just described seems to be very efficient, it can still be improved considerably (always assuming that the test is sufficiently sensitive and that there are no adverse effects caused by mixing different samples). E.g.:", + "We may start by running a test on a mixture of all the 25 samples. It can be verified that in about 60.35% of the cases this test will be negative, thus no more tests will be needed. Further testing will only be required for the remaining 39.65% of the cases.", + "If we know that at least one animal in a group of 5 is infected and the first 4 individual tests come out negative, there is no need to run a test on the fifth animal (we know that it must be infected).", + "We can try a different number of groups / different number of animals in each group, adjusting those numbers at each level so that the total expected number of tests will be minimised.", + "", + "To simplify the very wide range of possibilities, there is one restriction we place when devising the most cost-efficient testing scheme: whenever we start with a mixed sample, all the sheep contributing to that sample must be fully screened (i.e. a verdict of infected / virus-free must be reached for all of them) before we start examining any other animals.", + "", + "For the current example, it turns out that the most cost-efficient testing scheme (we'll call it the optimal strategy) requires an average of just 4.155452 tests!", + "", + "", + "", + "Using the optimal strategy, let T(s,p) represent the average number of tests needed to screen a flock of s sheep for a virus having probability p to be present in any individual.", + "Thus, rounded to six decimal places, T(25, 0.02) = 4.155452 and T(25, 0.10) = 12.702124.", + "", + "", + "", + "Find ΣT(10000, p) for p=0.01, 0.02, 0.03, ... 0.50.", + "Give your answer rounded to six decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler352() {", + " // Good luck!", + " return true;", + "}", + "", + "euler352();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4cd1000cf542c50ffe0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 353: Risky moon", + "tests": [ + { + "text": "euler353() should return 1.2759860331.", + "testString": "assert.strictEqual(euler353(), 1.2759860331, 'euler353() should return 1.2759860331.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A moon could be described by the sphere C(r) with centre (0,0,0) and radius r. ", + "", + "", + "", + "There are stations on the moon at the points on the surface of C(r) with integer coordinates. The station at (0,0,r) is called North Pole station, the station at (0,0,-r) is called South Pole station.", + "", + "", + "", + "All stations are connected with each other via the shortest road on the great arc through the stations. A journey between two stations is risky. If d is the length of the road between two stations, (d/(π r))2 is a measure for the risk of the journey (let us call it the risk of the road). If the journey includes more than two stations, the risk of the journey is the sum of risks of the used roads.", + "", + "", + "", + "A direct journey from the North Pole station to the South Pole station has the length πr and risk 1. The journey from the North Pole station to the South Pole station via (0,r,0) has the same length, but a smaller risk: (½πr/(πr))2+(½πr/(πr))2=0.5.", + "", + "", + "", + "The minimal risk of a journey from the North Pole station to the South Pole station on C(r) is M(r).", + "", + "", + "", + "You are given that M(7)=0.1784943998 rounded to 10 digits behind the decimal point. ", + "", + "", + "", + "Find ∑M(2n-1) for 1≤n≤15.", + "", + "", + "", + "Give your answer rounded to 10 digits behind the decimal point in the form a.bcdefghijk." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler353() {", + " // Good luck!", + " return true;", + "}", + "", + "euler353();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4cf1000cf542c50ffe1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 354: Distances in a bee's honeycomb", + "tests": [ + { + "text": "euler354() should return 58065134.", + "testString": "assert.strictEqual(euler354(), 58065134, 'euler354() should return 58065134.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider a honey bee's honeycomb where each cell is a perfect regular hexagon with side length 1.", + "", + "", + "", + "", + "", + "", + "One particular cell is occupied by the queen bee.", + "For a positive real number L, let B(L) count the cells with distance L from the queen bee cell (all distances are measured from centre to centre); you may assume that the honeycomb is large enough to accommodate for any distance we wish to consider. ", + "For example, B(√3) = 6, B(√21) = 12 and B(111 111 111) = 54.", + "", + "Find the number of L ≤ 5·1011 such that B(L) = 450." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler354() {", + " // Good luck!", + " return true;", + "}", + "", + "euler354();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4d01000cf542c50ffe2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 355: Maximal coprime subset", + "tests": [ + { + "text": "euler355() should return 1726545007.", + "testString": "assert.strictEqual(euler355(), 1726545007, 'euler355() should return 1726545007.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Define Co(n) to be the maximal possible sum of a set of mutually co-prime elements from {1, 2, ..., n}. For example Co(10) is 30 and hits that maximum on the subset {1, 5, 7, 8, 9}.", + "", + "", + "", + "You are given that Co(30) = 193 and Co(100) = 1356. ", + "", + "", + "Find Co(200000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler355() {", + " // Good luck!", + " return true;", + "}", + "", + "euler355();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4d01000cf542c50ffe3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 356: Largest roots of cubic polynomials", + "tests": [ + { + "text": "euler356() should return 28010159.", + "testString": "assert.strictEqual(euler356(), 28010159, 'euler356() should return 28010159.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let an be the largest real root of a polynomial g(x) = x3 - 2n·x2 + n.", + "For example, a2 = 3.86619826...", + "", + "", + "Find the last eight digits of.", + "", + "", + "Note: represents the floor function." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler356() {", + " // Good luck!", + " return true;", + "}", + "", + "euler356();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4d11000cf542c50ffe4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 357: Prime generating integers", + "tests": [ + { + "text": "euler357() should return 1739023853137.", + "testString": "assert.strictEqual(euler357(), 1739023853137, 'euler357() should return 1739023853137.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the divisors of 30: 1,2,3,5,6,10,15,30.", + "It can be seen that for every divisor d of 30, d+30/d is prime.", + "", + "", + "Find the sum of all positive integers n not exceeding 100 000 000such that", + "for every divisor d of n, d+n/d is prime." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler357() {", + " // Good luck!", + " return true;", + "}", + "", + "euler357();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4d21000cf542c50ffe5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 358: Cyclic numbers", + "tests": [ + { + "text": "euler358() should return 3284144505.", + "testString": "assert.strictEqual(euler358(), 3284144505, 'euler358() should return 3284144505.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A cyclic number with n digits has a very interesting property:", + "When it is multiplied by 1, 2, 3, 4, ... n, all the products have exactly the same digits, in the same order, but rotated in a circular fashion!", + "", + "", + "", + "The smallest cyclic number is the 6-digit number 142857 :", + "142857 × 1 = 142857", + "142857 × 2 = 285714", + "142857 × 3 = 428571", + "142857 × 4 = 571428", + "142857 × 5 = 714285", + "142857 × 6 = 857142 ", + "", + "", + "", + "The next cyclic number is 0588235294117647 with 16 digits :", + "0588235294117647 × 1 = 0588235294117647", + "0588235294117647 × 2 = 1176470588235294", + "0588235294117647 × 3 = 1764705882352941", + "...", + "0588235294117647 × 16 = 9411764705882352", + "", + "", + "", + "Note that for cyclic numbers, leading zeros are important.", + "", + "", + "", + "There is only one cyclic number for which, the eleven leftmost digits are 00000000137 and the five rightmost digits are 56789 (i.e., it has the form 00000000137...56789 with an unknown number of digits in the middle). Find the sum of all its digits." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler358() {", + " // Good luck!", + " return true;", + "}", + "", + "euler358();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4d31000cf542c50ffe6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 359: Hilbert's New Hotel", + "tests": [ + { + "text": "euler359() should return 40632119.", + "testString": "assert.strictEqual(euler359(), 40632119, 'euler359() should return 40632119.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An infinite number of people (numbered 1, 2, 3, etc.) are lined up to get a room at Hilbert's newest infinite hotel. The hotel contains an infinite number of floors (numbered 1, 2, 3, etc.), and each floor contains an infinite number of rooms (numbered 1, 2, 3, etc.). ", + "", + "", + "", + "Initially the hotel is empty. Hilbert declares a rule on how the nth person is assigned a room: person n gets the first vacant room in the lowest numbered floor satisfying either of the following:", + "the floor is empty", + "the floor is not empty, and if the latest person taking a room in that floor is person m, then m + n is a perfect square", + "", + "Person 1 gets room 1 in floor 1 since floor 1 is empty.", + "Person 2 does not get room 2 in floor 1 since 1 + 2 = 3 is not a perfect square.", + "Person 2 instead gets room 1 in floor 2 since floor 2 is empty.", + "Person 3 gets room 2 in floor 1 since 1 + 3 = 4 is a perfect square.", + "", + "", + "", + "Eventually, every person in the line gets a room in the hotel.", + "", + "", + "", + "Define P(f, r) to be n if person n occupies room r in floor f, and 0 if no person occupies the room. Here are a few examples:", + "P(1, 1) = 1", + "P(1, 2) = 3", + "P(2, 1) = 2", + "P(10, 20) = 440", + "P(25, 75) = 4863", + "P(99, 100) = 19454", + "", + "", + "", + "Find the sum of all P(f, r) for all positive f and r such that f × r = 71328803586048 and give the last 8 digits as your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler359() {", + " // Good luck!", + " return true;", + "}", + "", + "euler359();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4d41000cf542c50ffe7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 360: Scary Sphere", + "tests": [ + { + "text": "euler360() should return 878825614395267100.", + "testString": "assert.strictEqual(euler360(), 878825614395267100, 'euler360() should return 878825614395267100.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given two points (x1,y1,z1) and (x2,y2,z2) in three dimensional space, the Manhattan distance between those points is defined as |x1-x2|+|y1-y2|+|z1-z2|.", + "", + "", + "Let C(r) be a sphere with radius r and center in the origin O(0,0,0).", + "Let I(r) be the set of all points with integer coordinates on the surface of C(r).", + "Let S(r) be the sum of the Manhattan distances of all elements of I(r) to the origin O.", + "", + "", + "E.g. S(45)=34518.", + "", + "", + "Find S(1010)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler360() {", + " // Good luck!", + " return true;", + "}", + "", + "euler360();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4d51000cf542c50ffe8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 361: Subsequence of Thue-Morse sequence", + "tests": [ + { + "text": "euler361() should return 178476944.", + "testString": "assert.strictEqual(euler361(), 178476944, 'euler361() should return 178476944.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The Thue-Morse sequence {Tn} is a binary sequence satisfying:", + "T0 = 0", + "T2n = Tn", + "T2n+1 = 1 - Tn", + "", + "The first several terms of {Tn} are given as follows:", + "01101001100101101001011001101001....", + "", + "", + "", + "We define {An} as the sorted sequence of integers such that the binary expression of each element appears as a subsequence in {Tn}.", + "For example, the decimal number 18 is expressed as 10010 in binary. 10010 appears in {Tn} (T8 to T12), so 18 is an element of {An}.", + "The decimal number 14 is expressed as 1110 in binary. 1110 never appears in {Tn}, so 14 is not an element of {An}.", + "", + "", + "", + "The first several terms of An are given as follows:", + "n0123456789101112…An012345691011121318…", + "", + "", + "", + "We can also verify that A100 = 3251 and A1000 = 80852364498.", + "", + "", + "", + "Find the last 9 digits of ." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler361() {", + " // Good luck!", + " return true;", + "}", + "", + "euler361();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4d61000cf542c50ffe9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 362: Squarefree factors", + "tests": [ + { + "text": "euler362() should return 457895958010.", + "testString": "assert.strictEqual(euler362(), 457895958010, 'euler362() should return 457895958010.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the number 54.", + "54 can be factored in 7 distinct ways into one or more factors larger than 1:", + "54, 2×27, 3×18, 6×9, 3×3×6, 2×3×9 and 2×3×3×3.", + "If we require that the factors are all squarefree only two ways remain: 3×3×6 and 2×3×3×3.", + "", + "", + "Let's call Fsf(n) the number of ways n can be factored into one or more squarefree factors larger than 1, so", + "Fsf(54)=2.", + "", + "", + "Let S(n) be ∑Fsf(k) for k=2 to n.", + "", + "", + "S(100)=193.", + "", + "", + "Find S(10 000 000 000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler362() {", + " // Good luck!", + " return true;", + "}", + "", + "euler362();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4d91000cf542c50ffeb", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 363: Bézier Curves", + "tests": [ + { + "text": "euler363() should return 0.0000372091.", + "testString": "assert.strictEqual(euler363(), 0.0000372091, 'euler363() should return 0.0000372091.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A cubic Bézier curve is defined by four points: P0, P1, P2 and P3.", + "", + "", + "", + "The curve is constructed as follows:", + "On the segments P0P1, P1P2 and P2P3 the points Q0,Q1 and Q2 are drawn such that", + "P0Q0 / P0P1 = P1Q1 / P1P2 = P2Q2 / P2P3 = t (t in [0,1]).", + "On the segments Q0Q1 and Q1Q2 the points R0 and R1 are drawn such that", + "Q0R0 / Q0Q1 = Q1R1 / Q1Q2 = t for the same value of t.", + "On the segment R0R1 the point B is drawn such that R0B / R0R1 = t for the same value of t.", + "The Bézier curve defined by the points P0, P1, P2, P3 is the locus of B as Q0 takes all possible positions on the segment P0P1.", + "(Please note that for all points the value of t is the same.)", + "", + "At this (external) web address you will find an applet that allows you to drag the points P0, P1, P2 and P3 to see what the Bézier curve (green curve) defined by those points looks like. You can also drag the point Q0 along the segment P0P1.", + "", + "From the construction it is clear that the Bézier curve will be tangent to the segments P0P1 in P0 and P2P3 in P3.", + "", + "A cubic Bézier curve with P0=(1,0), P1=(1,v), P2=(v,1) and P3=(0,1) is used to approximate a quarter circle.", + "The value v > 0 is chosen such that the area enclosed by the lines OP0, OP3 and the curve is equal to π/4 (the area of the quarter circle).", + "", + "By how many percent does the length of the curve differ from the length of the quarter circle?", + "That is, if L is the length of the curve, calculate 100 × L − π/2π/2Give your answer rounded to 10 digits behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler363() {", + " // Good luck!", + " return true;", + "}", + "", + "euler363();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4d91000cf542c50ffea", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 364: Comfortable distance", + "tests": [ + { + "text": "euler364() should return 44855254.", + "testString": "assert.strictEqual(euler364(), 44855254, 'euler364() should return 44855254.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "There are N seats in a row. N people come after each other to fill the seats according to the following rules:", + "If there is any seat whose adjacent seat(s) are not occupied take such a seat.", + "If there is no such seat and there is any seat for which only one adjacent seat is occupied take such a seat.", + "Otherwise take one of the remaining available seats. ", + "", + "Let T(N) be the number of possibilities that N seats are occupied by N people with the given rules. The following figure shows T(4)=8.", + "", + "", + "", + "", + "", + "We can verify that T(10) = 61632 and T(1 000) mod 100 000 007 = 47255094.", + "Find T(1 000 000) mod 100 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler364() {", + " // Good luck!", + " return true;", + "}", + "", + "euler364();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4da1000cf542c50ffec", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 365: A huge binomial coefficient", + "tests": [ + { + "text": "euler365() should return 162619462356610300.", + "testString": "assert.strictEqual(euler365(), 162619462356610300, 'euler365() should return 162619462356610300.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The binomial coefficient C(1018,109) is a number with more than 9 billion (9×109) digits.", + "", + "", + "Let M(n,k,m) denote the binomial coefficient C(n,k) modulo m.", + "", + "", + "Calculate ∑M(1018,109,p*q*r) for 1000euler366() should return 88351299.", + "testString": "assert.strictEqual(euler366(), 88351299, 'euler366() should return 88351299.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Two players, Anton and Bernhard, are playing the following game.", + "There is one pile of n stones.", + "The first player may remove any positive number of stones, but not the whole pile.", + "Thereafter, each player may remove at most twice the number of stones his opponent took on the previous move.", + "The player who removes the last stone wins.", + "", + "", + "E.g. n=5", + "If the first player takes anything more than one stone the next player will be able to take all remaining stones.", + "If the first player takes one stone, leaving four, his opponent will take also one stone, leaving three stones.", + "The first player cannot take all three because he may take at most 2x1=2 stones. So let's say he takes also one stone, leaving 2. The second player can take the two remaining stones and wins.", + "So 5 is a losing position for the first player.", + "For some winning positions there is more than one possible move for the first player.", + "E.g. when n=17 the first player can remove one or four stones.", + "", + "", + "Let M(n) be the maximum number of stones the first player can take from a winning position at his first turn and M(n)=0 for any other position.", + "", + "", + "∑M(n) for n≤100 is 728.", + "", + "", + "Find ∑M(n) for n≤1018.", + "Give your answer modulo 108." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler366() {", + " // Good luck!", + " return true;", + "}", + "", + "euler366();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4db1000cf542c50ffee", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 367: Bozo sort", + "tests": [ + { + "text": "euler367() should return 48271207.", + "testString": "assert.strictEqual(euler367(), 48271207, 'euler367() should return 48271207.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Bozo sort, not to be confused with the slightly less efficient bogo sort, consists out of checking if the input sequence is sorted and if not swapping randomly two elements. This is repeated until eventually the sequence is sorted.", + "", + "", + "If we consider all permutations of the first 4 natural numbers as input the expectation value of the number of swaps, averaged over all 4! input sequences is 24.75.", + "The already sorted sequence takes 0 steps. ", + "", + "", + "In this problem we consider the following variant on bozo sort.", + "If the sequence is not in order we pick three elements at random and shuffle these three elements randomly.", + "All 3!=6 permutations of those three elements are equally likely. ", + "The already sorted sequence will take 0 steps.", + "If we consider all permutations of the first 4 natural numbers as input the expectation value of the number of shuffles, averaged over all 4! input sequences is 27.5. ", + "Consider as input sequences the permutations of the first 11 natural numbers.", + "Averaged over all 11! input sequences, what is the expected number of shuffles this sorting algorithm will perform?", + "", + "", + "Give your answer rounded to the nearest integer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler367() {", + " // Good luck!", + " return true;", + "}", + "", + "euler367();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4dd1000cf542c50ffef", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 368: A Kempner-like series", + "tests": [ + { + "text": "euler368() should return 253.6135092068.", + "testString": "assert.strictEqual(euler368(), 253.6135092068, 'euler368() should return 253.6135092068.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The harmonic series $1 + \\dfrac{1}{2} + \\dfrac{1}{3} + \\dfrac{1}{4} + ...$ is well known to be divergent.", + "", + "If we however omit from this series every term where the denominator has a 9 in it, the series remarkably enough converges to approximately 22.9206766193.", + "This modified harmonic series is called the Kempner series.", + "", + "Let us now consider another modified harmonic series by omitting from the harmonic series every term where the denominator has 3 or more equal consecutive digits.", + "One can verify that out of the first 1200 terms of the harmonic series, only 20 terms will be omitted.", + "These 20 omitted terms are:", + "$$\\dfrac{1}{111}, \\dfrac{1}{222}, \\dfrac{1}{333}, \\dfrac{1}{444}, \\dfrac{1}{555}, \\dfrac{1}{666}, \\dfrac{1}{777}, \\dfrac{1}{888}, \\dfrac{1}{999}, \\dfrac{1}{1000}, \\dfrac{1}{1110}, \\\\\\ \\dfrac{1}{1111}, \\dfrac{1}{1112}, \\dfrac{1}{1113}, \\dfrac{1}{1114}, \\dfrac{1}{1115}, \\dfrac{1}{1116}, \\dfrac{1}{1117}, \\dfrac{1}{1118}, \\dfrac{1}{1119}$$", + "", + "This series converges as well.", + "", + "Find the value the series converges to.", + "Give your answer rounded to 10 digits behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler368() {", + " // Good luck!", + " return true;", + "}", + "", + "euler368();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4de1000cf542c50fff0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 369: Badugi", + "tests": [ + { + "text": "euler369() should return 862400558448.", + "testString": "assert.strictEqual(euler369(), 862400558448, 'euler369() should return 862400558448.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In a standard 52 card deck of playing cards, a set of 4 cards is a Badugi if it contains 4 cards with no pairs and no two cards of the same suit.", + "", + "Let f(n) be the number of ways to choose n cards with a 4 card subset that is a Badugi. For example, there are 2598960 ways to choose five cards from a standard 52 card deck, of which 514800 contain a 4 card subset that is a Badugi, so f(5) = 514800.", + "", + "Find ∑f(n) for 4 ≤ n ≤ 13." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler369() {", + " // Good luck!", + " return true;", + "}", + "", + "euler369();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4de1000cf542c50fff1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 370: Geometric triangles", + "tests": [ + { + "text": "euler370() should return 41791929448408.", + "testString": "assert.strictEqual(euler370(), 41791929448408, 'euler370() should return 41791929448408.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let us define a geometric triangle as an integer sided triangle with sides a ≤ b ≤ c so that its sides form a geometric progression, i.e. b2 = a · c .  ", + "", + "An example of such a geometric triangle is the triangle with sides a = 144, b = 156 and c = 169.", + "", + "There are 861805 geometric triangles with perimeter ≤ 106 .", + "", + "How many geometric triangles exist with perimeter ≤ 2.5·1013 ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler370() {", + " // Good luck!", + " return true;", + "}", + "", + "euler370();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4e01000cf542c50fff2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 371: Licence plates", + "tests": [ + { + "text": "euler371() should return 40.66368097.", + "testString": "assert.strictEqual(euler371(), 40.66368097, 'euler371() should return 40.66368097.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Oregon licence plates consist of three letters followed by a three digit number (each digit can be from [0..9]).", + "While driving to work Seth plays the following game:", + "Whenever the numbers of two licence plates seen on his trip add to 1000 that's a win.", + "", + "", + "E.g. MIC-012 and HAN-988 is a win and RYU-500 and SET-500 too. (as long as he sees them in the same trip). ", + "", + "", + "Find the expected number of plates he needs to see for a win.", + "Give your answer rounded to 8 decimal places behind the decimal point.", + "", + "", + "Note: We assume that each licence plate seen is equally likely to have any three digit number on it." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler371() {", + " // Good luck!", + " return true;", + "}", + "", + "euler371();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4e11000cf542c50fff3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 372: Pencils of rays", + "tests": [ + { + "text": "euler372() should return 301450082318807040.", + "testString": "assert.strictEqual(euler372(), 301450082318807040, 'euler372() should return 301450082318807040.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let R(M, N) be the number of lattice points (x, y) which satisfy Meuler373() should return 727227472448913.", + "testString": "assert.strictEqual(euler373(), 727227472448913, 'euler373() should return 727227472448913.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Every triangle has a circumscribed circle that goes through the three vertices.", + "Consider all integer sided triangles for which the radius of the circumscribed circle is integral as well.", + "", + "", + "Let S(n) be the sum of the radii of the circumscribed circles of all such triangles for which the radius does not exceed n.", + "", + "S(100)=4950 and S(1200)=1653605.", + "", + "", + "Find S(107)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler373() {", + " // Good luck!", + " return true;", + "}", + "", + "euler373();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4e51000cf542c50fff6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 374: Maximum Integer Partition Product", + "tests": [ + { + "text": "euler374() should return 334420941.", + "testString": "assert.strictEqual(euler374(), 334420941, 'euler374() should return 334420941.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An integer partition of a number n is a way of writing n as a sum of positive integers.", + "", + "Partitions that differ only in the order of their summands are considered the same.", + "A partition of n into distinct parts is a partition of n in which every part occurs at most once.", + "", + "The partitions of 5 into distinct parts are:", + "5, 4+1 and 3+2.", + "", + "Let f(n) be the maximum product of the parts of any such partition of n into distinct parts and let m(n) be the number of elements of any such partition of n with that product.", + "", + "So f(5)=6 and m(5)=2.", + "", + "For n=10 the partition with the largest product is 10=2+3+5, which gives f(10)=30 and m(10)=3.", + "And their product, f(10)·m(10) = 30·3 = 90", + "", + "It can be verified that", + "∑f(n)·m(n) for 1 ≤ n ≤ 100 = 1683550844462.", + "", + "Find ∑f(n)·m(n) for 1 ≤ n ≤ 1014.", + "Give your answer modulo 982451653, the 50 millionth prime." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler374() {", + " // Good luck!", + " return true;", + "}", + "", + "euler374();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4e41000cf542c50fff5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 375: Minimum of subsequences", + "tests": [ + { + "text": "euler375() should return 7435327983715286000.", + "testString": "assert.strictEqual(euler375(), 7435327983715286000, 'euler375() should return 7435327983715286000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let Sn be an integer sequence produced with the following pseudo-random number generator:", + "S0", + " = ", + " 290797 ", + " Sn+1", + " = ", + " Sn2 mod 50515093", + " ", + "", + "", + "Let A(i, j) be the minimum of the numbers Si, Si+1, ... , Sj for i ≤ j.", + "Let M(N) = ΣA(i, j) for 1 ≤ i ≤ j ≤ N.", + "We can verify that M(10) = 432256955 and M(10 000) = 3264567774119.", + "", + "", + "Find M(2 000 000 000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler375() {", + " // Good luck!", + " return true;", + "}", + "", + "euler375();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4e51000cf542c50fff7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 376: Nontransitive sets of dice", + "tests": [ + { + "text": "euler376() should return 973059630185670.", + "testString": "assert.strictEqual(euler376(), 973059630185670, 'euler376() should return 973059630185670.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the following set of dice with nonstandard pips:", + "", + "", + "", + "Die A: 1 4 4 4 4 4", + "Die B: 2 2 2 5 5 5", + "Die C: 3 3 3 3 3 6", + "", + "", + "A game is played by two players picking a die in turn and rolling it. The player who rolls the highest value wins.", + "", + "", + "", + "If the first player picks die A and the second player picks die B we get", + "P(second player wins) = 7/12 > 1/2", + "", + "", + "If the first player picks die B and the second player picks die C we get", + "P(second player wins) = 7/12 > 1/2", + "", + "", + "If the first player picks die C and the second player picks die A we get", + "P(second player wins) = 25/36 > 1/2", + "", + "", + "So whatever die the first player picks, the second player can pick another die and have a larger than 50% chance of winning.", + "A set of dice having this property is called a nontransitive set of dice.", + "", + "", + "", + "We wish to investigate how many sets of nontransitive dice exist. We will assume the following conditions:There are three six-sided dice with each side having between 1 and N pips, inclusive.", + "Dice with the same set of pips are equal, regardless of which side on the die the pips are located.", + "The same pip value may appear on multiple dice; if both players roll the same value neither player wins.", + "The sets of dice {A,B,C}, {B,C,A} and {C,A,B} are the same set.", + "", + "For N = 7 we find there are 9780 such sets.", + "How many are there for N = 30 ?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler376() {", + " // Good luck!", + " return true;", + "}", + "", + "euler376();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4e51000cf542c50fff8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 377: Sum of digits, experience 13", + "tests": [ + { + "text": "euler377() should return 732385277.", + "testString": "assert.strictEqual(euler377(), 732385277, 'euler377() should return 732385277.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "There are 16 positive integers that do not have a zero in their digits and that have a digital sum equal to 5, namely: ", + "5, 14, 23, 32, 41, 113, 122, 131, 212, 221, 311, 1112, 1121, 1211, 2111 and 11111.", + "Their sum is 17891.", + "", + "", + "Let f(n) be the sum of all positive integers that do not have a zero in their digits and have a digital sum equal to n.", + "", + "", + "Find $\\displaystyle \\sum_{i=1}^{17} f(13^i)$.", + "Give the last 9 digits as your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler377() {", + " // Good luck!", + " return true;", + "}", + "", + "euler377();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4e61000cf542c50fff9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 378: Triangle Triples", + "tests": [ + { + "text": "euler378() should return 147534623725724700.", + "testString": "assert.strictEqual(euler378(), 147534623725724700, 'euler378() should return 147534623725724700.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let T(n) be the nth triangle number, so T(n) =", + "", + "", + "n (n+1)2", + "", + ".", + "", + "", + "Let dT(n) be the number of divisors of T(n).", + "E.g.:", + "T(7) = 28 and dT(7) = 6.", + "", + "", + "Let Tr(n) be the number of triples (i, j, k) such that 1 ≤ i < j < k ≤ n and dT(i) > dT(j) > dT(k).", + "Tr(20) = 14, Tr(100) = 5772 and Tr(1000) = 11174776.", + "", + "", + "Find Tr(60 000 000). ", + "Give the last 18 digits of your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler378() {", + " // Good luck!", + " return true;", + "}", + "", + "euler378();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4e81000cf542c50fffa", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 379: Least common multiple count", + "tests": [ + { + "text": "euler379() should return 132314136838185.", + "testString": "assert.strictEqual(euler379(), 132314136838185, 'euler379() should return 132314136838185.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let f(n) be the number of couples (x,y) with x and y positive integers, x ≤ y and the least common multiple of x and y equal to n.", + "", + "", + "Let g be the summatory function of f, i.e.: ", + "g(n) = ∑ f(i) for 1 ≤ i ≤ n.", + "", + "", + "You are given that g(106) = 37429395.", + "", + "", + "Find g(1012)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler379() {", + " // Good luck!", + " return true;", + "}", + "", + "euler379();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4e81000cf542c50fffb", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 380: Amazing Mazes!", + "tests": [ + { + "text": "euler380() should return Infinity.", + "testString": "assert.strictEqual(euler380(), Infinity, 'euler380() should return Infinity.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An m×n maze is an m×n rectangular grid with walls placed between grid cells such that there is exactly one path from the top-left square to any other square. The following are examples of a 9×12 maze and a 15×20 maze:", + "", + "", + "", + "", + "Let C(m,n) be the number of distinct m×n mazes. Mazes which can be formed by rotation and reflection from another maze are considered distinct.", + "", + "", + "It can be verified that C(1,1) = 1, C(2,2) = 4, C(3,4) = 2415, and C(9,12) = 2.5720e46 (in scientific notation rounded to 5 significant digits).", + "Find C(100,500) and write your answer in scientific notation rounded to 5 significant digits.", + "", + "", + "When giving your answer, use a lowercase e to separate mantissa and exponent.", + "E.g. if the answer is 1234567891011 then the answer format would be 1.2346e12." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler380() {", + " // Good luck!", + " return true;", + "}", + "", + "euler380();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ea1000cf542c50fffc", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 381: (prime-k) factorial", + "tests": [ + { + "text": "euler381() should return 139602943319822.", + "testString": "assert.strictEqual(euler381(), 139602943319822, 'euler381() should return 139602943319822.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a prime p let S(p) = (∑(p-k)!) mod(p) for 1 ≤ k ≤ 5.", + "", + "", + "For example, if p=7,", + "(7-1)! + (7-2)! + (7-3)! + (7-4)! + (7-5)! = 6! + 5! + 4! + 3! + 2! = 720+120+24+6+2 = 872. ", + "As 872 mod(7) = 4, S(7) = 4.", + "", + "", + "It can be verified that ∑S(p) = 480 for 5 ≤ p < 100.", + "", + "", + "Find ∑S(p) for 5 ≤ p < 108." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler381() {", + " // Good luck!", + " return true;", + "}", + "", + "euler381();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4eb1000cf542c50fffd", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 382: Generating polygons", + "tests": [ + { + "text": "euler382() should return 697003956.", + "testString": "assert.strictEqual(euler382(), 697003956, 'euler382() should return 697003956.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A polygon is a flat shape consisting of straight line segments that are joined to form a closed chain or circuit. A polygon consists of at least three sides and does not self-intersect.", + "", + "", + "", + "A set S of positive numbers is said to generate a polygon P if: no two sides of P are the same length,", + " the length of every side of P is in S, and", + " S contains no other value.", + "", + "For example:", + "The set {3, 4, 5} generates a polygon with sides 3, 4, and 5 (a triangle).", + "The set {6, 9, 11, 24} generates a polygon with sides 6, 9, 11, and 24 (a quadrilateral).", + "The sets {1, 2, 3} and {2, 3, 4, 9} do not generate any polygon at all.", + "", + "", + "Consider the sequence s, defined as follows:s1 = 1, s2 = 2, s3 = 3", + "sn = sn-1 + sn-3 for n > 3.", + "", + "Let Un be the set {s1, s2, ..., sn}. For example, U10 = {1, 2, 3, 4, 6, 9, 13, 19, 28, 41}.", + "Let f(n) be the number of subsets of Un which generate at least one polygon.", + "For example, f(5) = 7, f(10) = 501 and f(25) = 18635853.", + "", + "", + "", + "Find the last 9 digits of f(1018)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler382() {", + " // Good luck!", + " return true;", + "}", + "", + "euler382();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ed1000cf542c50ffff", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 383: Divisibility comparison between factorials", + "tests": [ + { + "text": "euler383() should return 22173624649806.", + "testString": "assert.strictEqual(euler383(), 22173624649806, 'euler383() should return 22173624649806.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let f5(n) be the largest integer x for which 5x divides n.", + "For example, f5(625000) = 7.", + "", + "", + "", + "Let T5(n) be the number of integers i which satisfy f5((2·i-1)!) < 2·f5(i!) and 1 ≤ i ≤ n.", + "It can be verified that T5(103) = 68 and T5(109) = 2408210.", + "", + "", + "", + "Find T5(1018)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler383() {", + " // Good luck!", + " return true;", + "}", + "", + "euler383();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ed1000cf542c50fffe", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 384: Rudin-Shapiro sequence", + "tests": [ + { + "text": "euler384() should return 3354706415856333000.", + "testString": "assert.strictEqual(euler384(), 3354706415856333000, 'euler384() should return 3354706415856333000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Define the sequence a(n) as the number of adjacent pairs of ones in the binary expansion of n (possibly overlapping).", + "E.g.: a(5) = a(1012) = 0, a(6) = a(1102) = 1, a(7) = a(1112) = 2", + "", + "Define the sequence b(n) = (-1)a(n).", + "This sequence is called the Rudin-Shapiro sequence.", + "Also consider the summatory sequence of b(n): .", + "", + "The first couple of values of these sequences are:", + "n        0     1     2     3     4     5     6     7", + "a(n)     0     0     0     1     0     0     1     2", + "b(n)     1     1     1    -1     1     1    -1     1", + "s(n)     1     2     3     2     3     4     3     4", + "", + "The sequence s(n) has the remarkable property that all elements are positive and every positive integer k occurs exactly k times.", + "", + "Define g(t,c), with 1 ≤ c ≤ t, as the index in s(n) for which t occurs for the c'th time in s(n).", + "E.g.: g(3,3) = 6, g(4,2) = 7 and g(54321,12345) = 1220847710.", + "", + "Let F(n) be the fibonacci sequence defined by:", + "F(0)=F(1)=1 and", + "F(n)=F(n-1)+F(n-2) for n>1.", + "", + "Define GF(t)=g(F(t),F(t-1)).", + "", + "Find ΣGF(t) for 2≤t≤45." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler384() {", + " // Good luck!", + " return true;", + "}", + "", + "euler384();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ee1000cf542c510000", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 385: Ellipses inside triangles", + "tests": [ + { + "text": "euler385() should return 3776957309612154000.", + "testString": "assert.strictEqual(euler385(), 3776957309612154000, 'euler385() should return 3776957309612154000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For any triangle T in the plane, it can be shown that there is a unique ellipse with largest area that is completely inside T.", + "", + "", + "", + "For a given n, consider triangles T such that:", + "- the vertices of T have integer coordinates with absolute value ≤ n, and ", + "- the foci1 of the largest-area ellipse inside T are (√13,0) and (-√13,0).", + "Let A(n) be the sum of the areas of all such triangles.", + "", + "", + "For example, if n = 8, there are two such triangles. Their vertices are (-4,-3),(-4,3),(8,0) and (4,3),(4,-3),(-8,0), and the area of each triangle is 36. Thus A(8) = 36 + 36 = 72.", + "", + "", + "It can be verified that A(10) = 252, A(100) = 34632 and A(1000) = 3529008.", + "", + "", + "Find A(1 000 000 000).", + "", + "", + "", + "1The foci (plural of focus) of an ellipse are two points A and B such that for every point P on the boundary of the ellipse, AP + PB is constant." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler385() {", + " // Good luck!", + " return true;", + "}", + "", + "euler385();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ef1000cf542c510001", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 386: Maximum length of an antichain", + "tests": [ + { + "text": "euler386() should return 528755790.", + "testString": "assert.strictEqual(euler386(), 528755790, 'euler386() should return 528755790.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let n be an integer and S(n) be the set of factors of n.", + "", + "A subset A of S(n) is called an antichain of S(n) if A contains only one element or if none of the elements of A divides any of the other elements of A.", + "", + "For example: S(30) = {1, 2, 3, 5, 6, 10, 15, 30}", + "{2, 5, 6} is not an antichain of S(30).", + "{2, 3, 5} is an antichain of S(30).", + "", + "Let N(n) be the maximum length of an antichain of S(n).", + "", + "Find ΣN(n) for 1 ≤ n ≤ 108" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler386() {", + " // Good luck!", + " return true;", + "}", + "", + "euler386();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f11000cf542c510003", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 387: Harshad Numbers", + "tests": [ + { + "text": "euler387() should return 696067597313468.", + "testString": "assert.strictEqual(euler387(), 696067597313468, 'euler387() should return 696067597313468.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A Harshad or Niven number is a number that is divisible by the sum of its digits.", + "201 is a Harshad number because it is divisible by 3 (the sum of its digits.)", + "When we truncate the last digit from 201, we get 20, which is a Harshad number.", + "When we truncate the last digit from 20, we get 2, which is also a Harshad number.", + "Let's call a Harshad number that, while recursively truncating the last digit, always results in a Harshad number a right truncatable Harshad number. ", + "", + "Also:", + "201/3=67 which is prime.", + "Let's call a Harshad number that, when divided by the sum of its digits, results in a prime a strong Harshad number.", + "", + "Now take the number 2011 which is prime.", + "When we truncate the last digit from it we get 201, a strong Harshad number that is also right truncatable.", + "Let's call such primes strong, right truncatable Harshad primes.", + "", + "You are given that the sum of the strong, right truncatable Harshad primes less than 10000 is 90619.", + "", + "Find the sum of the strong, right truncatable Harshad primes less than 1014." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler387() {", + " // Good luck!", + " return true;", + "}", + "", + "euler387();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f11000cf542c510002", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 388: Distinct Lines", + "tests": [ + { + "text": "euler388() should return 831907372805130000.", + "testString": "assert.strictEqual(euler388(), 831907372805130000, 'euler388() should return 831907372805130000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider all lattice points (a,b,c) with 0 ≤ a,b,c ≤ N.", + "", + "", + "From the origin O(0,0,0) all lines are drawn to the other lattice points.", + "Let D(N) be the number of distinct such lines.", + "", + "", + "You are given that D(1 000 000) = 831909254469114121.", + "", + "Find D(1010). Give as your answer the first nine digits followed by the last nine digits." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler388() {", + " // Good luck!", + " return true;", + "}", + "", + "euler388();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f21000cf542c510004", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 389: Platonic Dice", + "tests": [ + { + "text": "euler389() should return 2406376.3623.", + "testString": "assert.strictEqual(euler389(), 2406376.3623, 'euler389() should return 2406376.3623.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An unbiased single 4-sided die is thrown and its value, T, is noted.T unbiased 6-sided dice are thrown and their scores are added together. The sum, C, is noted.C unbiased 8-sided dice are thrown and their scores are added together. The sum, O, is noted.O unbiased 12-sided dice are thrown and their scores are added together. The sum, D, is noted.D unbiased 20-sided dice are thrown and their scores are added together. The sum, I, is noted.", + "Find the variance of I, and give your answer rounded to 4 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler389() {", + " // Good luck!", + " return true;", + "}", + "", + "euler389();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f21000cf542c510005", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 390: Triangles with non rational sides and integral area", + "tests": [ + { + "text": "euler390() should return 2919133642971.", + "testString": "assert.strictEqual(euler390(), 2919133642971, 'euler390() should return 2919133642971.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the triangle with sides √5, √65 and √68.", + "It can be shown that this triangle has area 9.", + "", + "S(n) is the sum of the areas of all triangles with sides √(1+b2), √(1+c2) and √(b2+c2) (for positive integers b and c ) that have an integral area not exceeding n.", + "", + "The example triangle has b=2 and c=8.", + "", + "S(106)=18018206.", + "", + "Find S(1010)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler390() {", + " // Good luck!", + " return true;", + "}", + "", + "euler390();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f31000cf542c510006", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 391: Hopping Game", + "tests": [ + { + "text": "euler391() should return 61029882288.", + "testString": "assert.strictEqual(euler391(), 61029882288, 'euler391() should return 61029882288.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let sk be the number of 1’s when writing the numbers from 0 to k in binary.", + "For example, writing 0 to 5 in binary, we have 0, 1, 10, 11, 100, 101. There are seven 1’s, so s5 = 7.", + "The sequence S = {sk : k ≥ 0} starts {0, 1, 2, 4, 5, 7, 9, 12, ...}.", + "", + "", + "A game is played by two players. Before the game starts, a number n is chosen. A counter c starts at 0. At each turn, the player chooses a number from 1 to n (inclusive) and increases c by that number. The resulting value of c must be a member of S. If there are no more valid moves, the player loses.", + "", + "", + "", + "For example:", + "Let n = 5. c starts at 0.", + "Player 1 chooses 4, so c becomes 0 + 4 = 4.", + "Player 2 chooses 5, so c becomes 4 + 5 = 9.", + "Player 1 chooses 3, so c becomes 9 + 3 = 12.", + "etc.", + "Note that c must always belong to S, and each player can increase c by at most n.", + "", + "", + "", + "Let M(n) be the highest number the first player can choose at her first turn to force a win, and M(n) = 0 if there is no such move. For example, M(2) = 2, M(7) = 1 and M(20) = 4.", + "", + "", + "", + "Given Σ(M(n))3 = 8150 for 1 ≤ n ≤ 20.", + "", + "", + "", + "Find Σ(M(n))3 for 1 ≤ n ≤ 1000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler391() {", + " // Good luck!", + " return true;", + "}", + "", + "euler391();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f41000cf542c510007", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 392: Enmeshed unit circle", + "tests": [ + { + "text": "euler392() should return 3.1486734435.", + "testString": "assert.strictEqual(euler392(), 3.1486734435, 'euler392() should return 3.1486734435.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A rectilinear grid is an orthogonal grid where the spacing between the gridlines does not have to be equidistant.", + "An example of such grid is logarithmic graph paper.", + "", + "", + "Consider rectilinear grids in the Cartesian coordinate system with the following properties:The gridlines are parallel to the axes of the Cartesian coordinate system.There are N+2 vertical and N+2 horizontal gridlines. Hence there are (N+1) x (N+1) rectangular cells.The equations of the two outer vertical gridlines are x = -1 and x = 1.The equations of the two outer horizontal gridlines are y = -1 and y = 1.The grid cells are colored red if they overlap with the unit circle, black otherwise.For this problem we would like you to find the positions of the remaining N inner horizontal and N inner vertical gridlines so that the area occupied by the red cells is minimized.", + "", + "", + "E.g. here is a picture of the solution for N = 10:", + "", + "", + "", + "", + "The area occupied by the red cells for N = 10 rounded to 10 digits behind the decimal point is 3.3469640797.", + "", + "", + "Find the positions for N = 400. ", + "Give as your answer the area occupied by the red cells rounded to 10 digits behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler392() {", + " // Good luck!", + " return true;", + "}", + "", + "euler392();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f61000cf542c510008", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 393: Migrating ants", + "tests": [ + { + "text": "euler393() should return 112398351350823100.", + "testString": "assert.strictEqual(euler393(), 112398351350823100, 'euler393() should return 112398351350823100.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An n×n grid of squares contains n2 ants, one ant per square.", + "All ants decide to move simultaneously to an adjacent square (usually 4 possibilities, except for ants on the edge of the grid or at the corners).", + "We define f(n) to be the number of ways this can happen without any ants ending on the same square and without any two ants crossing the same edge between two squares.", + "", + "", + "You are given that f(4) = 88.", + "Find f(10)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler393() {", + " // Good luck!", + " return true;", + "}", + "", + "euler393();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f71000cf542c510009", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 394: Eating pie", + "tests": [ + { + "text": "euler394() should return 3.2370342194.", + "testString": "assert.strictEqual(euler394(), 3.2370342194, 'euler394() should return 3.2370342194.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Jeff eats a pie in an unusual way.", + "The pie is circular. He starts with slicing an initial cut in the pie along a radius.", + "While there is at least a given fraction F of pie left, he performs the following procedure:", + "- He makes two slices from the pie centre to any point of what is remaining of the pie border, any point on the remaining pie border equally likely. This will divide the remaining pie into three pieces. ", + "- Going counterclockwise from the initial cut, he takes the first two pie pieces and eats them.", + "When less than a fraction F of pie remains, he does not repeat this procedure. Instead, he eats all of the remaining pie.", + "", + "", + "", + "", + "", + "", + "For x ≥ 1, let E(x) be the expected number of times Jeff repeats the procedure above with F = 1/x.", + "It can be verified that E(1) = 1, E(2) ≈ 1.2676536759, and E(7.5) ≈ 2.1215732071.", + "", + "", + "Find E(40) rounded to 10 decimal places behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler394() {", + " // Good luck!", + " return true;", + "}", + "", + "euler394();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f71000cf542c51000a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 395: Pythagorean tree", + "tests": [ + { + "text": "euler395() should return 28.2453753155.", + "testString": "assert.strictEqual(euler395(), 28.2453753155, 'euler395() should return 28.2453753155.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The Pythagorean tree is a fractal generated by the following procedure:", + "", + "", + "", + "Start with a unit square. Then, calling one of the sides its base (in the animation, the bottom side is the base):", + " Attach a right triangle to the side opposite the base, with the hypotenuse coinciding with that side and with the sides in a 3-4-5 ratio. Note that the smaller side of the triangle must be on the 'right' side with respect to the base (see animation).", + " Attach a square to each leg of the right triangle, with one of its sides coinciding with that leg.", + " Repeat this procedure for both squares, considering as their bases the sides touching the triangle.", + "", + "The resulting figure, after an infinite number of iterations, is the Pythagorean tree.", + "", + "", + "", + "", + "", + "It can be shown that there exists at least one rectangle, whose sides are parallel to the largest square of the Pythagorean tree, which encloses the Pythagorean tree completely.", + "", + "", + "Find the smallest area possible for such a bounding rectangle, and give your answer rounded to 10 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler395() {", + " // Good luck!", + " return true;", + "}", + "", + "euler395();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f81000cf542c51000b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 396: Weak Goodstein sequence", + "tests": [ + { + "text": "euler396() should return 173214653.", + "testString": "assert.strictEqual(euler396(), 173214653, 'euler396() should return 173214653.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For any positive integer n, the nth weak Goodstein sequence {g1, g2, g3, ...} is defined as:", + " g1 = n", + " for k > 1, gk is obtained by writing gk-1 in base k, interpreting it as a base k + 1 number, and subtracting 1.", + "", + "The sequence terminates when gk becomes 0.", + "", + "", + "For example, the 6th weak Goodstein sequence is {6, 11, 17, 25, ...}:", + " g1 = 6.", + " g2 = 11 since 6 = 1102, 1103 = 12, and 12 - 1 = 11.", + " g3 = 17 since 11 = 1023, 1024 = 18, and 18 - 1 = 17.", + " g4 = 25 since 17 = 1014, 1015 = 26, and 26 - 1 = 25.", + "", + "and so on.", + "", + "", + "It can be shown that every weak Goodstein sequence terminates.", + "", + "", + "Let G(n) be the number of nonzero elements in the nth weak Goodstein sequence.", + "It can be verified that G(2) = 3, G(4) = 21 and G(6) = 381.", + "It can also be verified that ΣG(n) = 2517 for 1 ≤ n < 8.", + "", + "", + "Find the last 9 digits of ΣG(n) for 1 ≤ n < 16." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler396() {", + " // Good luck!", + " return true;", + "}", + "", + "euler396();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4f91000cf542c51000c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 397: Triangle on parabola", + "tests": [ + { + "text": "euler397() should return 141630459461893730.", + "testString": "assert.strictEqual(euler397(), 141630459461893730, 'euler397() should return 141630459461893730.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "On the parabola y = x2/k, three points A(a, a2/k), B(b, b2/k) and C(c, c2/k) are chosen.", + "", + "", + "Let F(K, X) be the number of the integer quadruplets (k, a, b, c) such that at least one angle of the triangle ABC is 45-degree, with 1 ≤ k ≤ K and -X ≤ a < b < c ≤ X.", + "", + "", + "For example, F(1, 10) = 41 and F(10, 100) = 12492.", + "Find F(106, 109)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler397() {", + " // Good luck!", + " return true;", + "}", + "", + "euler397();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4fa1000cf542c51000d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 398: Cutting rope", + "tests": [ + { + "text": "euler398() should return 2010.59096.", + "testString": "assert.strictEqual(euler398(), 2010.59096, 'euler398() should return 2010.59096.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Inside a rope of length n, n-1 points are placed with distance 1 from each other and from the endpoints. Among these points, we choose m-1 points at random and cut the rope at these points to create m segments.", + "", + "", + "Let E(n, m) be the expected length of the second-shortest segment.", + "For example, E(3, 2) = 2 and E(8, 3) = 16/7.", + "Note that if multiple segments have the same shortest length the length of the second-shortest segment is defined as the same as the shortest length.", + "", + "", + "Find E(107, 100).", + "Give your answer rounded to 5 decimal places behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler398() {", + " // Good luck!", + " return true;", + "}", + "", + "euler398();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4fc1000cf542c51000e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 399: Squarefree Fibonacci Numbers", + "tests": [ + { + "text": "euler399() should return 1508395636674243, 6.5e27330467.", + "testString": "assert.strictEqual(euler399(), 1508395636674243, 6.5e27330467, 'euler399() should return 1508395636674243, 6.5e27330467.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The first 15 fibonacci numbers are:", + "1,1,2,3,5,8,13,21,34,55,89,144,233,377,610.", + "It can be seen that 8 and 144 are not squarefree: 8 is divisible by 4 and 144 is divisible by 4 and by 9. ", + "So the first 13 squarefree fibonacci numbers are:", + "1,1,2,3,5,13,21,34,55,89,233,377 and 610.", + "", + "", + "The 200th squarefree fibonacci number is:", + "971183874599339129547649988289594072811608739584170445.", + "The last sixteen digits of this number are: 1608739584170445 and in scientific notation this number can be written as 9.7e53.", + "", + "", + "Find the 100 000 000th squarefree fibonacci number.", + "Give as your answer its last sixteen digits followed by a comma followed by the number in scientific notation (rounded to one digit after the decimal point).", + "For the 200th squarefree number the answer would have been: 1608739584170445,9.7e53", + "", + "", + "", + "Note: ", + "For this problem, assume that for every prime p, the first fibonacci number divisible by p is not divisible by p2 (this is part of Wall's conjecture). This has been verified for primes ≤ 3·1015, but has not been proven in general.", + "", + "If it happens that the conjecture is false, then the accepted answer to this problem isn't guaranteed to be the 100 000 000th squarefree fibonacci number, rather it represents only a lower bound for that number." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler399() {", + " // Good luck!", + " return true;", + "}", + "", + "euler399();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4fe1000cf542c510010", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 400: Fibonacci tree game", + "tests": [ + { + "text": "euler400() should return 438505383468410600.", + "testString": "assert.strictEqual(euler400(), 438505383468410600, 'euler400() should return 438505383468410600.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A Fibonacci tree is a binary tree recursively defined as:T(0) is the empty tree.", + "T(1) is the binary tree with only one node.", + "T(k) consists of a root node that has T(k-1) and T(k-2) as children.", + "", + "On such a tree two players play a take-away game. On each turn a player selects a node and removes that node along with the subtree rooted at that node.", + "The player who is forced to take the root node of the entire tree loses.", + "", + "", + "Here are the winning moves of the first player on the first turn for T(k) from k=1 to k=6.", + "", + "", + "", + "", + "Let f(k) be the number of winning moves of the first player (i.e. the moves for which the second player has no winning strategy) on the first turn of the game when this game is played on T(k).", + "", + "", + "", + "For example, f(5) = 1 and f(10) = 17.", + "", + "", + "", + "Find f(10000). Give the last 18 digits of your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler400() {", + " // Good luck!", + " return true;", + "}", + "", + "euler400();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4fd1000cf542c51000f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 401: Sum of squares of divisors", + "tests": [ + { + "text": "euler401() should return 281632621.", + "testString": "assert.strictEqual(euler401(), 281632621, 'euler401() should return 281632621.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The divisors of 6 are 1,2,3 and 6.", + "The sum of the squares of these numbers is 1+4+9+36=50.", + "", + "", + "Let sigma2(n) represent the sum of the squares of the divisors of n.", + "Thus sigma2(6)=50.", + "", + "Let SIGMA2 represent the summatory function of sigma2, that is SIGMA2(n)=∑sigma2(i) for i=1 to n.", + "The first 6 values of SIGMA2 are: 1,6,16,37,63 and 113.", + "", + "", + "Find SIGMA2(1015) modulo 109." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler401() {", + " // Good luck!", + " return true;", + "}", + "", + "euler401();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f4ff1000cf542c510011", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 402: Integer-valued polynomials", + "tests": [ + { + "text": "euler402() should return 356019862.", + "testString": "assert.strictEqual(euler402(), 356019862, 'euler402() should return 356019862.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It can be shown that the polynomial n4 + 4n3 + 2n2 + 5n is a multiple of 6 for every integer n. It can also be shown that 6 is the largest integer satisfying this property.", + "", + "", + "Define M(a, b, c) as the maximum m such that n4 + an3 + bn2 + cn is a multiple of m for all integers n. For example, M(4, 2, 5) = 6.", + "", + "", + "Also, define S(N) as the sum of M(a, b, c) for all 0 < a, b, c ≤ N.", + "", + "", + "We can verify that S(10) = 1972 and S(10000) = 2024258331114.", + "", + "", + "Let Fk be the Fibonacci sequence:", + "F0 = 0, F1 = 1 and", + "Fk = Fk-1 + Fk-2 for k ≥ 2.", + "", + "", + "Find the last 9 digits of Σ S(Fk) for 2 ≤ k ≤ 1234567890123." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler402() {", + " // Good luck!", + " return true;", + "}", + "", + "euler402();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5001000cf542c510013", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 403: Lattice points enclosed by parabola and line", + "tests": [ + { + "text": "euler403() should return 18224771.", + "testString": "assert.strictEqual(euler403(), 18224771, 'euler403() should return 18224771.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For integers a and b, we define D(a, b) as the domain enclosed by the parabola y = x2 and the line y = a·x + b:D(a, b) = { (x, y) | x2 ≤ y ≤ a·x + b }.", + "", + "", + "L(a, b) is defined as the number of lattice points contained in D(a, b).", + "For example, L(1, 2) = 8 and L(2, -1) = 1.", + "", + "", + "We also define S(N) as the sum of L(a, b) for all the pairs (a, b) such that the area of D(a, b) is a rational number and |a|,|b| ≤ N.", + "We can verify that S(5) = 344 and S(100) = 26709528.", + "", + "", + "Find S(1012). Give your answer mod 108." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler403() {", + " // Good luck!", + " return true;", + "}", + "", + "euler403();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5001000cf542c510012", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 404: Crisscross Ellipses", + "tests": [ + { + "text": "euler404() should return 1199215615081353.", + "testString": "assert.strictEqual(euler404(), 1199215615081353, 'euler404() should return 1199215615081353.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Ea is an ellipse with an equation of the form x2 + 4y2 = 4a2.", + "Ea' is the rotated image of Ea by θ degrees counterclockwise around the origin O(0, 0) for 0° < θ < 90°.", + "", + "", + "", + "", + "", + "", + "b is the distance to the origin of the two intersection points closest to the origin and c is the distance of the two other intersection points.", + "We call an ordered triplet (a, b, c) a canonical ellipsoidal triplet if a, b and c are positive integers.", + "For example, (209, 247, 286) is a canonical ellipsoidal triplet.", + "", + "", + "", + "Let C(N) be the number of distinct canonical ellipsoidal triplets (a, b, c) for a ≤ N.", + "It can be verified that C(103) = 7, C(104) = 106 and C(106) = 11845.", + "", + "", + "", + "Find C(1017)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler404() {", + " // Good luck!", + " return true;", + "}", + "", + "euler404();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5021000cf542c510014", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 405: A rectangular tiling", + "tests": [ + { + "text": "euler405() should return 237696125.", + "testString": "assert.strictEqual(euler405(), 237696125, 'euler405() should return 237696125.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We wish to tile a rectangle whose length is twice its width.", + "Let T(0) be the tiling consisting of a single rectangle.", + "For n > 0, let T(n) be obtained from T(n-1) by replacing all tiles in the following manner:", + "", + "", + "", + "", + "", + "", + "The following animation demonstrates the tilings T(n) for n from 0 to 5:", + "", + "", + "", + "", + "", + "", + "Let f(n) be the number of points where four tiles meet in T(n).", + "For example, f(1) = 0, f(4) = 82 and f(109) mod 177 = 126897180.", + "", + "", + "", + "Find f(10k) for k = 1018, give your answer modulo 177." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler405() {", + " // Good luck!", + " return true;", + "}", + "", + "euler405();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5021000cf542c510015", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 406: Guessing Game", + "tests": [ + { + "text": "euler406() should return 36813.12757207.", + "testString": "assert.strictEqual(euler406(), 36813.12757207, 'euler406() should return 36813.12757207.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We are trying to find a hidden number selected from the set of integers {1, 2, ..., n} by asking questions. ", + "Each number (question) we ask, we get one of three possible answers: \"Your guess is lower than the hidden number\" (and you incur a cost of a), or", + " \"Your guess is higher than the hidden number\" (and you incur a cost of b), or", + " \"Yes, that's it!\" (and the game ends).", + "Given the value of n, a, and b, an optimal strategy minimizes the total cost for the worst possible case.", + "", + "For example, if n = 5, a = 2, and b = 3, then we may begin by asking \"2\" as our first question.", + "", + "If we are told that 2 is higher than the hidden number (for a cost of b=3), then we are sure that \"1\" is the hidden number (for a total cost of 3).", + "If we are told that 2 is lower than the hidden number (for a cost of a=2), then our next question will be \"4\".", + "If we are told that 4 is higher than the hidden number (for a cost of b=3), then we are sure that \"3\" is the hidden number (for a total cost of 2+3=5).", + "If we are told that 4 is lower than the hidden number (for a cost of a=2), then we are sure that \"5\" is the hidden number (for a total cost of 2+2=4).", + "Thus, the worst-case cost achieved by this strategy is 5. It can also be shown that this is the lowest worst-case cost that can be achieved. ", + "So, in fact, we have just described an optimal strategy for the given values of n, a, and b.", + "", + "Let C(n, a, b) be the worst-case cost achieved by an optimal strategy for the given values of n, a, and b.", + "", + "Here are a few examples:", + "C(5, 2, 3) = 5", + "C(500, √2, √3) = 13.22073197...", + "C(20000, 5, 7) = 82", + "C(2000000, √5, √7) = 49.63755955...", + "", + "Let Fk be the Fibonacci numbers: Fk = Fk-1 + Fk-2 with base cases F1 = F2 = 1.Find ∑1≤k≤30 C(1012, √k, √Fk), and give your answer rounded to 8 decimal places behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler406() {", + " // Good luck!", + " return true;", + "}", + "", + "euler406();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5041000cf542c510016", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 407: Idempotents", + "tests": [ + { + "text": "euler407() should return 39782849136421.", + "testString": "assert.strictEqual(euler407(), 39782849136421, 'euler407() should return 39782849136421.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "If we calculate a2 mod 6 for 0 ≤ a ≤ 5 we get: 0,1,4,3,4,1.", + "", + "", + "The largest value of a such that a2 ≡ a mod 6 is 4.", + "Let's call M(n) the largest value of a < n such that a2 ≡ a (mod n).", + "So M(6) = 4.", + "", + "", + "Find ∑M(n) for 1 ≤ n ≤ 107." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler407() {", + " // Good luck!", + " return true;", + "}", + "", + "euler407();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5091000cf542c51001b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 408: Admissible paths through a grid", + "tests": [ + { + "text": "euler408() should return 299742733.", + "testString": "assert.strictEqual(euler408(), 299742733, 'euler408() should return 299742733.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let's call a lattice point (x, y) inadmissible if x, y and x + y are all positive perfect squares.", + "For example, (9, 16) is inadmissible, while (0, 4), (3, 1) and (9, 4) are not.", + "", + "Consider a path from point (x1, y1) to point (x2, y2) using only unit steps north or east.", + "Let's call such a path admissible if none of its intermediate points are inadmissible.", + "", + "Let P(n) be the number of admissible paths from (0, 0) to (n, n).", + "It can be verified that P(5) = 252, P(16) = 596994440 and P(1000) mod 1 000 000 007 = 341920854.", + "", + "Find P(10 000 000) mod 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler408() {", + " // Good luck!", + " return true;", + "}", + "", + "euler408();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5061000cf542c510017", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 409: Nim Extreme", + "tests": [ + { + "text": "euler409() should return 253223948.", + "testString": "assert.strictEqual(euler409(), 253223948, 'euler409() should return 253223948.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let n be a positive integer. Consider nim positions where:There are n non-empty piles.", + "Each pile has size less than 2n.", + "No two piles have the same size.", + "Let W(n) be the number of winning nim positions satisfying the above", + "conditions (a position is winning if the first player has a winning strategy). For example, W(1) = 1, W(2) = 6, W(3) = 168, W(5) = 19764360 and W(100) mod 1 000 000 007 = 384777056.", + "", + "Find W(10 000 000) mod 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler409() {", + " // Good luck!", + " return true;", + "}", + "", + "euler409();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5071000cf542c510018", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 410: Circle and tangent line", + "tests": [ + { + "text": "euler410() should return 799999783589946600.", + "testString": "assert.strictEqual(euler410(), 799999783589946600, 'euler410() should return 799999783589946600.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let C be the circle with radius r, x2 + y2 = r2. We choose two points P(a, b) and Q(-a, c) so that the line passing through P and Q is tangent to C.", + "", + "For example, the quadruplet (r, a, b, c) = (2, 6, 2, -7) satisfies this property.", + "", + "Let F(R, X) be the number of the integer quadruplets (r, a, b, c) with this property, and with 0 < r ≤ R and 0 < a ≤ X.", + "", + "We can verify that F(1, 5) = 10, F(2, 10) = 52 and F(10, 100) = 3384.", + "Find F(108, 109) + F(109, 108)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler410() {", + " // Good luck!", + " return true;", + "}", + "", + "euler410();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5081000cf542c510019", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 411: Uphill paths", + "tests": [ + { + "text": "euler411() should return 9936352.", + "testString": "assert.strictEqual(euler411(), 9936352, 'euler411() should return 9936352.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let n be a positive integer. Suppose there are stations at the coordinates (x, y) = (2i mod n, 3i mod n) for 0 ≤ i ≤ 2n. We will consider stations with the same coordinates as the same station.", + "", + "We wish to form a path from (0, 0) to (n, n) such that the x and y coordinates never decrease.", + "Let S(n) be the maximum number of stations such a path can pass through.", + "", + "For example, if n = 22, there are 11 distinct stations, and a valid path can pass through at most 5 stations. Therefore, S(22) = 5.", + "The case is illustrated below, with an example of an optimal path:", + "", + "", + "", + "It can also be verified that S(123) = 14 and S(10000) = 48.", + "", + "Find ∑ S(k5) for 1 ≤ k ≤ 30." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler411() {", + " // Good luck!", + " return true;", + "}", + "", + "euler411();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5081000cf542c51001a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 412: Gnomon numbering", + "tests": [ + { + "text": "euler412() should return 38788800.", + "testString": "assert.strictEqual(euler412(), 38788800, 'euler412() should return 38788800.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For integers m, n (0 ≤ n < m), let L(m, n) be an m×m grid with the top-right n×n grid removed.", + "", + "For example, L(5, 3) looks like this:", + "", + "", + "", + "We want to number each cell of L(m, n) with consecutive integers 1, 2, 3, ... such that the number in every cell is smaller than the number below it and to the left of it.", + "", + "For example, here are two valid numberings of L(5, 3):", + "", + "", + "Let LC(m, n) be the number of valid numberings of L(m, n).", + "It can be verified that LC(3, 0) = 42, LC(5, 3) = 250250, LC(6, 3) = 406029023400 and LC(10, 5) mod 76543217 = 61251715.", + "", + "Find LC(10000, 5000) mod 76543217." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler412() {", + " // Good luck!", + " return true;", + "}", + "", + "euler412();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f50a1000cf542c51001c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 413: One-child Numbers", + "tests": [ + { + "text": "euler413() should return 3079418648040719.", + "testString": "assert.strictEqual(euler413(), 3079418648040719, 'euler413() should return 3079418648040719.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We say that a d-digit positive number (no leading zeros) is a one-child number if exactly one of its sub-strings is divisible by d.", + "", + "For example, 5671 is a 4-digit one-child number. Among all its sub-strings 5, 6, 7, 1, 56, 67, 71, 567, 671 and 5671, only 56 is divisible by 4.", + "Similarly, 104 is a 3-digit one-child number because only 0 is divisible by 3.", + "1132451 is a 7-digit one-child number because only 245 is divisible by 7.", + "", + "Let F(N) be the number of the one-child numbers less than N.", + "We can verify that F(10) = 9, F(103) = 389 and F(107) = 277674.", + "", + "Find F(1019)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler413() {", + " // Good luck!", + " return true;", + "}", + "", + "euler413();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f50b1000cf542c51001d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 414: Kaprekar constant", + "tests": [ + { + "text": "euler414() should return 552506775824935500.", + "testString": "assert.strictEqual(euler414(), 552506775824935500, 'euler414() should return 552506775824935500.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "6174 is a remarkable number; if we sort its digits in increasing order and subtract that number from the number you get when you sort the digits in decreasing order, we get 7641-1467=6174.", + "Even more remarkable is that if we start from any 4 digit number and repeat this process of sorting and subtracting, we'll eventually end up with 6174 or immediately with 0 if all digits are equal. ", + "This also works with numbers that have less than 4 digits if we pad the number with leading zeroes until we have 4 digits.", + "E.g. let's start with the number 0837:", + "8730-0378=8352", + "8532-2358=6174", + "", + "", + "6174 is called the Kaprekar constant. The process of sorting and subtracting and repeating this until either 0 or the Kaprekar constant is reached is called the Kaprekar routine.", + "", + "", + "We can consider the Kaprekar routine for other bases and number of digits. ", + "Unfortunately, it is not guaranteed a Kaprekar constant exists in all cases; either the routine can end up in a cycle for some input numbers or the constant the routine arrives at can be different for different input numbers.", + "However, it can be shown that for 5 digits and a base b = 6t+3≠9, a Kaprekar constant exists.", + "E.g. base 15: (10,4,14,9,5)15", + "base 21: (14,6,20,13,7)21", + "", + "Define Cb to be the Kaprekar constant in base b for 5 digits.", + "Define the function sb(i) to be", + " 0 if i = Cb or if i written in base b consists of 5 identical digits", + " the number of iterations it takes the Kaprekar routine in base b to arrive at Cb, otherwise", + "", + "Note that we can define sb(i) for all integers i < b5. If i written in base b takes less than 5 digits, the number is padded with leading zero digits until we have 5 digits before applying the Kaprekar routine.", + "", + "", + "Define S(b) as the sum of sb(i) for 0 < i < b5.", + "E.g. S(15) = 5274369 ", + "S(111) = 400668930299", + "", + "", + "Find the sum of S(6k+3) for 2 ≤ k ≤ 300.", + "Give the last 18 digits as your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler414() {", + " // Good luck!", + " return true;", + "}", + "", + "euler414();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f50c1000cf542c51001e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 415: Titanic sets", + "tests": [ + { + "text": "euler415() should return 55859742.", + "testString": "assert.strictEqual(euler415(), 55859742, 'euler415() should return 55859742.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A set of lattice points S is called a titanic set if there exists a line passing through exactly two points in S.", + "", + "An example of a titanic set is S = {(0, 0), (0, 1), (0, 2), (1, 1), (2, 0), (1, 0)}, where the line passing through (0, 1) and (2, 0) does not pass through any other point in S.", + "", + "On the other hand, the set {(0, 0), (1, 1), (2, 2), (4, 4)} is not a titanic set since the line passing through any two points in the set also passes through the other two.", + "", + "For any positive integer N, let T(N) be the number of titanic sets S whose every point (x, y) satisfies 0 ≤ x, y ≤ N.", + "It can be verified that T(1) = 11, T(2) = 494, T(4) = 33554178, T(111) mod 108 = 13500401 and T(105) mod 108 = 63259062.", + "", + "Find T(1011) mod 108." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler415() {", + " // Good luck!", + " return true;", + "}", + "", + "euler415();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f50e1000cf542c510020", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 416: A frog's trip", + "tests": [ + { + "text": "euler416() should return 898082747.", + "testString": "assert.strictEqual(euler416(), 898082747, 'euler416() should return 898082747.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A row of n squares contains a frog in the leftmost square. By successive jumps the frog goes to the rightmost square and then back to the leftmost square. On the outward trip he jumps one, two or three squares to the right, and on the homeward trip he jumps to the left in a similar manner. He cannot jump outside the squares. He repeats the round-trip travel m times.", + "", + "Let F(m, n) be the number of the ways the frog can travel so that at most one square remains unvisited.", + "For example, F(1, 3) = 4, F(1, 4) = 15, F(1, 5) = 46, F(2, 3) = 16 and F(2, 100) mod 109 = 429619151.", + "", + "Find the last 9 digits of F(10, 1012)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler416() {", + " // Good luck!", + " return true;", + "}", + "", + "euler416();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f50d1000cf542c51001f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 417: Reciprocal cycles II", + "tests": [ + { + "text": "euler417() should return 446572970925740.", + "testString": "assert.strictEqual(euler417(), 446572970925740, 'euler417() should return 446572970925740.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:", + "", + "1/2= 0.5", + "1/3= 0.(3)", + "1/4= 0.25", + "1/5= 0.2", + "1/6= 0.1(6)", + "1/7= 0.(142857)", + "1/8= 0.125", + "1/9= 0.(1)", + "1/10= 0.1", + "", + "Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.", + "", + "Unit fractions whose denominator has no other prime factors than 2 and/or 5 are not considered to have a recurring cycle.", + "We define the length of the recurring cycle of those unit fractions as 0. ", + "", + "", + "Let L(n) denote the length of the recurring cycle of 1/n.", + "You are given that ∑L(n) for 3 ≤ n ≤ 1 000 000 equals 55535191115.", + "", + "", + "Find ∑L(n) for 3 ≤ n ≤ 100 000 000" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler417() {", + " // Good luck!", + " return true;", + "}", + "", + "euler417();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f50f1000cf542c510021", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 418: Factorisation triples", + "tests": [ + { + "text": "euler418() should return 1177163565297340400.", + "testString": "assert.strictEqual(euler418(), 1177163565297340400, 'euler418() should return 1177163565297340400.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let n be a positive integer. An integer triple (a, b, c) is called a factorisation triple of n if: 1 ≤ a ≤ b ≤ c", + " a·b·c = n.", + "", + "Define f(n) to be a + b + c for the factorisation triple (a, b, c) of n which minimises c / a. One can show that this triple is unique.", + "", + "", + "For example, f(165) = 19, f(100100) = 142 and f(20!) = 4034872.", + "", + "", + "Find f(43!)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler418() {", + " // Good luck!", + " return true;", + "}", + "", + "euler418();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5101000cf542c510022", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 419: Look and say sequence", + "tests": [ + { + "text": "euler419() should return 998567458, 1046245404, 43363922.", + "testString": "assert.strictEqual(euler419(), 998567458, 1046245404, 43363922, 'euler419() should return 998567458, 1046245404, 43363922.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The look and say sequence goes 1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, ...", + "The sequence starts with 1 and all other members are obtained by describing the previous member in terms of consecutive digits.", + "It helps to do this out loud:", + "1 is 'one one' → 11", + "11 is 'two ones' → 21", + "21 is 'one two and one one' → 1211 ", + "1211 is 'one one, one two and two ones' → 111221", + "111221 is 'three ones, two twos and one one' → 312211", + "...", + "", + "", + "Define A(n), B(n) and C(n) as the number of ones, twos and threes in the n'th element of the sequence respectively.", + "One can verify that A(40) = 31254, B(40) = 20259 and C(40) = 11625.", + "", + "", + "Find A(n), B(n) and C(n) for n = 1012. ", + "Give your answer modulo 230 and separate your values for A, B and C by a comma. ", + "E.g. for n = 40 the answer would be 31254,20259,11625" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler419() {", + " // Good luck!", + " return true;", + "}", + "", + "euler419();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5111000cf542c510023", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 420: 2x2 positive integer matrix", + "tests": [ + { + "text": "euler420() should return 145159332.", + "testString": "assert.strictEqual(euler420(), 145159332, 'euler420() should return 145159332.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A positive integer matrix is a matrix whose elements are all positive integers.", + "Some positive integer matrices can be expressed as a square of a positive integer matrix in two different ways. Here is an example:", + "", + "", + "", + "", + "", + "We define F(N) as the number of the 2x2 positive integer matrices which have a trace less than N and which can be expressed as a square of a positive integer matrix in two different ways.", + "We can verify that F(50) = 7 and F(1000) = 1019.", + "", + "", + "", + "Find F(107)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler420() {", + " // Good luck!", + " return true;", + "}", + "", + "euler420();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5131000cf542c510024", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 421: Prime factors of n15+1", + "tests": [ + { + "text": "euler421() should return 2304215802083466200.", + "testString": "assert.strictEqual(euler421(), 2304215802083466200, 'euler421() should return 2304215802083466200.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Numbers of the form n15+1 are composite for every integer n > 1.", + "For positive integers n and m let s(n,m) be defined as the sum of the distinct prime factors of n15+1 not exceeding m.", + "", + "E.g. 215+1 = 3×3×11×331.", + "So s(2,10) = 3 and s(2,1000) = 3+11+331 = 345.", + "", + "Also 1015+1 = 7×11×13×211×241×2161×9091.", + "So s(10,100) = 31 and s(10,1000) = 483.", + "Find ∑ s(n,108) for 1 ≤ n ≤ 1011." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler421() {", + " // Good luck!", + " return true;", + "}", + "", + "euler421();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5131000cf542c510025", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 422: Sequence of points on a hyperbola", + "tests": [ + { + "text": "euler422() should return 92060460.", + "testString": "assert.strictEqual(euler422(), 92060460, 'euler422() should return 92060460.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let H be the hyperbola defined by the equation 12x2 + 7xy - 12y2 = 625.", + "", + "Next, define X as the point (7, 1). It can be seen that X is in H.", + "", + "Now we define a sequence of points in H, {Pi : i ≥ 1}, as:", + " P1 = (13, 61/4).", + " P2 = (-43/6, -4).", + " For i > 2, Pi is the unique point in H that is different from Pi-1 and such that line PiPi-1 is parallel to line Pi-2X. It can be shown that Pi is well-defined, and that its coordinates are always rational.", + "You are given that P3 = (-19/2, -229/24), P4 = (1267/144, -37/12) and P7 = (17194218091/143327232, 274748766781/1719926784).", + "", + "Find Pn for n = 1114 in the following format:If Pn = (a/b, c/d) where the fractions are in lowest terms and the denominators are positive, then the answer is (a + b + c + d) mod 1 000 000 007.", + "", + "For n = 7, the answer would have been: 806236837." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler422() {", + " // Good luck!", + " return true;", + "}", + "", + "euler422();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5141000cf542c510027", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 423: Consecutive die throws", + "tests": [ + { + "text": "euler423() should return 653972374.", + "testString": "assert.strictEqual(euler423(), 653972374, 'euler423() should return 653972374.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let n be a positive integer.", + "A 6-sided die is thrown n times. Let c be the number of pairs of consecutive throws that give the same value.", + "", + "For example, if n = 7 and the values of the die throws are (1,1,5,6,6,6,3), then the following pairs of consecutive throws give the same value:", + "(1,1,5,6,6,6,3)", + "(1,1,5,6,6,6,3)", + "(1,1,5,6,6,6,3)", + "Therefore, c = 3 for (1,1,5,6,6,6,3).", + "", + "Define C(n) as the number of outcomes of throwing a 6-sided die n times such that c does not exceed π(n).1", + "For example, C(3) = 216, C(4) = 1290, C(11) = 361912500 and C(24) = 4727547363281250000.", + "", + "Define S(L) as ∑ C(n) for 1 ≤ n ≤ L.", + "For example, S(50) mod 1 000 000 007 = 832833871.", + "", + "Find S(50 000 000) mod 1 000 000 007.", + "", + "1 π denotes the prime-counting function, i.e. π(n) is the number of primes ≤ n." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler423() {", + " // Good luck!", + " return true;", + "}", + "", + "euler423();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5141000cf542c510026", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 424: Kakuro", + "tests": [ + { + "text": "euler424() should return 1059760019628.", + "testString": "assert.strictEqual(euler424(), 1059760019628, 'euler424() should return 1059760019628.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The above is an example of a cryptic kakuro (also known as cross sums, or even sums cross) puzzle, with its final solution on the right. (The common rules of kakuro puzzles can be found easily on numerous internet sites. Other related information can also be currently found at krazydad.com whose author has provided the puzzle data for this challenge.)", + "", + "The downloadable text file (kakuro200.txt) contains the description of 200 such puzzles, a mix of 5x5 and 6x6 types. The first puzzle in the file is the above example which is coded as follows:", + "", + "6,X,X,(vCC),(vI),X,X,X,(hH),B,O,(vCA),(vJE),X,(hFE,vD),O,O,O,O,(hA),O,I,(hJC,vB),O,O,(hJC),H,O,O,O,X,X,X,(hJE),O,O,X", + "", + "The first character is a numerical digit indicating the size of the information grid. It would be either a 6 (for a 5x5 kakuro puzzle) or a 7 (for a 6x6 puzzle) followed by a comma (,). The extra top line and left column are needed to insert information.", + "", + "The content of each cell is then described and followed by a comma, going left to right and starting with the top line.", + "X = Gray cell, not required to be filled by a digit.", + "O (upper case letter)= White empty cell to be filled by a digit.", + "A = Or any one of the upper case letters from A to J to be replaced by its equivalent digit in the solved puzzle.", + "( ) = Location of the encrypted sums. Horizontal sums are preceded by a lower case \"h\" and vertical sums are preceded by a lower case \"v\". Those are followed by one or two upper case letters depending if the sum is a single digit or double digit one. For double digit sums, the first letter would be for the \"tens\" and the second one for the \"units\". When the cell must contain information for both a horizontal and a vertical sum, the first one is always for the horizontal sum and the two are separated by a comma within the same set of brackets, ex.: (hFE,vD). Each set of brackets is also immediately followed by a comma.", + "", + "The description of the last cell is followed by a Carriage Return/Line Feed (CRLF) instead of a comma.", + "", + "The required answer to each puzzle is based on the value of each letter necessary to arrive at the solution and according to the alphabetical order. As indicated under the example puzzle, its answer would be 8426039571. At least 9 out of the 10 encrypting letters are always part of the problem description. When only 9 are given, the missing one must be assigned the remaining digit.", + "", + "You are given that the sum of the answers for the first 10 puzzles in the file is 64414157580.", + "", + "Find the sum of the answers for the 200 puzzles." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler424() {", + " // Good luck!", + " return true;", + "}", + "", + "euler424();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5151000cf542c510028", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 425: Prime connection", + "tests": [ + { + "text": "euler425() should return 46479497324.", + "testString": "assert.strictEqual(euler425(), 46479497324, 'euler425() should return 46479497324.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Two positive numbers A and B are said to be connected (denoted by \"A ↔ B\") if one of these conditions holds:", + "(1) A and B have the same length and differ in exactly one digit; for example, 123 ↔ 173.", + "(2) Adding one digit to the left of A (or B) makes B (or A); for example, 23 ↔ 223 and 123 ↔ 23.", + "", + "", + "We call a prime P a 2's relative if there exists a chain of connected primes between 2 and P and no prime in the chain exceeds P.", + "", + "", + "For example, 127 is a 2's relative. One of the possible chains is shown below:", + "2 ↔ 3 ↔ 13 ↔ 113 ↔ 103 ↔ 107 ↔ 127", + "However, 11 and 103 are not 2's relatives.", + "", + "", + "Let F(N) be the sum of the primes ≤ N which are not 2's relatives.", + "We can verify that F(103) = 431 and F(104) = 78728.", + "", + "", + "Find F(107)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler425() {", + " // Good luck!", + " return true;", + "}", + "", + "euler425();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5171000cf542c510029", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 426: Box-ball system", + "tests": [ + { + "text": "euler426() should return 31591886008.", + "testString": "assert.strictEqual(euler426(), 31591886008, 'euler426() should return 31591886008.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider an infinite row of boxes. Some of the boxes contain a ball. For example, an initial configuration of 2 consecutive occupied boxes followed by 2 empty boxes, 2 occupied boxes, 1 empty box, and 2 occupied boxes can be denoted by the sequence (2, 2, 2, 1, 2), in which the number of consecutive occupied and empty boxes appear alternately.", + "", + "", + "A turn consists of moving each ball exactly once according to the following rule: Transfer the leftmost ball which has not been moved to the nearest empty box to its right.", + "", + "", + "After one turn the sequence (2, 2, 2, 1, 2) becomes (2, 2, 1, 2, 3) as can be seen below; note that we begin the new sequence starting at the first occupied box.", + "", + "", + "", + "", + "", + "", + "A system like this is called a Box-Ball System or BBS for short.", + "", + "", + "It can be shown that after a sufficient number of turns, the system evolves to a state where the consecutive numbers of occupied boxes is invariant. In the example below, the consecutive numbers of occupied boxes evolves to [1, 2, 3]; we shall call this the final state.", + "", + "", + "", + "", + "", + "", + "We define the sequence {ti}:s0 = 290797", + "sk+1 = sk2 mod 50515093", + "tk = (sk mod 64) + 1", + "", + "Starting from the initial configuration (t0, t1, …, t10), the final state becomes [1, 3, 10, 24, 51, 75].", + "Starting from the initial configuration (t0, t1, …, t10 000 000), find the final state.", + "Give as your answer the sum of the squares of the elements of the final state. For example, if the final state is [1, 2, 3] then 14 ( = 12 + 22 + 32) is your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler426() {", + " // Good luck!", + " return true;", + "}", + "", + "euler426();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5181000cf542c51002a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 427: n-sequences", + "tests": [ + { + "text": "euler427() should return 97138867.", + "testString": "assert.strictEqual(euler427(), 97138867, 'euler427() should return 97138867.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A sequence of integers S = {si} is called an n-sequence if it has n elements and each element si satisfies 1 ≤ si ≤ n. Thus there are nn distinct n-sequences in total.", + "For example, the sequence S = {1, 5, 5, 10, 7, 7, 7, 2, 3, 7} is a 10-sequence.", + "", + "For any sequence S, let L(S) be the length of the longest contiguous subsequence of S with the same value.", + "For example, for the given sequence S above, L(S) = 3, because of the three consecutive 7's.", + "", + "Let f(n) = ∑ L(S) for all n-sequences S.", + "", + "For example, f(3) = 45, f(7) = 1403689 and f(11) = 481496895121.", + "", + "Find f(7 500 000) mod 1 000 000 009." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler427() {", + " // Good luck!", + " return true;", + "}", + "", + "euler427();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5191000cf542c51002b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 428: About Project Euler", + "tests": [ + { + "text": "euler428() should return 747215561862.", + "testString": "assert.strictEqual(euler428(), 747215561862, 'euler428() should return 747215561862.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler428() {", + " // Good luck!", + " return true;", + "}", + "", + "euler428();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5191000cf542c51002c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 429: Sum of squares of unitary divisors", + "tests": [ + { + "text": "euler429() should return 98792821.", + "testString": "assert.strictEqual(euler429(), 98792821, 'euler429() should return 98792821.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A unitary divisor d of a number n is a divisor of n that has the property gcd(d, n/d) = 1.", + "The unitary divisors of 4! = 24 are 1, 3, 8 and 24.", + "The sum of their squares is 12 + 32 + 82 + 242 = 650.", + "", + "", + "Let S(n) represent the sum of the squares of the unitary divisors of n. Thus S(4!)=650.", + "", + "", + "Find S(100 000 000!) modulo 1 000 000 009." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler429() {", + " // Good luck!", + " return true;", + "}", + "", + "euler429();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f51a1000cf542c51002d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 430: Range flips", + "tests": [ + { + "text": "euler430() should return 5000624921.38.", + "testString": "assert.strictEqual(euler430(), 5000624921.38, 'euler430() should return 5000624921.38.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "N disks are placed in a row, indexed 1 to N from left to right.", + "Each disk has a black side and white side. Initially all disks show their white side.", + "", + "At each turn, two, not necessarily distinct, integers A and B between 1 and N (inclusive) are chosen uniformly at random.", + "All disks with an index from A to B (inclusive) are flipped.", + "", + "The following example shows the case N = 8. At the first turn A = 5 and B = 2, and at the second turn A = 4 and B = 6.", + "", + "", + "", + "Let E(N, M) be the expected number of disks that show their white side after M turns.", + "We can verify that E(3, 1) = 10/9, E(3, 2) = 5/3, E(10, 4) ≈ 5.157 and E(100, 10) ≈ 51.893.", + "", + "Find E(1010, 4000).", + "Give your answer rounded to 2 decimal places behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler430() {", + " // Good luck!", + " return true;", + "}", + "", + "euler430();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f51b1000cf542c51002e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 431: Square Space Silo", + "tests": [ + { + "text": "euler431() should return 23.386029052.", + "testString": "assert.strictEqual(euler431(), 23.386029052, 'euler431() should return 23.386029052.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Fred the farmer arranges to have a new storage silo installed on his farm and having an obsession for all things square he is absolutely devastated when he discovers that it is circular. Quentin, the representative from the company that installed the silo, explains that they only manufacture cylindrical silos, but he points out that it is resting on a square base. Fred is not amused and insists that it is removed from his property.", + "", + "Quick thinking Quentin explains that when granular materials are delivered from above a conical slope is formed and the natural angle made with the horizontal is called the angle of repose. For example if the angle of repose, $\\alpha = 30$ degrees, and grain is delivered at the centre of the silo then a perfect cone will form towards the top of the cylinder. In the case of this silo, which has a diameter of 6m, the amount of space wasted would be approximately 32.648388556 m3. However, if grain is delivered at a point on the top which has a horizontal distance of $x$ metres from the centre then a cone with a strangely curved and sloping base is formed. He shows Fred a picture.", + "", + "", + " ", + "", + "We shall let the amount of space wasted in cubic metres be given by $V(x)$. If $x = 1.114785284$, which happens to have three squared decimal places, then the amount of space wasted, $V(1.114785284) \\approx 36$. Given the range of possible solutions to this problem there is exactly one other option: $V(2.511167869) \\approx 49$. It would be like knowing that the square is king of the silo, sitting in splendid glory on top of your grain.", + "", + "Fred's eyes light up with delight at this elegant resolution, but on closer inspection of Quentin's drawings and calculations his happiness turns to despondency once more. Fred points out to Quentin that it's the radius of the silo that is 6 metres, not the diameter, and the angle of repose for his grain is 40 degrees. However, if Quentin can find a set of solutions for this particular silo then he will be more than happy to keep it.", + "", + "If Quick thinking Quentin is to satisfy frustratingly fussy Fred the farmer's appetite for all things square then determine the values of $x$ for all possible square space wastage options and calculate $\\sum x$ correct to 9 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler431() {", + " // Good luck!", + " return true;", + "}", + "", + "euler431();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f51e1000cf542c510030", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 432: Totient sum", + "tests": [ + { + "text": "euler432() should return 754862080.", + "testString": "assert.strictEqual(euler432(), 754862080, 'euler432() should return 754862080.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let S(n,m) = ∑φ(n × i) for 1 ≤ i ≤ m. (φ is Euler's totient function)", + "You are given that S(510510,106 )= 45480596821125120. ", + "", + "", + "Find S(510510,1011).", + "Give the last 9 digits of your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler432() {", + " // Good luck!", + " return true;", + "}", + "", + "euler432();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f51d1000cf542c51002f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 433: Steps in Euclid's algorithm", + "tests": [ + { + "text": "euler433() should return 326624372659664.", + "testString": "assert.strictEqual(euler433(), 326624372659664, 'euler433() should return 326624372659664.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let E(x0, y0) be the number of steps it takes to determine the greatest common divisor of x0 and y0 with Euclid's algorithm. More formally:x1 = y0, y1 = x0 mod y0xn = yn-1, yn = xn-1 mod yn-1", + "E(x0, y0) is the smallest n such that yn = 0.", + "", + "", + "We have E(1,1) = 1, E(10,6) = 3 and E(6,10) = 4.", + "", + "", + "Define S(N) as the sum of E(x,y) for 1 ≤ x,y ≤ N.", + "We have S(1) = 1, S(10) = 221 and S(100) = 39826.", + "", + "", + "Find S(5·106)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler433() {", + " // Good luck!", + " return true;", + "}", + "", + "euler433();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f51f1000cf542c510031", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 434: Rigid graphs", + "tests": [ + { + "text": "euler434() should return 863253606.", + "testString": "assert.strictEqual(euler434(), 863253606, 'euler434() should return 863253606.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Recall that a graph is a collection of vertices and edges connecting the vertices, and that two vertices connected by an edge are called adjacent.", + "Graphs can be embedded in Euclidean space by associating each vertex with a point in the Euclidean space.", + "A flexible graph is an embedding of a graph where it is possible to move one or more vertices continuously so that the distance between at least two nonadjacent vertices is altered while the distances between each pair of adjacent vertices is kept constant.", + "A rigid graph is an embedding of a graph which is not flexible.", + "Informally, a graph is rigid if by replacing the vertices with fully rotating hinges and the edges with rods that are unbending and inelastic, no parts of the graph can be moved independently from the rest of the graph.", + "", + "The grid graphs embedded in the Euclidean plane are not rigid, as the following animation demonstrates:", + "However, one can make them rigid by adding diagonal edges to the cells. For example, for the 2x3 grid graph, there are 19 ways to make the graph rigid:", + "Note that for the purposes of this problem, we do not consider changing the orientation of a diagonal edge or adding both diagonal edges to a cell as a different way of making a grid graph rigid.", + "", + "Let R(m,n) be the number of ways to make the m × n grid graph rigid. ", + "E.g. R(2,3) = 19 and R(5,5) = 23679901", + "", + "Define S(N) as ∑R(i,j) for 1 ≤ i, j ≤ N.", + "E.g. S(5) = 25021721.", + "Find S(100), give your answer modulo 1000000033" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler434() {", + " // Good luck!", + " return true;", + "}", + "", + "euler434();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5201000cf542c510032", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 435: Polynomials of Fibonacci numbers", + "tests": [ + { + "text": "euler435() should return 252541322550.", + "testString": "assert.strictEqual(euler435(), 252541322550, 'euler435() should return 252541322550.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The Fibonacci numbers {fn, n ≥ 0} are defined recursively as fn = fn-1 + fn-2 with base cases f0 = 0 and f1 = 1.", + "Define the polynomials {Fn, n ≥ 0} as Fn(x) = ∑fixi for 0 ≤ i ≤ n.", + "For example, F7(x) = x + x2 + 2x3 + 3x4 + 5x5 + 8x6 + 13x7, and F7(11) = 268357683.", + "Let n = 1015. Find the sum [∑0≤x≤100 Fn(x)] mod 1307674368000 (= 15!)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler435() {", + " // Good luck!", + " return true;", + "}", + "", + "euler435();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5221000cf542c510033", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 436: Unfair wager", + "tests": [ + { + "text": "euler436() should return 0.5276662759.", + "testString": "assert.strictEqual(euler436(), 0.5276662759, 'euler436() should return 0.5276662759.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Julie proposes the following wager to her sister Louise.", + "She suggests they play a game of chance to determine who will wash the dishes.", + "For this game, they shall use a generator of independent random numbers uniformly distributed between 0 and 1.", + "The game starts with S = 0.", + "The first player, Louise, adds to S different random numbers from the generator until S > 1 and records her last random number 'x'.", + "The second player, Julie, continues adding to S different random numbers from the generator until S > 2 and records her last random number 'y'.", + "The player with the highest number wins and the loser washes the dishes, i.e. if y > x the second player wins.", + "", + "For example, if the first player draws 0.62 and 0.44, the first player turn ends since 0.62+0.44 > 1 and x = 0.44.", + "If the second players draws 0.1, 0.27 and 0.91, the second player turn ends since 0.62+0.44+0.1+0.27+0.91 > 2 and y = 0.91.", + "Since y > x, the second player wins.", + "", + "Louise thinks about it for a second, and objects: \"That's not fair\".", + "What is the probability that the second player wins?", + "Give your answer rounded to 10 places behind the decimal point in the form 0.abcdefghij" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler436() {", + " // Good luck!", + " return true;", + "}", + "", + "euler436();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5241000cf542c510036", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 437: Fibonacci primitive roots", + "tests": [ + { + "text": "euler437() should return 74204709657207.", + "testString": "assert.strictEqual(euler437(), 74204709657207, 'euler437() should return 74204709657207.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "When we calculate 8n modulo 11 for n=0 to 9 we get: 1, 8, 9, 6, 4, 10, 3, 2, 5, 7.", + "As we see all possible values from 1 to 10 occur. So 8 is a primitive root of 11.", + "But there is more:", + "If we take a closer look we see:", + "1+8=9", + "8+9=17≡6 mod 11", + "9+6=15≡4 mod 11", + "6+4=10", + "4+10=14≡3 mod 11", + "10+3=13≡2 mod 11", + "3+2=5", + "2+5=7", + "5+7=12≡1 mod 11.", + "", + "So the powers of 8 mod 11 are cyclic with period 10, and 8n + 8n+1 ≡ 8n+2 (mod 11).", + "8 is called a Fibonacci primitive root of 11.", + "Not every prime has a Fibonacci primitive root.", + "There are 323 primes less than 10000 with one or more Fibonacci primitive roots and the sum of these primes is 1480491.", + "Find the sum of the primes less than 100,000,000 with at least one Fibonacci primitive root." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler437() {", + " // Good luck!", + " return true;", + "}", + "", + "euler437();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5231000cf542c510034", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 438: Integer part of polynomial equation's solutions", + "tests": [ + { + "text": "euler438() should return 2046409616809.", + "testString": "assert.strictEqual(euler438(), 2046409616809, 'euler438() should return 2046409616809.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For an n-tuple of integers t = (a1, ..., an), let (x1, ..., xn) be the solutions of the polynomial equation xn + a1xn-1 + a2xn-2 + ... + an-1x + an = 0.", + "", + "", + "Consider the following two conditions:", + "x1, ..., xn are all real.", + "If x1, ..., xn are sorted, ⌊xi⌋ = i for 1 ≤ i ≤ n. (⌊·⌋: floor function.)", + "", + "In the case of n = 4, there are 12 n-tuples of integers which satisfy both conditions.", + "We define S(t) as the sum of the absolute values of the integers in t.", + "For n = 4 we can verify that ∑S(t) = 2087 for all n-tuples t which satisfy both conditions.", + "", + "", + "Find ∑S(t) for n = 7." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler438() {", + " // Good luck!", + " return true;", + "}", + "", + "euler438();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5231000cf542c510035", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 439: Sum of sum of divisors", + "tests": [ + { + "text": "euler439() should return 968697378.", + "testString": "assert.strictEqual(euler439(), 968697378, 'euler439() should return 968697378.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let d(k) be the sum of all divisors of k.", + "We define the function S(N) = ∑1≤i≤N ∑1≤j≤Nd(i·j).", + "For example, S(3) = d(1) + d(2) + d(3) + d(2) + d(4) + d(6) + d(3) + d(6) + d(9) = 59.", + "", + "You are given that S(103) = 563576517282 and S(105) mod 109 = 215766508.", + "Find S(1011) mod 109." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler439() {", + " // Good luck!", + " return true;", + "}", + "", + "euler439();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5241000cf542c510037", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 440: GCD and Tiling", + "tests": [ + { + "text": "euler440() should return 970746056.", + "testString": "assert.strictEqual(euler440(), 970746056, 'euler440() should return 970746056.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We want to tile a board of length n and height 1 completely, with either 1 × 2 blocks or 1 × 1 blocks with a single decimal digit on top:", + "", + "For example, here are some of the ways to tile a board of length n = 8:", + "", + "Let T(n) be the number of ways to tile a board of length n as described above.", + "", + "For example, T(1) = 10 and T(2) = 101.", + "", + "Let S(L) be the triple sum ∑a,b,c gcd(T(ca), T(cb)) for 1 ≤ a, b, c ≤ L.", + "For example:", + "S(2) = 10444", + "S(3) = 1292115238446807016106539989", + "S(4) mod 987 898 789 = 670616280.", + "", + "Find S(2000) mod 987 898 789." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler440() {", + " // Good luck!", + " return true;", + "}", + "", + "euler440();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5261000cf542c510038", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 441: The inverse summation of coprime couples", + "tests": [ + { + "text": "euler441() should return 5000088.8395.", + "testString": "assert.strictEqual(euler441(), 5000088.8395, 'euler441() should return 5000088.8395.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For an integer M, we define R(M) as the sum of 1/(p·q) for all the integer pairs p and q which satisfy all of these conditions:", + "", + " 1 ≤ p < q ≤ M", + " p + q ≥ M", + " p and q are coprime.", + "", + "We also define S(N) as the sum of R(i) for 2 ≤ i ≤ N.", + "We can verify that S(2) = R(2) = 1/2, S(10) ≈ 6.9147 and S(100) ≈ 58.2962.", + "", + "", + "Find S(107). Give your answer rounded to four decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler441() {", + " // Good luck!", + " return true;", + "}", + "", + "euler441();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5271000cf542c510039", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 442: Eleven-free integers", + "tests": [ + { + "text": "euler442() should return 1295552661530920200.", + "testString": "assert.strictEqual(euler442(), 1295552661530920200, 'euler442() should return 1295552661530920200.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An integer is called eleven-free if its decimal expansion does not contain any substring representing a power of 11 except 1.", + "", + "For example, 2404 and 13431 are eleven-free, while 911 and 4121331 are not.", + "", + "Let E(n) be the nth positive eleven-free integer. For example, E(3) = 3, E(200) = 213 and E(500 000) = 531563.", + "", + "Find E(1018)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler442() {", + " // Good luck!", + " return true;", + "}", + "", + "euler442();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5271000cf542c51003a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 443: GCD sequence", + "tests": [ + { + "text": "euler443() should return 2744233049300770.", + "testString": "assert.strictEqual(euler443(), 2744233049300770, 'euler443() should return 2744233049300770.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let g(n) be a sequence defined as follows:", + "g(4) = 13,", + "g(n) = g(n-1) + gcd(n, g(n-1)) for n > 4.", + "", + "The first few values are:", + "", + " n4567891011121314151617181920...", + " g(n)1314161718272829303132333451545560...", + " ", + "", + "You are given that g(1 000) = 2524 and g(1 000 000) = 2624152.", + "", + "Find g(1015)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler443() {", + " // Good luck!", + " return true;", + "}", + "", + "euler443();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f52a1000cf542c51003b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 444: The Roundtable Lottery", + "tests": [ + { + "text": "euler444() should return 1.200856722e+263.", + "testString": "assert.strictEqual(euler444(), 1.200856722e+263, 'euler444() should return 1.200856722e+263.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A group of p people decide to sit down at a round table and play a lottery-ticket trading game. Each person starts off with a randomly-assigned, unscratched lottery ticket. Each ticket, when scratched, reveals a whole-pound prize ranging anywhere from £1 to £p, with no two tickets alike. The goal of the game is for each person to maximize his ticket winnings upon leaving the game.", + "", + "An arbitrary person is chosen to be the first player. Going around the table, each player has only one of two options:", + "", + "1. The player can scratch his ticket and reveal its worth to everyone at the table.", + "2. The player can trade his unscratched ticket for a previous player's scratched ticket, and then leave the game with that ticket. The previous player then scratches his newly-acquired ticket and reveals its worth to everyone at the table.", + "", + "The game ends once all tickets have been scratched. All players still remaining at the table must leave with their currently-held tickets.", + "", + "Assume that each player uses the optimal strategy for maximizing the expected value of his ticket winnings. ", + "", + "Let E(p) represent the expected number of players left at the table when the game ends in a game consisting of p players (e.g. E(111) = 5.2912 when rounded to 5 significant digits).", + "", + "Let S1(N) = E(p)", + "Let Sk(N) = Sk-1(p) for k > 1", + "", + "Find S20(1014) and write the answer in scientific notation rounded to 10 significant digits. Use a lowercase e to separate mantissa and exponent (e.g. S3(100) = 5.983679014e5)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler444() {", + " // Good luck!", + " return true;", + "}", + "", + "euler444();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f52a1000cf542c51003c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 445: Retractions A", + "tests": [ + { + "text": "euler445() should return 659104042.", + "testString": "assert.strictEqual(euler445(), 659104042, 'euler445() should return 659104042.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For every integer n>1, the family of functions fn,a,b is defined ", + "by fn,a,b(x)≡ax+b mod n for a,b,x integer and 0euler446() should return 907803852.", + "testString": "assert.strictEqual(euler446(), 907803852, 'euler446() should return 907803852.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For every integer n>1, the family of functions fn,a,b is defined ", + "by fn,a,b(x)≡ax+b mod n for a,b,x integer and 0euler447() should return 530553372.", + "testString": "assert.strictEqual(euler447(), 530553372, 'euler447() should return 530553372.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For every integer n>1, the family of functions fn,a,b is defined ", + "by fn,a,b(x)≡ax+b mod n for a,b,x integer and 0euler448() should return 106467648.", + "testString": "assert.strictEqual(euler448(), 106467648, 'euler448() should return 106467648.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The function lcm(a,b) denotes the least common multiple of a and b.", + "Let A(n) be the average of the values of lcm(n,i) for 1≤i≤n.", + "E.g: A(2)=(2+2)/2=2 and A(10)=(10+10+30+20+10+30+70+40+90+10)/10=32. ", + "", + "Let S(n)=∑A(k) for 1≤k≤n.", + "S(100)=122726.", + "", + "", + "Find S(99999999019) mod 999999017." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler448() {", + " // Good luck!", + " return true;", + "}", + "", + "euler448();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f52d1000cf542c510040", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 449: Chocolate covered candy", + "tests": [ + { + "text": "euler449() should return 103.37870096.", + "testString": "assert.strictEqual(euler449(), 103.37870096, 'euler449() should return 103.37870096.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Phil the confectioner is making a new batch of chocolate covered candy. Each candy centre is shaped like an ellipsoid of revolution defined by the equation: b2x2 + b2y2 + a2z2 = a2b2.", + "", + "", + "Phil wants to know how much chocolate is needed to cover one candy centre with a uniform coat of chocolate one millimeter thick.", + "If a=1 mm and b=1 mm, the amount of chocolate required is ", + " ", + " 283", + " π mm3", + "", + "If a=2 mm and b=1 mm, the amount of chocolate required is approximately 60.35475635 mm3.", + "", + "", + "Find the amount of chocolate in mm3 required if a=3 mm and b=1 mm. Give your answer as the number rounded to 8 decimal places behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler449() {", + " // Good luck!", + " return true;", + "}", + "", + "euler449();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f52e1000cf542c510041", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 450: Hypocycloid and Lattice points", + "tests": [ + { + "text": "euler450() should return 583333163984220900.", + "testString": "assert.strictEqual(euler450(), 583333163984220900, 'euler450() should return 583333163984220900.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A hypocycloid is the curve drawn by a point on a small circle rolling inside a larger circle. The parametric equations of a hypocycloid centered at the origin, and starting at the right most point is given by:", + "$x(t) = (R - r) \\cos(t) + r \\cos(\\frac {R - r} r t)$", + "$y(t) = (R - r) \\sin(t) - r \\sin(\\frac {R - r} r t)$", + "Where R is the radius of the large circle and r the radius of the small circle.", + "", + "", + "Let $C(R, r)$ be the set of distinct points with integer coordinates on the hypocycloid with radius R and r and for which there is a corresponding value of t such that $\\sin(t)$ and $\\cos(t)$ are rational numbers.", + "", + "Let $S(R, r) = \\sum_{(x,y) \\in C(R, r)} |x| + |y|$ be the sum of the absolute values of the x and y coordinates of the points in $C(R, r)$.", + "", + "", + "Let $T(N) = \\sum_{R = 3}^N \\sum_{r=1}^{\\lfloor \\frac {R - 1} 2 \\rfloor} S(R, r)$ be the sum of $S(R, r)$ for R and r positive integers, $R\\leq N$ and $2r < R$.", + "", + "", + "You are given:C(3, 1) =", + "{(3, 0), (-1, 2), (-1,0), (-1,-2)}", + "C(2500, 1000) =", + "{(2500, 0), (772, 2376), (772, -2376), (516, 1792),", + " (516, -1792), (500, 0), (68, 504), (68, -504),(-1356, 1088), (-1356, -1088), (-1500, 1000), (-1500, -1000)}", + "", + "Note: (-625, 0) is not an element of C(2500, 1000) because $\\sin(t)$ is not a rational number for the corresponding values of t.", + "", + "", + "S(3, 1) = (|3| + |0|) + (|-1| + |2|) + (|-1| + |0|) + (|-1| + |-2|) = 10", + "", + "T(3) = 10; T(10) = 524 ;T(100) = 580442; T(103) = 583108600.", + "", + "", + "Find T(106)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler450() {", + " // Good luck!", + " return true;", + "}", + "", + "euler450();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5311000cf542c510042", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 451: Modular inverses", + "tests": [ + { + "text": "euler451() should return 153651073760956.", + "testString": "assert.strictEqual(euler451(), 153651073760956, 'euler451() should return 153651073760956.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the number 15.", + "There are eight positive numbers less than 15 which are coprime to 15: 1, 2, 4, 7, 8, 11, 13, 14.", + "The modular inverses of these numbers modulo 15 are: 1, 8, 4, 13, 2, 11, 7, 14 ", + "because", + "1*1 mod 15=1", + "2*8=16 mod 15=1", + "4*4=16 mod 15=1", + "7*13=91 mod 15=1", + "11*11=121 mod 15=1", + "14*14=196 mod 15=1", + "", + "Let I(n) be the largest positive number m smaller than n-1 such that the modular inverse of m modulo n equals m itself.", + "So I(15)=11.", + "Also I(100)=51 and I(7)=1.", + "", + "Find ∑I(n) for 3≤n≤2·107" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler451() {", + " // Good luck!", + " return true;", + "}", + "", + "euler451();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5311000cf542c510043", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 452: Long Products", + "tests": [ + { + "text": "euler452() should return 345558983.", + "testString": "assert.strictEqual(euler452(), 345558983, 'euler452() should return 345558983.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Define F(m,n) as the number of n-tuples of positive integers for which the product of the elements doesn't exceed m.", + "F(10, 10) = 571.", + "F(106, 106) mod 1 234 567 891 = 252903833.", + "Find F(109, 109) mod 1 234 567 891." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler452() {", + " // Good luck!", + " return true;", + "}", + "", + "euler452();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5311000cf542c510044", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 453: Lattice Quadrilaterals", + "tests": [ + { + "text": "euler453() should return 104354107.", + "testString": "assert.strictEqual(euler453(), 104354107, 'euler453() should return 104354107.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A simple quadrilateral is a polygon that has four distinct vertices, has no straight angles and does not self-intersect.", + "", + "Let Q(m, n) be the number of simple quadrilaterals whose vertices are lattice points with coordinates (x,y) satisfying 0 ≤ x ≤ m and 0 ≤ y ≤ n.", + "", + "For example, Q(2, 2) = 94 as can be seen below:", + "", + "It can also be verified that Q(3, 7) = 39590, Q(12, 3) = 309000 and Q(123, 45) = 70542215894646.", + "", + "Find Q(12345, 6789) mod 135707531." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler453() {", + " // Good luck!", + " return true;", + "}", + "", + "euler453();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5331000cf542c510045", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 454: Diophantine reciprocals III", + "tests": [ + { + "text": "euler454() should return 5435004633092.", + "testString": "assert.strictEqual(euler454(), 5435004633092, 'euler454() should return 5435004633092.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In the following equation x, y, and n are positive integers.", + "", + "1x", + " + ", + "1y", + " = ", + "1n", + "", + "For a limit L we define F(L) as the number of solutions which satisfy x < y ≤ L.", + "", + "We can verify that F(15) = 4 and F(1000) = 1069.", + "Find F(1012)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler454() {", + " // Good luck!", + " return true;", + "}", + "", + "euler454();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5331000cf542c510046", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 455: Powers With Trailing Digits", + "tests": [ + { + "text": "euler455() should return 450186511399999.", + "testString": "assert.strictEqual(euler455(), 450186511399999, 'euler455() should return 450186511399999.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let f(n) be the largest positive integer x less than 109 such that the last 9 digits of nx form the number x (including leading zeros), or zero if no such integer exists.", + "", + "For example:", + "", + "f(4) = 411728896 (4411728896 = ...490411728896) ", + "f(10) = 0", + "f(157) = 743757 (157743757 = ...567000743757)", + "Σf(n), 2 ≤ n ≤ 103 = 442530011399", + "Find Σf(n), 2 ≤ n ≤ 106." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler455() {", + " // Good luck!", + " return true;", + "}", + "", + "euler455();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5351000cf542c510047", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 456: Triangles containing the origin II", + "tests": [ + { + "text": "euler456() should return 333333208685971500.", + "testString": "assert.strictEqual(euler456(), 333333208685971500, 'euler456() should return 333333208685971500.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Define:xn = (1248n mod 32323) - 16161yn = (8421n mod 30103) - 15051", + "Pn = {(x1, y1), (x2, y2), ..., (xn, yn)}", + "", + "", + "For example, P8 = {(-14913, -6630), (-10161, 5625), (5226, 11896), (8340, -10778), (15852, -5203), (-15165, 11295), (-1427, -14495), (12407, 1060)}.", + "", + "Let C(n) be the number of triangles whose vertices are in Pn which contain the origin in the interior.", + "", + "", + "Examples:", + "C(8) = 20", + "C(600) = 8950634", + "C(40 000) = 2666610948988", + "", + "", + "Find C(2 000 000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler456() {", + " // Good luck!", + " return true;", + "}", + "", + "euler456();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5361000cf542c510048", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 457: A polynomial modulo the square of a prime", + "tests": [ + { + "text": "euler457() should return 2647787126797397000.", + "testString": "assert.strictEqual(euler457(), 2647787126797397000, 'euler457() should return 2647787126797397000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let f(n) = n2 - 3n - 1.", + "Let p be a prime.", + "Let R(p) be the smallest positive integer n such that f(n) mod p2 = 0 if such an integer n exists, otherwise R(p) = 0.", + "", + "", + "Let SR(L) be ∑R(p) for all primes not exceeding L.", + "", + "", + "Find SR(107)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler457() {", + " // Good luck!", + " return true;", + "}", + "", + "euler457();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5361000cf542c510049", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 458: Permutations of Project", + "tests": [ + { + "text": "euler458() should return 423341841.", + "testString": "assert.strictEqual(euler458(), 423341841, 'euler458() should return 423341841.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the alphabet A made out of the letters of the word \"project\": A={c,e,j,o,p,r,t}.", + "Let T(n) be the number of strings of length n consisting of letters from A that do not have a substring that is one of the 5040 permutations of \"project\".", + "", + "T(7)=77-7!=818503.", + "", + "", + "Find T(1012). Give the last 9 digits of your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler458() {", + " // Good luck!", + " return true;", + "}", + "", + "euler458();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5371000cf542c51004a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 459: Flipping game", + "tests": [ + { + "text": "euler459() should return 3996390106631.", + "testString": "assert.strictEqual(euler459(), 3996390106631, 'euler459() should return 3996390106631.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The flipping game is a two player game played on a N by N square board.", + "Each square contains a disk with one side white and one side black.", + "The game starts with all disks showing their white side.", + "", + "A turn consists of flipping all disks in a rectangle with the following properties:", + "the upper right corner of the rectangle contains a white disk", + "the rectangle width is a perfect square (1, 4, 9, 16, ...)", + "the rectangle height is a triangular number (1, 3, 6, 10, ...)", + "", + "", + "Players alternate turns. A player wins by turning the grid all black.", + "", + "Let W(N) be the number of winning moves for the first player on a N by N board with all disks white, assuming perfect play.", + "W(1) = 1, W(2) = 0, W(5) = 8 and W(102) = 31395.", + "", + "For N=5, the first player's eight winning first moves are:", + "", + "", + "", + "", + "Find W(106)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler459() {", + " // Good luck!", + " return true;", + "}", + "", + "euler459();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5381000cf542c51004b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 460: An ant on the move", + "tests": [ + { + "text": "euler460() should return 18.420738199.", + "testString": "assert.strictEqual(euler460(), 18.420738199, 'euler460() should return 18.420738199.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "On the Euclidean plane, an ant travels from point A(0, 1) to point B(d, 1) for an integer d.", + "", + "", + "In each step, the ant at point (x0, y0) chooses one of the lattice points (x1, y1) which satisfy x1 ≥ 0 and y1 ≥ 1 and goes straight to (x1, y1) at a constant velocity v. The value of v depends on y0 and y1 as follows:", + " If y0 = y1, the value of v equals y0.", + " If y0 ≠ y1, the value of v equals (y1 - y0) / (ln(y1) - ln(y0)).", + "", + "The left image is one of the possible paths for d = 4. First the ant goes from A(0, 1) to P1(1, 3) at velocity (3 - 1) / (ln(3) - ln(1)) ≈ 1.8205. Then the required time is sqrt(5) / 1.8205 ≈ 1.2283.", + "From P1(1, 3) to P2(3, 3) the ant travels at velocity 3 so the required time is 2 / 3 ≈ 0.6667. From P2(3, 3) to B(4, 1) the ant travels at velocity (1 - 3) / (ln(1) - ln(3)) ≈ 1.8205 so the required time is sqrt(5) / 1.8205 ≈ 1.2283.", + "Thus the total required time is 1.2283 + 0.6667 + 1.2283 = 3.1233.", + "", + "", + "The right image is another path. The total required time is calculated as 0.98026 + 1 + 0.98026 = 2.96052. It can be shown that this is the quickest path for d = 4.", + "", + "", + "", + "Let F(d) be the total required time if the ant chooses the quickest path. For example, F(4) ≈ 2.960516287.", + "We can verify that F(10) ≈ 4.668187834 and F(100) ≈ 9.217221972.", + "", + "", + "Find F(10000). Give your answer rounded to nine decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler460() {", + " // Good luck!", + " return true;", + "}", + "", + "euler460();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f53a1000cf542c51004c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 461: Almost Pi", + "tests": [ + { + "text": "euler461() should return 159820276.", + "testString": "assert.strictEqual(euler461(), 159820276, 'euler461() should return 159820276.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let fn(k) = ek/n - 1, for all non-negative integers k.", + "Remarkably, f200(6) + f200(75) + f200(89) + f200(226) = 3.141592644529… ≈ π.", + "In fact, it is the best approximation of π of the form fn(a) + fn(b) + fn(c) + fn(d) for n = 200.", + "Let g(n) = a2 + b2 + c2 + d 2 for a, b, c, d that minimize the error: | fn(a) + fn(b) + fn(c) + fn(d) - π|", + "(where |x| denotes the absolute value of x).", + "You are given g(200) = 62 + 752 + 892 + 2262 = 64658.", + "Find g(10000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler461() {", + " // Good luck!", + " return true;", + "}", + "", + "euler461();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f53b1000cf542c51004d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 462: Permutation of 3-smooth numbers", + "tests": [ + { + "text": "euler462() should return Infinity.", + "testString": "assert.strictEqual(euler462(), Infinity, 'euler462() should return Infinity.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A 3-smooth number is an integer which has no prime factor larger than 3. For an integer N, we define S(N) as the set of 3-smooth numbers less than or equal to N . For example, S(20) = { 1, 2, 3, 4, 6, 8, 9, 12, 16, 18 }.", + "", + "", + "We define F(N) as the number of permutations of S(N) in which each element comes after all of its proper divisors.", + "", + "", + "This is one of the possible permutations for N = 20.", + "- 1, 2, 4, 3, 9, 8, 16, 6, 18, 12.", + "This is not a valid permutation because 12 comes before its divisor 6.", + "- 1, 2, 4, 3, 9, 8, 12, 16, 6, 18.", + "", + "", + "We can verify that F(6) = 5, F(8) = 9, F(20) = 450 and F(1000) ≈ 8.8521816557e21.", + "Find F(1018). Give as your answer its scientific notation rounded to ten digits after the decimal point.", + "When giving your answer, use a lowercase e to separate mantissa and exponent. E.g. if the answer is 112,233,445,566,778,899 then the answer format would be 1.1223344557e17." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler462() {", + " // Good luck!", + " return true;", + "}", + "", + "euler462();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f53c1000cf542c51004e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 463: A weird recurrence relation", + "tests": [ + { + "text": "euler463() should return 808981553.", + "testString": "assert.strictEqual(euler463(), 808981553, 'euler463() should return 808981553.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The function $f$ is defined for all positive integers as follows:", + "$f(1)=1$", + "$f(3)=3$", + "$f(2n)=f(n)$", + "$f(4n + 1)=2f(2n + 1) - f(n)$", + "$f(4n + 3)=3f(2n + 1) - 2f(n)$", + "", + "The function $S(n)$ is defined as $\\sum_{i=1}^{n}f(i)$.", + "$S(8)=22$ and $S(100)=3604$.", + "Find $S(3^{37})$. Give the last 9 digits of your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler463() {", + " // Good luck!", + " return true;", + "}", + "", + "euler463();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f53d1000cf542c51004f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 464: Möbius function and intervals", + "tests": [ + { + "text": "euler464() should return 198775297232878.", + "testString": "assert.strictEqual(euler464(), 198775297232878, 'euler464() should return 198775297232878.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The Möbius function, denoted μ(n), is defined as:", + "μ(n) = (-1)ω(n) if n is squarefree (where ω(n) is the number of distinct prime factors of n)", + "μ(n) = 0 if n is not squarefree.", + "", + "Let P(a,b) be the number of integers n in the interval [a,b] such that μ(n) = 1.", + "Let N(a,b) be the number of integers n in the interval [a,b] such that μ(n) = -1.", + "For example, P(2,10) = 2 and N(2,10) = 4.", + "", + "", + "", + "Let C(n) be the number of integer pairs (a,b) such that:", + " 1 ≤ a ≤ b ≤ n,", + " 99·N(a,b) ≤ 100·P(a,b), and", + " 99·P(a,b) ≤ 100·N(a,b).", + "", + "For example, C(10) = 13, C(500) = 16676 and C(10 000) = 20155319.", + "", + "", + "", + "Find C(20 000 000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler464() {", + " // Good luck!", + " return true;", + "}", + "", + "euler464();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f53d1000cf542c510050", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 465: Polar polygons", + "tests": [ + { + "text": "euler465() should return 585965659.", + "testString": "assert.strictEqual(euler465(), 585965659, 'euler465() should return 585965659.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The kernel of a polygon is defined by the set of points from which the entire polygon's boundary is visible. We define a polar polygon as a polygon for which the origin is strictly contained inside its kernel.", + "", + "For this problem, a polygon can have collinear consecutive vertices. However, a polygon still cannot have self-intersection and cannot have zero area.", + "", + "For example, only the first of the following is a polar polygon (the kernels of the second, third, and fourth do not strictly contain the origin, and the fifth does not have a kernel at all):", + "", + "", + "", + "Notice that the first polygon has three consecutive collinear vertices.", + "", + "Let P(n) be the number of polar polygons such that the vertices (x, y) have integer coordinates whose absolute values are not greater than n.", + "", + "Note that polygons should be counted as different if they have different set of edges, even if they enclose the same area. For example, the polygon with vertices [(0,0),(0,3),(1,1),(3,0)] is distinct from the polygon with vertices [(0,0),(0,3),(1,1),(3,0),(1,0)].", + "", + "For example, P(1) = 131, P(2) = 1648531, P(3) = 1099461296175 and P(343) mod 1 000 000 007 = 937293740.", + "", + "Find P(713) mod 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler465() {", + " // Good luck!", + " return true;", + "}", + "", + "euler465();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f53e1000cf542c510051", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 466: Distinct terms in a multiplication table", + "tests": [ + { + "text": "euler466() should return 258381958195474750.", + "testString": "assert.strictEqual(euler466(), 258381958195474750, 'euler466() should return 258381958195474750.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let P(m,n) be the number of distinct terms in an m×n multiplication table.", + "", + "For example, a 3×4 multiplication table looks like this:", + "", + "× 12341 12342 24683 36912", + "", + "", + "", + "There are 8 distinct terms {1,2,3,4,6,8,9,12}, therefore P(3,4) = 8.", + "", + "You are given that:", + "P(64,64) = 1263,", + "P(12,345) = 1998, and", + "P(32,1015) = 13826382602124302.", + "", + "Find P(64,1016)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler466() {", + " // Good luck!", + " return true;", + "}", + "", + "euler466();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5411000cf542c510052", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 467: Superinteger", + "tests": [ + { + "text": "euler467() should return 775181359.", + "testString": "assert.strictEqual(euler467(), 775181359, 'euler467() should return 775181359.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An integer s is called a superinteger of another integer n if the digits of n form a subsequence of the digits of s.", + "For example, 2718281828 is a superinteger of 18828, while 314159 is not a superinteger of 151.", + "", + "", + "Let p(n) be the nth prime number, and let c(n) be the nth composite number. For example, p(1) = 2, p(10) = 29, c(1) = 4 and c(10) = 18.", + "{p(i) : i ≥ 1} = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, ...}", + "{c(i) : i ≥ 1} = {4, 6, 8, 9, 10, 12, 14, 15, 16, 18, ...}", + "", + "Let PD the sequence of the digital roots of {p(i)} (CD is defined similarly for {c(i)}):", + "PD = {2, 3, 5, 7, 2, 4, 8, 1, 5, 2, ...}", + "CD = {4, 6, 8, 9, 1, 3, 5, 6, 7, 9, ...}", + "", + "Let Pn be the integer formed by concatenating the first n elements of PD (Cn is defined similarly for CD).", + "P10 = 2357248152", + "C10 = 4689135679", + "", + "Let f(n) be the smallest positive integer that is a common superinteger of Pn and Cn. For example, f(10) = 2357246891352679, and f(100) mod 1 000 000 007 = 771661825.", + "", + "Find f(10 000) mod 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler467() {", + " // Good luck!", + " return true;", + "}", + "", + "euler467();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5411000cf542c510054", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 468: Smooth divisors of binomial coefficients", + "tests": [ + { + "text": "euler468() should return 852950321.", + "testString": "assert.strictEqual(euler468(), 852950321, 'euler468() should return 852950321.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An integer is called B-smooth if none of its prime factors is greater than B.", + "", + "Let SB(n) be the largest B-smooth divisor of n.", + "Examples:", + "S1(10) = 1", + "S4(2100) = 12", + "S17(2496144) = 5712", + "", + "Define F(n) = ∑1≤B≤n ∑0≤r≤n SB(C(n,r)). Here, C(n,r) denotes the binomial coefficient.", + "Examples:", + "F(11) = 3132", + "F(1 111) mod 1 000 000 993 = 706036312", + "F(111 111) mod 1 000 000 993 = 22156169", + "", + "Find F(11 111 111) mod 1 000 000 993." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler468() {", + " // Good luck!", + " return true;", + "}", + "", + "euler468();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5411000cf542c510053", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 469: Empty chairs", + "tests": [ + { + "text": "euler469() should return 0.56766764161831.", + "testString": "assert.strictEqual(euler469(), 0.56766764161831, 'euler469() should return 0.56766764161831.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "In a room N chairs are placed around a round table.", + "Knights enter the room one by one and choose at random an available empty chair.", + "To have enough elbow room the knights always leave at least one empty chair between each other.", + "", + "", + "When there aren't any suitable chairs left, the fraction C of empty chairs is determined.", + "We also define E(N) as the expected value of C.", + "We can verify that E(4) = 1/2 and E(6) = 5/9.", + "", + "", + "Find E(1018). Give your answer rounded to fourteen decimal places in the form 0.abcdefghijklmn." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler469() {", + " // Good luck!", + " return true;", + "}", + "", + "euler469();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5431000cf542c510055", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 470: Super Ramvok", + "tests": [ + { + "text": "euler470() should return 147668794.", + "testString": "assert.strictEqual(euler470(), 147668794, 'euler470() should return 147668794.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider a single game of Ramvok:", + "", + "Let t represent the maximum number of turns the game lasts. If t = 0, then the game ends immediately. Otherwise, on each turn i, the player rolls a die. After rolling, if i < t the player can either stop the game and receive a prize equal to the value of the current roll, or discard the roll and try again next turn. If i = t, then the roll cannot be discarded and the prize must be accepted. Before the game begins, t is chosen by the player, who must then pay an up-front cost ct for some constant c. For c = 0, t can be chosen to be infinite (with an up-front cost of 0). Let R(d, c) be the expected profit (i.e. net gain) that the player receives from a single game of optimally-played Ramvok, given a fair d-sided die and cost constant c. For example, R(4, 0.2) = 2.65. Assume that the player has sufficient funds for paying any/all up-front costs.", + "", + "Now consider a game of Super Ramvok:", + "", + "In Super Ramvok, the game of Ramvok is played repeatedly, but with a slight modification. After each game, the die is altered. The alteration process is as follows: The die is rolled once, and if the resulting face has its pips visible, then that face is altered to be blank instead. If the face is already blank, then it is changed back to its original value. After the alteration is made, another game of Ramvok can begin (and during such a game, at each turn, the die is rolled until a face with a value on it appears). The player knows which faces are blank and which are not at all times. The game of Super Ramvok ends once all faces of the die are blank.", + "", + "Let S(d, c) be the expected profit that the player receives from an optimally-played game of Super Ramvok, given a fair d-sided die to start (with all sides visible), and cost constant c. For example, S(6, 1) = 208.3.", + "", + "Let F(n) = ∑4≤d≤n ∑0≤c≤n S(d, c).", + "", + "Calculate F(20), rounded to the nearest integer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler470() {", + " // Good luck!", + " return true;", + "}", + "", + "euler470();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5431000cf542c510056", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 471: Triangle inscribed in ellipse", + "tests": [ + { + "text": "euler471() should return 1.895093981e+31.", + "testString": "assert.strictEqual(euler471(), 1.895093981e+31, 'euler471() should return 1.895093981e+31.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The triangle ΔABC is inscribed in an ellipse with equation $\\frac {x^2} {a^2} + \\frac {y^2} {b^2} = 1$, 0 < 2b < a, a and b integers.", + "Let r(a,b) be the radius of the incircle of ΔABC when the incircle has center (2b, 0) and A has coordinates $\\left( \\frac a 2, \\frac {\\sqrt 3} 2 b\\right)$.", + "For example, r(3,1) = ½, r(6,2) = 1, r(12,3) = 2.", + "", + "", + "Let $G(n) = \\sum_{a=3}^n \\sum_{b=1}^{\\lfloor \\frac {a - 1} 2 \\rfloor} r(a, b)$", + "You are given G(10) = 20.59722222, G(100) = 19223.60980 (rounded to 10 significant digits).", + "Find G(1011).", + "Give your answer in scientific notation rounded to 10 significant digits. Use a lowercase e to separate mantissa and exponent.", + "For G(10) the answer would have been 2.059722222e1." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler471() {", + " // Good luck!", + " return true;", + "}", + "", + "euler471();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5451000cf542c510057", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 472: Comfortable Distance II", + "tests": [ + { + "text": "euler472() should return 73811586.", + "testString": "assert.strictEqual(euler472(), 73811586, 'euler472() should return 73811586.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "There are N seats in a row. N people come one after another to fill the seats according to the following rules:", + "No person sits beside another.", + "The first person chooses any seat.", + "Each subsequent person chooses the seat furthest from anyone else already seated, as long as it does not violate rule 1. If there is more than one choice satisfying this condition, then the person chooses the leftmost choice.", + "Note that due to rule 1, some seats will surely be left unoccupied, and the maximum number of people that can be seated is less than N (for N > 1).", + "", + "Here are the possible seating arrangements for N = 15:", + "", + "", + "", + "We see that if the first person chooses correctly, the 15 seats can seat up to 7 people.", + "We can also see that the first person has 9 choices to maximize the number of people that may be seated.", + "", + "Let f(N) be the number of choices the first person has to maximize the number of occupants for N seats in a row. Thus, f(1) = 1, f(15) = 9, f(20) = 6, and f(500) = 16.", + "", + "Also, ∑f(N) = 83 for 1 ≤ N ≤ 20 and ∑f(N) = 13343 for 1 ≤ N ≤ 500.", + "", + "Find ∑f(N) for 1 ≤ N ≤ 1012. Give the last 8 digits of your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler472() {", + " // Good luck!", + " return true;", + "}", + "", + "euler472();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5461000cf542c510058", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 473: Phigital number base", + "tests": [ + { + "text": "euler473() should return 35856681704365.", + "testString": "assert.strictEqual(euler473(), 35856681704365, 'euler473() should return 35856681704365.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let $\\varphi$ be the golden ratio: $\\varphi=\\frac{1+\\sqrt{5}}{2}.$", + "Remarkably it is possible to write every positive integer as a sum of powers of $\\varphi$ even if we require that every power of $\\varphi$ is used at most once in this sum.", + "Even then this representation is not unique.", + "We can make it unique by requiring that no powers with consecutive exponents are used and that the representation is finite.", + "E.g: ", + "$2=\\varphi+\\varphi^{-2}$ and $3=\\varphi^{2}+\\varphi^{-2}$", + "", + "", + "To represent this sum of powers of $\\varphi$ we use a string of 0's and 1's with a point to indicate where the negative exponents start.", + "We call this the representation in the phigital numberbase.", + "So $1=1_{\\varphi}$, $2=10.01_{\\varphi}$, $3=100.01_{\\varphi}$ and $14=100100.001001_{\\varphi}$. ", + "The strings representing 1, 2 and 14 in the phigital number base are palindromic, while the string representing 3 is not. (the phigital point is not the middle character).", + "", + "", + "The sum of the positive integers not exceeding 1000 whose phigital representation is palindromic is 4345.", + "", + "", + "Find the sum of the positive integers not exceeding $10^{10}$ whose phigital representation is palindromic." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler473() {", + " // Good luck!", + " return true;", + "}", + "", + "euler473();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5471000cf542c510059", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 474: Last digits of divisors", + "tests": [ + { + "text": "euler474() should return 9690646731515010.", + "testString": "assert.strictEqual(euler474(), 9690646731515010, 'euler474() should return 9690646731515010.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a positive integer n and digits d, we define F(n, d) as the number of the divisors of n whose last digits equal d.", + "For example, F(84, 4) = 3. Among the divisors of 84 (1, 2, 3, 4, 6, 7, 12, 14, 21, 28, 42, 84), three of them (4, 14, 84) have the last digit 4.", + "", + "", + "We can also verify that F(12!, 12) = 11 and F(50!, 123) = 17888.", + "", + "", + "Find F(106!, 65432) modulo (1016 + 61)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler474() {", + " // Good luck!", + " return true;", + "}", + "", + "euler474();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5481000cf542c51005a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 475: Music festival", + "tests": [ + { + "text": "euler475() should return 75780067.", + "testString": "assert.strictEqual(euler475(), 75780067, 'euler475() should return 75780067.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "12n musicians participate at a music festival. On the first day, they form 3n quartets and practice all day.", + "It is a disaster. At the end of the day, all musicians decide they will never again agree to play with any member of their quartet.", + "On the second day, they form 4n trios, each musician avoiding his previous quartet partners.", + "", + "Let f(12n) be the number of ways to organize the trios amongst the 12n musicians.", + "You are given f(12) = 576 and f(24) mod 1 000 000 007 = 509089824.", + "", + "Find f(600) mod 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler475() {", + " // Good luck!", + " return true;", + "}", + "", + "euler475();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5481000cf542c51005b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 476: Circle Packing II", + "tests": [ + { + "text": "euler476() should return 110242.87794.", + "testString": "assert.strictEqual(euler476(), 110242.87794, 'euler476() should return 110242.87794.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let R(a, b, c) be the maximum area covered by three non-overlapping circles inside a triangle with edge lengths a, b and c.", + "Let S(n) be the average value of R(a, b, c) over all integer triplets (a, b, c) such that 1 ≤ a ≤ b ≤ c < a + b ≤ n", + "You are given S(2) = R(1, 1, 1) ≈ 0.31998, S(5) ≈ 1.25899.", + "Find S(1803) rounded to 5 decimal places behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler476() {", + " // Good luck!", + " return true;", + "}", + "", + "euler476();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f54a1000cf542c51005c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 477: Number Sequence Game", + "tests": [ + { + "text": "euler477() should return 25044905874565164.", + "testString": "assert.strictEqual(euler477(), 25044905874565164, 'euler477() should return 25044905874565164.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The number sequence game starts with a sequence S of N numbers written on a line.", + "Two players alternate turns. At his turn, a player must select and remove either the first or the last number remaining in the sequence.", + "The player score is the sum of all the numbers he has taken. Each player attempts to maximize his own sum.", + "If N = 4 and S = {1, 2, 10, 3}, then each player maximizes his score as follows:", + "Player 1: removes the first number (1)", + "Player 2: removes the last number from the remaining sequence (3)", + "Player 1: removes the last number from the remaining sequence (10)", + "Player 2: removes the remaining number (2)", + "Player 1 score is 1 + 10 = 11.", + "Let F(N) be the score of player 1 if both players follow the optimal strategy for the sequence S = {s1, s2, ..., sN} defined as:", + "s1 = 0", + "si+1 = (si2 + 45) modulo 1 000 000 007", + "The sequence begins with S = {0, 45, 2070, 4284945, 753524550, 478107844, 894218625, ...}.", + "You are given F(2) = 45, F(4) = 4284990, F(100) = 26365463243, F(104) = 2495838522951.", + "Find F(108)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler477() {", + " // Good luck!", + " return true;", + "}", + "", + "euler477();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f54c1000cf542c51005e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 478: Mixtures", + "tests": [ + { + "text": "euler478() should return 59510340.", + "testString": "assert.strictEqual(euler478(), 59510340, 'euler478() should return 59510340.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let us consider mixtures of three substances: A, B and C. A mixture can be described by a ratio of the amounts of A, B, and C in it, i.e., (a : b : c). For example, a mixture described by the ratio (2 : 3 : 5) contains 20% A, 30% B and 50% C.", + "", + "For the purposes of this problem, we cannot separate the individual components from a mixture. However, we can combine different amounts of different mixtures to form mixtures with new ratios.", + "", + "For example, say we have three mixtures with ratios (3 : 0 : 2), (3 : 6 : 11) and (3 : 3 : 4). By mixing 10 units of the first, 20 units of the second and 30 units of the third, we get a new mixture with ratio (6 : 5 : 9), since:", + "(10·3/5 + 20·3/20 + 30·3/10 : 10·0/5 + 20·6/20 + 30·3/10 : 10·2/5 + 20·11/20 + 30·4/10)", + "= (18 : 15 : 27) = (6 : 5 : 9)", + "", + "However, with the same three mixtures, it is impossible to form the ratio (3 : 2 : 1), since the amount of B is always less than the amount of C.", + "", + "Let n be a positive integer. Suppose that for every triple of integers (a, b, c) with 0 ≤ a, b, c ≤ n and gcd(a, b, c) = 1, we have a mixture with ratio (a : b : c). Let M(n) be the set of all such mixtures.", + "", + "For example, M(2) contains the 19 mixtures with the following ratios:", + "{(0 : 0 : 1), (0 : 1 : 0), (0 : 1 : 1), (0 : 1 : 2), (0 : 2 : 1), ", + "(1 : 0 : 0), (1 : 0 : 1), (1 : 0 : 2), (1 : 1 : 0), (1 : 1 : 1), ", + "(1 : 1 : 2), (1 : 2 : 0), (1 : 2 : 1), (1 : 2 : 2), (2 : 0 : 1), ", + "(2 : 1 : 0), (2 : 1 : 1), (2 : 1 : 2), (2 : 2 : 1)}.", + "", + "Let E(n) be the number of subsets of M(n) which can produce the mixture with ratio (1 : 1 : 1), i.e., the mixture with equal parts A, B and C. ", + "We can verify that E(1) = 103, E(2) = 520447, E(10) mod 118 = 82608406 and E(500) mod 118 = 13801403.", + "Find E(10 000 000) mod 118." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler478() {", + " // Good luck!", + " return true;", + "}", + "", + "euler478();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f54b1000cf542c51005d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 479: Roots on the Rise", + "tests": [ + { + "text": "euler479() should return 191541795.", + "testString": "assert.strictEqual(euler479(), 191541795, 'euler479() should return 191541795.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let ak, bk, and ck represent the three solutions (real or complex numbers) to the expression 1/x = (k/x)2(k+x2) - kx.", + "", + "For instance, for k = 5, we see that {a5, b5, c5} is approximately {5.727244, -0.363622+2.057397i, -0.363622-2.057397i}.", + "", + "Let S(n) = Σ (ak+bk)p(bk+ck)p(ck+ak)p for all integers p, k such that 1 ≤ p, k ≤ n. ", + "", + "Interestingly, S(n) is always an integer. For example, S(4) = 51160.", + "", + "Find S(106) modulo 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler479() {", + " // Good luck!", + " return true;", + "}", + "", + "euler479();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f54c1000cf542c51005f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 480: The Last Question", + "tests": [ + { + "text": "euler480() should return turnthestarson.", + "testString": "assert.strictEqual(euler480(), turnthestarson, 'euler480() should return turnthestarson.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider all the words which can be formed by selecting letters, in any order, from the phrase:", + "thereisasyetinsufficientdataforameaningfulanswer", + "Suppose those with 15 letters or less are listed in alphabetical order and numbered sequentially starting at 1.", + "The list would include:", + "1 : a", + "2 : aa", + "3 : aaa", + "4 : aaaa", + "5 : aaaaa", + "6 : aaaaaa", + "7 : aaaaaac", + "8 : aaaaaacd", + "9 : aaaaaacde", + "10 : aaaaaacdee", + "11 : aaaaaacdeee", + "12 : aaaaaacdeeee", + "13 : aaaaaacdeeeee", + "14 : aaaaaacdeeeeee", + "15 : aaaaaacdeeeeeef", + "16 : aaaaaacdeeeeeeg", + "17 : aaaaaacdeeeeeeh", + "...", + "28 : aaaaaacdeeeeeey", + "29 : aaaaaacdeeeeef", + "30 : aaaaaacdeeeeefe", + "...", + "115246685191495242: euleoywuttttsss", + "115246685191495243: euler", + "115246685191495244: eulera", + "...", + "525069350231428029: ywuuttttssssrrrDefine P(w) as the position of the word w.", + "Define W(p) as the word in position p.", + "We can see that P(w) and W(p) are inverses: P(W(p)) = p and W(P(w)) = w.", + "Examples:", + "W(10) = aaaaaacdee", + "P(aaaaaacdee) = 10", + "W(115246685191495243) = euler", + "P(euler) = 115246685191495243Find W(P(legionary) + P(calorimeters) - P(annihilate) + P(orchestrated) - P(fluttering)).", + "Give your answer using lowercase characters (no punctuation or space)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler480() {", + " // Good luck!", + " return true;", + "}", + "", + "euler480();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f54d1000cf542c510060", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 481: Chef Showdown", + "tests": [ + { + "text": "euler481() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler481(), TODO: MISSING ANSWER, 'euler481() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A group of chefs (numbered #1, #2, etc) participate in a turn-based strategic cooking competition. On each chef's turn, he/she cooks up a dish to the best of his/her ability and gives it to a separate panel of judges for taste-testing. Let S(k) represent chef #k's skill level (which is publicly known). More specifically, S(k) is the probability that chef #k's dish will be assessed favorably by the judges (on any/all turns). If the dish receives a favorable rating, then the chef must choose one other chef to be eliminated from the competition. The last chef remaining in the competition is the winner.", + "", + "The game always begins with chef #1, with the turn order iterating sequentially over the rest of the chefs still in play. Then the cycle repeats from the lowest-numbered chef. All chefs aim to optimize their chances of winning within the rules as stated, assuming that the other chefs behave in the same manner. In the event that a chef has more than one equally-optimal elimination choice, assume that the chosen chef is always the one with the next-closest turn.", + "", + "Define Wn(k) as the probability that chef #k wins in a competition with n chefs. If we have S(1) = 0.25, S(2) = 0.5, and S(3) = 1, then W3(1) = 0.29375.", + "", + "Going forward, we assign S(k) = Fk/Fn+1 over all 1 ≤ k ≤ n, where Fk is a Fibonacci number: Fk = Fk-1 + Fk-2 with base cases F1 = F2 = 1. Then, for example, when considering a competition with n = 7 chefs, we have W7(1) = 0.08965042, W7(2) = 0.20775702, W7(3) = 0.15291406, W7(4) = 0.14554098, W7(5) = 0.15905291, W7(6) = 0.10261412, and W7(7) = 0.14247050, rounded to 8 decimal places each.", + "", + "Let E(n) represent the expected number of dishes cooked in a competition with n chefs. For instance, E(7) = 42.28176050.", + "", + "Find E(14) rounded to 8 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler481() {", + " // Good luck!", + " return true;", + "}", + "", + "euler481();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f54f1000cf542c510061", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 482: The incenter of a triangle", + "tests": [ + { + "text": "euler482() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler482(), TODO: MISSING ANSWER, 'euler482() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "ABC is an integer sided triangle with incenter I and perimeter p.", + "The segments IA, IB and IC have integral length as well. ", + "", + "", + "Let L = p + |IA| + |IB| + |IC|. ", + "", + "", + "Let S(P) = ∑L for all such triangles where p ≤ P. For example, S(103) = 3619.", + "", + "", + "Find S(107)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler482() {", + " // Good luck!", + " return true;", + "}", + "", + "euler482();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f54f1000cf542c510062", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 483: Repeated permutation", + "tests": [ + { + "text": "euler483() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler483(), TODO: MISSING ANSWER, 'euler483() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We define a permutation as an operation that rearranges the order of the elements {1, 2, 3, ..., n}.", + "There are n! such permutations, one of which leaves the elements in their initial order.", + "For n = 3 we have 3! = 6 permutations:", + "- P1 = keep the initial order", + "- P2 = exchange the 1st and 2nd elements", + "- P3 = exchange the 1st and 3rd elements", + "- P4 = exchange the 2nd and 3rd elements", + "- P5 = rotate the elements to the right", + "- P6 = rotate the elements to the left", + "", + "", + "If we select one of these permutations, and we re-apply the same permutation repeatedly, we eventually restore the initial order.For a permutation Pi, let f(Pi) be the number of steps required to restore the initial order by applying the permutation Pi repeatedly.For n = 3, we obtain:- f(P1) = 1 : (1,2,3) → (1,2,3)- f(P2) = 2 : (1,2,3) → (2,1,3) → (1,2,3)- f(P3) = 2 : (1,2,3) → (3,2,1) → (1,2,3)- f(P4) = 2 : (1,2,3) → (1,3,2) → (1,2,3)- f(P5) = 3 : (1,2,3) → (3,1,2) → (2,3,1) → (1,2,3)- f(P6) = 3 : (1,2,3) → (2,3,1) → (3,1,2) → (1,2,3)", + "", + "", + "Let g(n) be the average value of f2(Pi) over all permutations Pi of length n.g(3) = (12 + 22 + 22 + 22 + 32 + 32)/3! = 31/6 ≈ 5.166666667e0g(5) = 2081/120 ≈ 1.734166667e1g(20) = 12422728886023769167301/2432902008176640000 ≈ 5.106136147e3", + "", + "", + "Find g(350) and write the answer in scientific notation rounded to 10 significant digits, using a lowercase e to separate mantissa and exponent, as in the examples above." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler483() {", + " // Good luck!", + " return true;", + "}", + "", + "euler483();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5501000cf542c510063", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 484: Arithmetic Derivative", + "tests": [ + { + "text": "euler484() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler484(), TODO: MISSING ANSWER, 'euler484() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The arithmetic derivative is defined by", + "p' = 1 for any prime p", + "(ab)' = a'b + ab' for all integers a, b (Leibniz rule)", + "For example, 20' = 24", + "", + "Find ∑ gcd(k,k') for 1 < k ≤ 5·1015", + "", + "Note: gcd(x,y) denotes the greatest common divisor of x and y." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler484() {", + " // Good luck!", + " return true;", + "}", + "", + "euler484();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5511000cf542c510064", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 485: Maximum number of divisors", + "tests": [ + { + "text": "euler485() should return 51281274340.", + "testString": "assert.strictEqual(euler485(), 51281274340, 'euler485() should return 51281274340.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let d(n) be the number of divisors of n.", + "Let M(n,k) be the maximum value of d(j) for n ≤ j ≤ n+k-1.", + "Let S(u,k) be the sum of M(n,k) for 1 ≤ n ≤ u-k+1.", + "", + "", + "You are given that S(1000,10)=17176.", + "", + "", + "Find S(100 000 000,100 000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler485() {", + " // Good luck!", + " return true;", + "}", + "", + "euler485();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5531000cf542c510065", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 486: Palindrome-containing strings", + "tests": [ + { + "text": "euler486() should return 11408450515.", + "testString": "assert.strictEqual(euler486(), 11408450515, 'euler486() should return 11408450515.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let F5(n) be the number of strings s such that:", + "s consists only of '0's and '1's,", + "s has length at most n, and", + "s contains a palindromic substring of length at least 5.", + "For example, F5(4) = 0, F5(5) = 8, ", + "F5(6) = 42 and F5(11) = 3844.", + "", + "Let D(L) be the number of integers n such that ", + "5 ≤ n ≤ L and F5(n) is divisible by 87654321.", + "", + "For example, D(107) = 0 and D(5·109) = 51.", + "", + "Find D(1018)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler486() {", + " // Good luck!", + " return true;", + "}", + "", + "euler486();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5531000cf542c510066", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 487: Sums of power sums", + "tests": [ + { + "text": "euler487() should return 106650212746.", + "testString": "assert.strictEqual(euler487(), 106650212746, 'euler487() should return 106650212746.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let fk(n) be the sum of the kth powers of the first n positive integers.", + "", + "For example, f2(10) = 12 + 22 + 32 + 42 + 52 + 62 + 72 + 82 + 92 + 102 = 385.", + "", + "Let Sk(n) be the sum of fk(i) for 1 ≤ i ≤ n. For example, S4(100) = 35375333830.", + "", + "What is ∑ (S10000(1012) mod p) over all primes p between 2 ⋅ 109 and 2 ⋅ 109 + 2000?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler487() {", + " // Good luck!", + " return true;", + "}", + "", + "euler487();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5541000cf542c510067", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 488: Unbalanced Nim", + "tests": [ + { + "text": "euler488() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler488(), TODO: MISSING ANSWER, 'euler488() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Alice and Bob have enjoyed playing Nim every day. However, they finally got bored of playing ordinary three-heap Nim.", + "So, they added an extra rule:", + "", + "- Must not make two heaps of the same size.", + "", + "The triple (a,b,c) indicates the size of three heaps.", + "Under this extra rule, (2,4,5) is one of the losing positions for the next player.", + "", + "To illustrate:", + "- Alice moves to (2,4,3)", + "- Bob moves to (0,4,3)", + "- Alice moves to (0,2,3)", + "- Bob moves to (0,2,1)", + "", + "Unlike ordinary three-heap Nim, (0,1,2) and its permutations are the end states of this game.", + "", + "For an integer N, we define F(N) as the sum of a+b+c for all the losing positions for the next player, with 0 < a < b < c < N.", + "", + "For example, F(8) = 42, because there are 4 losing positions for the next player, (1,3,5), (1,4,6), (2,3,6) and (2,4,5).", + "We can also verify that F(128) = 496062.", + "", + "Find the last 9 digits of F(1018)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler488() {", + " // Good luck!", + " return true;", + "}", + "", + "euler488();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5561000cf542c510068", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 489: Common factors between two sequences", + "tests": [ + { + "text": "euler489() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler489(), TODO: MISSING ANSWER, 'euler489() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let G(a, b) be the smallest non-negative integer n for which gcd(n3 + b, (n + a)3 + b) is maximized.", + "For example, G(1, 1) = 5 because gcd(n3 + 1, (n + 1)3 + 1) reaches its maximum value of 7 for n = 5, and is smaller for 0 ≤ n < 5.", + "Let H(m, n) = Σ G(a, b) for 1 ≤ a ≤ m, 1 ≤ b ≤ n.", + "You are given H(5, 5) = 128878 and H(10, 10) = 32936544.", + "Find H(18, 1900)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler489() {", + " // Good luck!", + " return true;", + "}", + "", + "euler489();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5561000cf542c510069", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 490: Jumping frog", + "tests": [ + { + "text": "euler490() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler490(), TODO: MISSING ANSWER, 'euler490() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "There are n stones in a pond, numbered 1 to n. Consecutive stones are spaced one unit apart.", + "", + "A frog sits on stone 1. He wishes to visit each stone exactly once, stopping on stone n. However, he can only jump from one stone to another if they are at most 3 units apart. In other words, from stone i, he can reach a stone j if 1 ≤ j ≤ n and j is in the set {i-3, i-2, i-1, i+1, i+2, i+3}.", + "", + "Let f(n) be the number of ways he can do this. For example, f(6) = 14, as shown below:", + "1 → 2 → 3 → 4 → 5 → 6 ", + "1 → 2 → 3 → 5 → 4 → 6 ", + "1 → 2 → 4 → 3 → 5 → 6 ", + "1 → 2 → 4 → 5 → 3 → 6 ", + "1 → 2 → 5 → 3 → 4 → 6 ", + "1 → 2 → 5 → 4 → 3 → 6 ", + "1 → 3 → 2 → 4 → 5 → 6 ", + "1 → 3 → 2 → 5 → 4 → 6 ", + "1 → 3 → 4 → 2 → 5 → 6 ", + "1 → 3 → 5 → 2 → 4 → 6 ", + "1 → 4 → 2 → 3 → 5 → 6 ", + "1 → 4 → 2 → 5 → 3 → 6 ", + "1 → 4 → 3 → 2 → 5 → 6 ", + "1 → 4 → 5 → 2 → 3 → 6", + "", + "Other examples are f(10) = 254 and f(40) = 1439682432976.", + "", + "Let S(L) = ∑ f(n)3 for 1 ≤ n ≤ L.", + "Examples:", + "S(10) = 18230635", + "S(20) = 104207881192114219", + "S(1 000) mod 109 = 225031475", + "S(1 000 000) mod 109 = 363486179", + "", + "Find S(1014) mod 109." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler490() {", + " // Good luck!", + " return true;", + "}", + "", + "euler490();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5591000cf542c51006b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 491: Double pandigital number divisible by 11", + "tests": [ + { + "text": "euler491() should return 194505988824000.", + "testString": "assert.strictEqual(euler491(), 194505988824000, 'euler491() should return 194505988824000.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We call a positive integer double pandigital if it uses all the digits 0 to 9 exactly twice (with no leading zero). For example, 40561817703823564929 is one such number.", + "", + "How many double pandigital numbers are divisible by 11?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler491() {", + " // Good luck!", + " return true;", + "}", + "", + "euler491();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5581000cf542c51006a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 492: Exploding sequence", + "tests": [ + { + "text": "euler492() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler492(), TODO: MISSING ANSWER, 'euler492() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Define the sequence a1, a2, a3, ... as:", + "a1 = 1", + "an+1 = 6an2 + 10an + 3 for n ≥ 1.", + "", + "Examples:", + "a3 = 2359", + "a6 = 269221280981320216750489044576319", + "a6 mod 1 000 000 007 = 203064689", + "a100 mod 1 000 000 007 = 456482974", + "", + "", + "", + "Define B(x,y,n) as ∑ (an mod p) for every prime p such that x ≤ p ≤ x+y.", + "", + "", + "", + "Examples:", + "B(109, 103, 103) = 23674718882", + "B(109, 103, 1015) = 20731563854", + "", + "", + "Find B(109, 107, 1015)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler492() {", + " // Good luck!", + " return true;", + "}", + "", + "euler492();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f55a1000cf542c51006c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 493: Under The Rainbow", + "tests": [ + { + "text": "euler493() should return 6.818741802.", + "testString": "assert.strictEqual(euler493(), 6.818741802, 'euler493() should return 6.818741802.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "70 colored balls are placed in an urn, 10 for each of the seven rainbow colors.", + "What is the expected number of distinct colors in 20 randomly picked balls?", + "Give your answer with nine digits after the decimal point (a.bcdefghij)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler493() {", + " // Good luck!", + " return true;", + "}", + "", + "euler493();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f55a1000cf542c51006d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 494: Collatz prefix families", + "tests": [ + { + "text": "euler494() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler494(), TODO: MISSING ANSWER, 'euler494() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The Collatz sequence is defined as:", + "$a_{i+1} = \\left\\{ \\large{\\frac {a_i} 2 \\atop 3 a_i+1} {\\text{if }a_i\\text{ is even} \\atop \\text{if }a_i\\text{ is odd}} \\right.$.", + "", + "", + "The Collatz conjecture states that starting from any positive integer, the sequence eventually reaches the cycle 1,4,2,1....", + "We shall define the sequence prefix p(n) for the Collatz sequence starting with a1 = n as the sub-sequence of all numbers not a power of 2 (20=1 is considered a power of 2 for this problem). For example:p(13) = {13, 40, 20, 10, 5} p(8) = {}", + "Any number invalidating the conjecture would have an infinite length sequence prefix.", + "", + "", + "Let Sm be the set of all sequence prefixes of length m. Two sequences {a1, a2, ..., am} and {b1, b2, ..., bm} in Sm are said to belong to the same prefix family if ai < aj if and only if bi < bj for all 1 ≤ i,j ≤ m.", + "", + "", + "For example, in S4, {6, 3, 10, 5} is in the same family as {454, 227, 682, 341}, but not {113, 340, 170, 85}.", + "Let f(m) be the number of distinct prefix families in Sm.", + "You are given f(5) = 5, f(10) = 55, f(20) = 6771.", + "", + "", + "Find f(90)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler494() {", + " // Good luck!", + " return true;", + "}", + "", + "euler494();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f55b1000cf542c51006e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 495: Writing n as the product of k distinct positive integers", + "tests": [ + { + "text": "euler495() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler495(), TODO: MISSING ANSWER, 'euler495() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let W(n,k) be the number of ways in which n can be written as the product of k distinct positive integers.", + "For example, W(144,4) = 7. There are 7 ways in which 144 can be written as a product of 4 distinct positive integers:", + "144 = 1×2×4×18", + "144 = 1×2×8×9", + "144 = 1×2×3×24", + "144 = 1×2×6×12", + "144 = 1×3×4×12", + "144 = 1×3×6×8", + "144 = 2×3×4×6", + "Note that permutations of the integers themselves are not considered distinct.", + "Furthermore, W(100!,10) modulo 1 000 000 007 = 287549200.", + "Find W(10000!,30) modulo 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler495() {", + " // Good luck!", + " return true;", + "}", + "", + "euler495();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f55d1000cf542c51006f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 496: Incenter and circumcenter of triangle", + "tests": [ + { + "text": "euler496() should return 2042473533769142800.", + "testString": "assert.strictEqual(euler496(), 2042473533769142800, 'euler496() should return 2042473533769142800.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given an integer sided triangle ABC:", + "Let I be the incenter of ABC.", + "Let D be the intersection between the line AI and the circumcircle of ABC (A ≠ D).", + "", + "We define F(L) as the sum of BC for the triangles ABC that satisfy AC = DI and BC ≤ L.", + "", + "For example, F(15) = 45 because the triangles ABC with (BC,AC,AB) = (6,4,5), (12,8,10), (12,9,7), (15,9,16) satisfy the conditions.", + "", + "Find F(109)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler496() {", + " // Good luck!", + " return true;", + "}", + "", + "euler496();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f55f1000cf542c510070", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 497: Drunken Tower of Hanoi", + "tests": [ + { + "text": "euler497() should return 684901360.", + "testString": "assert.strictEqual(euler497(), 684901360, 'euler497() should return 684901360.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Bob is very familiar with the famous mathematical puzzle/game, \"Tower of Hanoi,\" which consists of three upright rods and disks of different sizes that can slide onto any of the rods. The game begins with a stack of n disks placed on the leftmost rod in descending order by size. The objective of the game is to move all of the disks from the leftmost rod to the rightmost rod, given the following restrictions:", + "", + "Only one disk can be moved at a time.", + "A valid move consists of taking the top disk from one stack and placing it onto another stack (or an empty rod).", + "No disk can be placed on top of a smaller disk.", + "Moving on to a variant of this game, consider a long room k units (square tiles) wide, labeled from 1 to k in ascending order. Three rods are placed at squares a, b, and c, and a stack of n disks is placed on the rod at square a.", + "", + "Bob begins the game standing at square b. His objective is to play the Tower of Hanoi game by moving all of the disks to the rod at square c. However, Bob can only pick up or set down a disk if he is on the same square as the rod / stack in question.", + "", + "Unfortunately, Bob is also drunk. On a given move, Bob will either stumble one square to the left or one square to the right with equal probability, unless Bob is at either end of the room, in which case he can only move in one direction. Despite Bob's inebriated state, he is still capable of following the rules of the game itself, as well as choosing when to pick up or put down a disk.", + "", + "The following animation depicts a side-view of a sample game for n = 3, k = 7, a = 2, b = 4, and c = 6:", + "", + "", + "", + "Let E(n,k,a,b,c) be the expected number of squares that Bob travels during a single optimally-played game. A game is played optimally if the number of disk-pickups is minimized.", + "", + "Interestingly enough, the result is always an integer. For example, E(2,5,1,3,5) = 60 and E(3,20,4,9,17) = 2358.", + "", + "Find the last nine digits of ∑1≤n≤10000 E(n,10n,3n,6n,9n)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler497() {", + " // Good luck!", + " return true;", + "}", + "", + "euler497();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f55f1000cf542c510071", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 498: Remainder of polynomial division", + "tests": [ + { + "text": "euler498() should return 472294837.", + "testString": "assert.strictEqual(euler498(), 472294837, 'euler498() should return 472294837.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For positive integers n and m, we define two polynomials Fn(x) = xn and Gm(x) = (x-1)m.", + "We also define a polynomial Rn,m(x) as the remainder of the division of Fn(x) by Gm(x).", + "For example, R6,3(x) = 15x2 - 24x + 10.", + "", + "Let C(n, m, d) be the absolute value of the coefficient of the d-th degree term of Rn,m(x).", + "We can verify that C(6, 3, 1) = 24 and C(100, 10, 4) = 227197811615775.", + "", + "Find C(1013, 1012, 104) mod 999999937." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler498() {", + " // Good luck!", + " return true;", + "}", + "", + "euler498();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5611000cf542c510072", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 499: St. Petersburg Lottery", + "tests": [ + { + "text": "euler499() should return 0.8660312.", + "testString": "assert.strictEqual(euler499(), 0.8660312, 'euler499() should return 0.8660312.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A gambler decides to participate in a special lottery. In this lottery the gambler plays a series of one or more games.", + "Each game costs m pounds to play and starts with an initial pot of 1 pound. The gambler flips an unbiased coin. Every time a head appears, the pot is doubled and the gambler continues. When a tail appears, the game ends and the gambler collects the current value of the pot. The gambler is certain to win at least 1 pound, the starting value of the pot, at the cost of m pounds, the initial fee.", + "", + "The gambler cannot continue to play if his fortune falls below m pounds.", + "Let pm(s) denote the probability that the gambler will never run out of money in this lottery given his initial fortune s and the cost per game m.", + "For example p2(2) ≈ 0.2522, p2(5) ≈ 0.6873 and p6(10 000) ≈ 0.9952 (note: pm(s) = 0 for s < m).", + "", + "Find p15(109) and give your answer rounded to 7 decimal places behind the decimal point in the form 0.abcdefg." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler499() {", + " // Good luck!", + " return true;", + "}", + "", + "euler499();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5611000cf542c510073", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 500: Problem 500!!!", + "tests": [ + { + "text": "euler500() should return 35407281.", + "testString": "assert.strictEqual(euler500(), 35407281, 'euler500() should return 35407281.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The number of divisors of 120 is 16.", + "In fact 120 is the smallest number having 16 divisors.", + "", + "", + "Find the smallest number with 2500500 divisors.", + "Give your answer modulo 500500507." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler500() {", + " // Good luck!", + " return true;", + "}", + "", + "euler500();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5621000cf542c510074", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 501: Eight Divisors", + "tests": [ + { + "text": "euler501() should return 197912312715.", + "testString": "assert.strictEqual(euler501(), 197912312715, 'euler501() should return 197912312715.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The eight divisors of 24 are 1, 2, 3, 4, 6, 8, 12 and 24.", + "The ten numbers not exceeding 100 having exactly eight divisors are 24, 30, 40, 42, 54, 56, 66, 70, 78 and 88.", + "Let f(n) be the count of numbers not exceeding n with exactly eight divisors.", + "You are given f(100) = 10, f(1000) = 180 and f(106) = 224427.", + "Find f(1012)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler501() {", + " // Good luck!", + " return true;", + "}", + "", + "euler501();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5621000cf542c510075", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 502: Counting Castles", + "tests": [ + { + "text": "euler502() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler502(), TODO: MISSING ANSWER, 'euler502() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We define a block to be a rectangle with a height of 1 and an integer-valued length. Let a castle be a configuration of stacked blocks.", + "", + "Given a game grid that is w units wide and h units tall, a castle is generated according to the following rules:", + "", + "", + "Blocks can be placed on top of other blocks as long as nothing sticks out past the edges or hangs out over open space.", + "All blocks are aligned/snapped to the grid.", + "Any two neighboring blocks on the same row have at least one unit of space between them.", + "The bottom row is occupied by a block of length w.", + "The maximum achieved height of the entire castle is exactly h.", + "The castle is made from an even number of blocks.", + "The following is a sample castle for w=8 and h=5:", + "", + "", + "", + "Let F(w,h) represent the number of valid castles, given grid parameters w and h.", + "", + "For example, F(4,2) = 10, F(13,10) = 3729050610636, F(10,13) = 37959702514, and F(100,100) mod 1 000 000 007 = 841913936.", + "", + "Find (F(1012,100) + F(10000,10000) + F(100,1012)) mod 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler502() {", + " // Good luck!", + " return true;", + "}", + "", + "euler502();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5631000cf542c510076", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 503: Compromise or persist", + "tests": [ + { + "text": "euler503() should return 3.8694550145.", + "testString": "assert.strictEqual(euler503(), 3.8694550145, 'euler503() should return 3.8694550145.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Alice is playing a game with n cards numbered 1 to n.", + "", + "A game consists of iterations of the following steps.", + "(1) Alice picks one of the cards at random.", + "(2) Alice cannot see the number on it. Instead, Bob, one of her friends, sees the number and tells Alice how many previously-seen numbers are bigger than the number which he is seeing.", + "(3) Alice can end or continue the game. If she decides to end, the number becomes her score. If she decides to continue, the card is removed from the game and she returns to (1). If there is no card left, she is forced to end the game.", + "", + "Let F(n) be the Alice's expected score if she takes the optimized strategy to minimize her score.", + "", + "For example, F(3) = 5/3. At the first iteration, she should continue the game. At the second iteration, she should end the game if Bob says that one previously-seen number is bigger than the number which he is seeing, otherwise she should continue the game.", + "", + "We can also verify that F(4) = 15/8 and F(10) ≈ 2.5579365079.", + "", + "Find F(106). Give your answer rounded to 10 decimal places behind the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler503() {", + " // Good luck!", + " return true;", + "}", + "", + "euler503();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5641000cf542c510077", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 504: Square on the Inside", + "tests": [ + { + "text": "euler504() should return 694687.", + "testString": "assert.strictEqual(euler504(), 694687, 'euler504() should return 694687.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let ABCD be a quadrilateral whose vertices are lattice points lying on the coordinate axes as follows:", + "", + "A(a, 0), B(0, b), C(−c, 0), D(0, −d), where 1 ≤ a, b, c, d ≤ m and a, b, c, d, m are integers.", + "", + "It can be shown that for m = 4 there are exactly 256 valid ways to construct ABCD. Of these 256 quadrilaterals, 42 of them strictly contain a square number of lattice points.", + "", + "How many quadrilaterals ABCD strictly contain a square number of lattice points for m = 100?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler504() {", + " // Good luck!", + " return true;", + "}", + "", + "euler504();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5661000cf542c510078", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 505: Bidirectional Recurrence", + "tests": [ + { + "text": "euler505() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler505(), TODO: MISSING ANSWER, 'euler505() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let:", + "$\\begin{array}{ll} x(0)&=0 \\\\ x(1)&=1 \\\\ x(2k)&=(3x(k)+2x(\\lfloor \\frac k 2 \\rfloor)) \\text{ mod } 2^{60} \\text{ for } k \\ge 1 \\text {, where } \\lfloor \\text { } \\rfloor \\text { is the floor function} \\\\ x(2k+1)&=(2x(k)+3x(\\lfloor \\frac k 2 \\rfloor)) \\text{ mod } 2^{60} \\text{ for } k \\ge 1 \\\\ y_n(k)&=\\left\\{{\\begin{array}{lc} x(k) && \\text{if } k \\ge n \\\\ 2^{60} - 1 - max(y_n(2k),y_n(2k+1)) && \\text{if } k < n \\end{array}} \\right. \\\\ A(n)&=y_n(1) \\end{array}$", + "You are given:", + "$\\begin{array}{ll} x(2)&=3 \\\\ x(3)&=2 \\\\ x(4)&=11 \\\\ y_4(4)&=11 \\\\ y_4(3)&=2^{60}-9\\\\ y_4(2)&=2^{60}-12 \\\\ y_4(1)&=A(4)=8 \\\\ A(10)&=2^{60}-34\\\\ A(10^3)&=101881 \\end{array}$", + "Find $A(10^{12})$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler505() {", + " // Good luck!", + " return true;", + "}", + "", + "euler505();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5671000cf542c510079", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 506: Clock sequence", + "tests": [ + { + "text": "euler506() should return 18934502.", + "testString": "assert.strictEqual(euler506(), 18934502, 'euler506() should return 18934502.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the infinite repeating sequence of digits:", + "1234321234321234321...", + "Amazingly, you can break this sequence of digits into a sequence of integers such that the sum of the digits in the n'th value is n.", + "The sequence goes as follows:", + "1, 2, 3, 4, 32, 123, 43, 2123, 432, 1234, 32123, ...", + "Let vn be the n'th value in this sequence. For example, v2 = 2, v5 = 32 and v11 = 32123.", + "Let S(n) be v1 + v2 + ... + vn. For example, S(11) = 36120, and S(1000) mod 123454321 = 18232686.", + "Find S(1014) mod 123454321." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler506() {", + " // Good luck!", + " return true;", + "}", + "", + "euler506();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5671000cf542c51007a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 507: Shortest Lattice Vector", + "tests": [ + { + "text": "euler507() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler507(), TODO: MISSING ANSWER, 'euler507() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let $t_n$ be the tribonacci numbers defined as:", + "$t_0 = t_1 = 0$;", + "$t_2 = 1$;", + "$t_n = t_{n-1} + t_{n-2} + t_{n-3}$ for $n \\ge 3$", + "and let $r_n = t_n \\text{ mod } 10^7$.", + "", + "", + "For each pair of Vectors $V_n=(v_1,v_2,v_3)$ and $W_n=(w_1,w_2,w_3)$ with $v_1=r_{12n-11}-r_{12n-10}, v_2=r_{12n-9}+r_{12n-8}, v_3=r_{12n-7} \\cdot r_{12n-6}$ and $w_1=r_{12n-5}-r_{12n-4}, w_2=r_{12n-3}+r_{12n-2}, w_3=r_{12n-1} \\cdot r_{12n}$", + "", + "", + "we define $S(n)$ as the minimal value of the manhattan length of the vector $D=k \\cdot V_n+l \\cdot W_n$ measured as $|k \\cdot v_1+l \\cdot w_1|+|k \\cdot v_2+l \\cdot w_2|+|k \\cdot v_3+l \\cdot w_3|$", + " for any integers $k$ and $l$ with $(k,l)\\neq (0,0)$.", + "", + "The first vector pair is (-1, 3, 28), (-11, 125, 40826).", + "You are given that $S(1)=32$ and $\\sum_{n=1}^{10} S(n)=130762273722$.", + "", + "", + "Find $\\sum_{n=1}^{20000000} S(n)$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler507() {", + " // Good luck!", + " return true;", + "}", + "", + "euler507();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5691000cf542c51007c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 508: Integers in base i-1", + "tests": [ + { + "text": "euler508() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler508(), TODO: MISSING ANSWER, 'euler508() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the Gaussian integer i-1. A base i-1 representation of a Gaussian integer a+bi is a finite sequence of digits dn-1dn-2...d1d0 such that:", + "", + "a+bi = dn-1(i-1)n-1 + dn-2(i-1)n-2 + ... + d1(i-1) + d0", + "Each dk is in {0,1}", + "There are no leading zeroes, i.e. dn-1 ≠ 0, unless a+bi is itself 0", + "Here are base i-1 representations of a few Gaussian integers:", + "11+24i → 111010110001101", + "24-11i → 110010110011", + "8+0i → 111000000", + "-5+0i → 11001101", + "0+0i → 0", + "", + "Remarkably, every Gaussian integer has a unique base i-1 representation!", + "", + "Define f(a+bi) as the number of 1s in the unique base i-1 representation of a+bi. For example, f(11+24i) = 9 and f(24-11i) = 7.", + "", + "Define B(L) as the sum of f(a+bi) for all integers a, b such that |a| ≤ L and |b| ≤ L. For example, B(500) = 10795060.", + "", + "Find B(1015) mod 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler508() {", + " // Good luck!", + " return true;", + "}", + "", + "euler508();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5691000cf542c51007b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 509: Divisor Nim", + "tests": [ + { + "text": "euler509() should return 151725678.", + "testString": "assert.strictEqual(euler509(), 151725678, 'euler509() should return 151725678.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Anton and Bertrand love to play three pile Nim.", + "However, after a lot of games of Nim they got bored and changed the rules somewhat.", + "They may only take a number of stones from a pile that is a proper divisor of the number of stones present in the pile. E.g. if a pile at a certain moment contains 24 stones they may take only 1,2,3,4,6,8 or 12 stones from that pile.", + "So if a pile contains one stone they can't take the last stone from it as 1 isn't a proper divisor of 1.", + "The first player that can't make a valid move loses the game.", + "Of course both Anton and Bertrand play optimally.", + "", + "The triple (a,b,c) indicates the number of stones in the three piles.", + "Let S(n) be the number of winning positions for the next player for 1 ≤ a, b, c ≤ n.S(10) = 692 and S(100) = 735494.", + "", + "Find S(123456787654321) modulo 1234567890." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler509() {", + " // Good luck!", + " return true;", + "}", + "", + "euler509();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f56b1000cf542c51007d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 510: Tangent Circles", + "tests": [ + { + "text": "euler510() should return 315306518862563700.", + "testString": "assert.strictEqual(euler510(), 315306518862563700, 'euler510() should return 315306518862563700.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Circles A and B are tangent to each other and to line L at three distinct points.", + "Circle C is inside the space between A, B and L, and tangent to all three.", + "Let rA, rB and rC be the radii of A, B and C respectively.", + "Let S(n) = Σ rA + rB + rC, for 0 < rA ≤ rB ≤ n where rA, rB and rC are integers.", + "The only solution for 0 < rA ≤ rB ≤ 5 is rA = 4, rB = 4 and rC = 1, so S(5) = 4 + 4 + 1 = 9.", + "You are also given S(100) = 3072.", + "Find S(109)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler510() {", + " // Good luck!", + " return true;", + "}", + "", + "euler510();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f56b1000cf542c51007e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 511: Sequences with nice divisibility properties", + "tests": [ + { + "text": "euler511() should return 935247012.", + "testString": "assert.strictEqual(euler511(), 935247012, 'euler511() should return 935247012.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let Seq(n,k) be the number of positive-integer sequences {ai}1≤i≤n of length n such that:", + "n is divisible by ai for 1 ≤ i ≤ n, and", + " n + a1 + a2 + ... + an is divisible by k.", + "Examples:", + "Seq(3,4) = 4, and the 4 sequences are:", + "{1, 1, 3}", + "{1, 3, 1}", + "{3, 1, 1}", + "{3, 3, 3}", + "Seq(4,11) = 8, and the 8 sequences are:", + "{1, 1, 1, 4}", + "{1, 1, 4, 1}", + "{1, 4, 1, 1}", + "{4, 1, 1, 1}", + "{2, 2, 2, 1}", + "{2, 2, 1, 2}", + "{2, 1, 2, 2}", + "{1, 2, 2, 2}", + "The last nine digits of Seq(1111,24) are 840643584.", + "Find the last nine digits of Seq(1234567898765,4321)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler511() {", + " // Good luck!", + " return true;", + "}", + "", + "euler511();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f56d1000cf542c51007f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 512: Sums of totients of powers", + "tests": [ + { + "text": "euler512() should return 50660591862310320.", + "testString": "assert.strictEqual(euler512(), 50660591862310320, 'euler512() should return 50660591862310320.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let $\\varphi(n)$ be Euler's totient function.", + "Let $f(n)=(\\sum_{i=1}^{n}\\varphi(n^i)) \\text{ mod } (n+1)$.", + "Let $g(n)=\\sum_{i=1}^{n} f(i)$.", + "$g(100)=2007$.", + "", + "", + "Find $g(5 \\times 10^8)$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler512() {", + " // Good luck!", + " return true;", + "}", + "", + "euler512();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f56e1000cf542c510080", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 513: Integral median", + "tests": [ + { + "text": "euler513() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler513(), TODO: MISSING ANSWER, 'euler513() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "ABC is an integral sided triangle with sides a≤b≤c.", + "mc is the median connecting C and the midpoint of AB. ", + "F(n) is the number of such triangles with c≤n for which mc has integral length as well.", + "F(10)=3 and F(50)=165.", + "", + "Find F(100000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler513() {", + " // Good luck!", + " return true;", + "}", + "", + "euler513();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f56f1000cf542c510081", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 514: Geoboard Shapes", + "tests": [ + { + "text": "euler514() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler514(), TODO: MISSING ANSWER, 'euler514() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A geoboard (of order N) is a square board with equally-spaced pins protruding from the surface, representing an integer point lattice for coordinates 0 ≤ x,y ≤ N.", + "", + "John begins with a pinless geoboard. Each position on the board is a hole that can be filled with a pin. John decides to generate a random integer between 1 and N+1 (inclusive) for each hole in the geoboard. If the random integer is equal to 1 for a given hole, then a pin is placed in that hole.", + "", + "After John is finished generating numbers for all (N+1)2 holes and placing any/all corresponding pins, he wraps a tight rubberband around the entire group of pins protruding from the board. Let S represent the shape that is formed. S can also be defined as the smallest convex shape that contains all the pins.", + "", + "", + "", + "The above image depicts a sample layout for N = 4. The green markers indicate positions where pins have been placed, and the blue lines collectively represent the rubberband. For this particular arrangement, S has an area of 6. If there are fewer than three pins on the board (or if all pins are collinear), S can be assumed to have zero area.", + "", + "Let E(N) be the expected area of S given a geoboard of order N. For example, E(1) = 0.18750, E(2) = 0.94335, and E(10) = 55.03013 when rounded to five decimal places each.", + "", + "Calculate E(100) rounded to five decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler514() {", + " // Good luck!", + " return true;", + "}", + "", + "euler514();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5711000cf542c510083", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 515: Dissonant Numbers", + "tests": [ + { + "text": "euler515() should return 2422639000800.", + "testString": "assert.strictEqual(euler515(), 2422639000800, 'euler515() should return 2422639000800.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let d(p,n,0) be the multiplicative inverse of n modulo prime p, defined as n × d(p,n,0) = 1 mod p.", + "Let d(p,n,k) = $\\sum_{i=1}^n$d(p,i,k−1) for k ≥ 1.", + "Let D(a,b,k) = $\\sum$(d(p,p-1,k) mod p) for all primes a ≤ p < a + b.", + "You are given:", + "D(101,1,10) = 45", + "D(103,102,102) = 8334", + "D(106,103,103) = 38162302Find D(109,105,105)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler515() {", + " // Good luck!", + " return true;", + "}", + "", + "euler515();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5701000cf542c510082", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 516: 5-smooth totients", + "tests": [ + { + "text": "euler516() should return 939087315.", + "testString": "assert.strictEqual(euler516(), 939087315, 'euler516() should return 939087315.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "5-smooth numbers are numbers whose largest prime factor doesn't exceed 5.", + "5-smooth numbers are also called Hamming numbers.", + "Let S(L) be the sum of the numbers n not exceeding L such that Euler's totient function φ(n) is a Hamming number.", + "S(100)=3728.", + "", + "", + "Find S(1012). Give your answer modulo 232." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler516() {", + " // Good luck!", + " return true;", + "}", + "", + "euler516();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5721000cf542c510084", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 517: A real recursion", + "tests": [ + { + "text": "euler517() should return 581468882.", + "testString": "assert.strictEqual(euler517(), 581468882, 'euler517() should return 581468882.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For every real number $a \\gt 1$ is given the sequence $g_a$ by:", + "$g_{a}(x)=1$ for $x \\lt a$", + "$g_{a}(x)=g_{a}(x-1)+g_a(x-a)$ for $x \\ge a$", + "", + "$G(n)=g_{\\sqrt {n}}(n)$", + "$G(90)=7564511$.", + "", + "Find $\\sum G(p)$ for $p$ prime and $10000000 \\lt p \\lt 10010000$", + "Give your answer modulo 1000000007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler517() {", + " // Good luck!", + " return true;", + "}", + "", + "euler517();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5721000cf542c510085", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 518: Prime triples and geometric sequences", + "tests": [ + { + "text": "euler518() should return 100315739184392.", + "testString": "assert.strictEqual(euler518(), 100315739184392, 'euler518() should return 100315739184392.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let S(n) = Σ a+b+c over all triples (a,b,c) such that:", + "", + "a, b, and c are prime numbers.", + "a < b < c < n.", + "a+1, b+1, and c+1 form a geometric sequence.", + "For example, S(100) = 1035 with the following triples: ", + "", + "(2, 5, 11), (2, 11, 47), (5, 11, 23), (5, 17, 53), (7, 11, 17), (7, 23, 71), (11, 23, 47), (17, 23, 31), (17, 41, 97), (31, 47, 71), (71, 83, 97)", + "", + "Find S(108)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler518() {", + " // Good luck!", + " return true;", + "}", + "", + "euler518();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5741000cf542c510086", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 519: Tricolored Coin Fountains", + "tests": [ + { + "text": "euler519() should return 804739330.", + "testString": "assert.strictEqual(euler519(), 804739330, 'euler519() should return 804739330.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An arrangement of coins in one or more rows with the bottom row being a block without gaps and every coin in a higher row touching exactly two coins in the row below is called a fountain of coins. Let f(n) be the number of possible fountains with n coins. For 4 coins there are three possible arrangements:", + "", + "Therefore f(4) = 3 while f(10) = 78.", + "Let T(n) be the number of all possible colorings with three colors for all f(n) different fountains with n coins, given the condition that no two touching coins have the same color. Below you see the possible colorings for one of the three valid fountains for 4 coins:", + "", + "You are given that T(4) = 48 and T(10) = 17760.", + "Find the last 9 digits of T(20000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler519() {", + " // Good luck!", + " return true;", + "}", + "", + "euler519();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5751000cf542c510087", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 520: Simbers", + "tests": [ + { + "text": "euler520() should return 238413705.", + "testString": "assert.strictEqual(euler520(), 238413705, 'euler520() should return 238413705.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We define a simber to be a positive integer in which any odd digit, if present, occurs an odd number of times, and any even digit, if present, occurs an even number of times.", + "", + "For example, 141221242 is a 9-digit simber because it has three 1's, four 2's and two 4's. ", + "", + "Let Q(n) be the count of all simbers with at most n digits. ", + "", + "You are given Q(7) = 287975 and Q(100) mod 1 000 000 123 = 123864868.", + "", + "Find (∑1≤u≤39 Q(2u)) mod 1 000 000 123." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler520() {", + " // Good luck!", + " return true;", + "}", + "", + "euler520();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5751000cf542c510088", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 521: Smallest prime factor", + "tests": [ + { + "text": "euler521() should return 44389811.", + "testString": "assert.strictEqual(euler521(), 44389811, 'euler521() should return 44389811.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let smpf(n) be the smallest prime factor of n.", + "smpf(91)=7 because 91=7×13 and smpf(45)=3 because 45=3×3×5.", + "Let S(n) be the sum of smpf(i) for 2 ≤ i ≤ n.", + "E.g. S(100)=1257.", + "", + "", + "", + "Find S(1012) mod 109." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler521() {", + " // Good luck!", + " return true;", + "}", + "", + "euler521();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900f5761000cf542c510089", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 522: Hilbert's Blackout", + "tests": [ + { + "text": "euler522() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler522(), TODO: MISSING ANSWER, 'euler522() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Despite the popularity of Hilbert's infinite hotel, Hilbert decided to try managing extremely large finite hotels, instead. ", + "", + "To cut costs, Hilbert wished to power the new hotel with his own special generator. Each floor would send power to the floor above it, with the top floor sending power back down to the bottom floor. That way, Hilbert could have the generator placed on any given floor (as he likes having the option) and have electricity flow freely throughout the entire hotel.", + "", + "Unfortunately, the contractors misinterpreted the schematics when they built the hotel. They informed Hilbert that each floor sends power to another floor at random, instead. This may compromise Hilbert's freedom to have the generator placed anywhere, since blackouts could occur on certain floors.", + "", + "For example, consider a sample flow diagram for a three-story hotel:", + "", + "", + "", + "If the generator were placed on the first floor, then every floor would receive power. But if it were placed on the second or third floors instead, then there would be a blackout on the first floor. Note that while a given floor can receive power from many other floors at once, it can only send power to one other floor.", + "", + "To resolve the blackout concerns, Hilbert decided to have a minimal number of floors rewired. To rewire a floor is to change the floor it sends power to. In the sample diagram above, all possible blackouts can be avoided by rewiring the second floor to send power to the first floor instead of the third floor.", + "", + "Let F(n) be the sum of the minimum number of floor rewirings needed over all possible power-flow arrangements in a hotel of n floors. For example, F(3) = 6, F(8) = 16276736, and F(100) mod 135707531 = 84326147.", + "", + "Find F(12344321) mod 135707531." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler522() {", + " // Good luck!", + " return true;", + "}", + "", + "euler522();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fe885726495c153991c8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 523: First Sort I", + "tests": [ + { + "text": "euler523() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler523(), TODO: MISSING ANSWER, 'euler523() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the following algorithm for sorting a list:", + "1. Starting from the beginning of the list, check each pair of adjacent elements in turn.", + "2. If the elements are out of order:", + "a. Move the smallest element of the pair at the beginning of the list.", + "b. Restart the process from step 1.", + "3. If all pairs are in order, stop.For example, the list { 4 1 3 2 } is sorted as follows:", + "4 1 3 2 (4 and 1 are out of order so move 1 to the front of the list)", + "1 4 3 2 (4 and 3 are out of order so move 3 to the front of the list)", + "3 1 4 2 (3 and 1 are out of order so move 1 to the front of the list)", + "1 3 4 2 (4 and 2 are out of order so move 2 to the front of the list)", + "2 1 3 4 (2 and 1 are out of order so move 1 to the front of the list)", + "1 2 3 4 (The list is now sorted)Let F(L) be the number of times step 2a is executed to sort list L. For example, F({ 4 1 3 2 }) = 5.", + "", + "Let E(n) be the expected value of F(P) over all permutations P of the integers {1, 2, ..., n}.", + "You are given E(4) = 3.25 and E(10) = 115.725.", + "", + "Find E(30). Give your answer rounded to two digits after the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler523() {", + " // Good luck!", + " return true;", + "}", + "", + "euler523();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fece58d9425c70af4f5e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 524: First Sort II", + "tests": [ + { + "text": "euler524() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler524(), TODO: MISSING ANSWER, 'euler524() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the following algorithm for sorting a list:", + "1. Starting from the beginning of the list, check each pair of adjacent elements in turn.", + "2. If the elements are out of order:", + "a. Move the smallest element of the pair at the beginning of the list.", + "b. Restart the process from step 1.", + "3. If all pairs are in order, stop.For example, the list { 4 1 3 2 } is sorted as follows:", + "4 1 3 2 (4 and 1 are out of order so move 1 to the front of the list)", + "1 4 3 2 (4 and 3 are out of order so move 3 to the front of the list)", + "3 1 4 2 (3 and 1 are out of order so move 1 to the front of the list)", + "1 3 4 2 (4 and 2 are out of order so move 2 to the front of the list)", + "2 1 3 4 (2 and 1 are out of order so move 1 to the front of the list)", + "1 2 3 4 (The list is now sorted)Let F(L) be the number of times step 2a is executed to sort list L. For example, F({ 4 1 3 2 }) = 5.", + "", + "We can list all permutations P of the integers {1, 2, ..., n} in lexicographical order, and assign to each permutation an index In(P) from 1 to n! corresponding to its position in the list.", + "", + "Let Q(n, k) = min(In(P)) for F(P) = k, the index of the first permutation requiring exactly k steps to sort with First Sort. If there is no permutation for which F(P) = k, then Q(n, k) is undefined.", + "", + "For n = 4 we have:", + "", + "PI4(P)F(P){1, 2, 3, 4}10Q(4, 0) = 1{1, 2, 4, 3}24Q(4, 4) = 2{1, 3, 2, 4}32Q(4, 2) = 3{1, 3, 4, 2}42{1, 4, 2, 3}56Q(4, 6) = 5{1, 4, 3, 2}64{2, 1, 3, 4}71Q(4, 1) = 7{2, 1, 4, 3}85Q(4, 5) = 8{2, 3, 1, 4}91{2, 3, 4, 1}101{2, 4, 1, 3}115{2, 4, 3, 1}123Q(4, 3) = 12{3, 1, 2, 4}133{3, 1, 4, 2}143{3, 2, 1, 4}152{3, 2, 4, 1}162{3, 4, 1, 2}173{3, 4, 2, 1}182{4, 1, 2, 3}197Q(4, 7) = 19{4, 1, 3, 2}205{4, 2, 1, 3}216{4, 2, 3, 1}224{4, 3, 1, 2}234{4, 3, 2, 1}243Let R(k) = min(Q(n, k)) over all n for which Q(n, k) is defined.", + "", + "Find R(1212)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler524() {", + " // Good luck!", + " return true;", + "}", + "", + "euler524();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fecf58d9425c70af4f5f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 525: Rolling Ellipse", + "tests": [ + { + "text": "euler525() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler525(), TODO: MISSING ANSWER, 'euler525() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An ellipse E(a, b) is given at its initial position by equation:", + "$\\frac {x^2} {a^2} + \\frac {(y - b)^2} {b^2} = 1$", + "", + "The ellipse rolls without slipping along the x axis for one complete turn. Interestingly, the length of the curve generated by a focus is independent from the size of the minor axis:", + "$F(a,b) = 2 \\pi \\text{ } max(a,b)$", + "", + "", + "", + "This is not true for the curve generated by the ellipse center. Let C(a,b) be the length of the curve generated by the center of the ellipse as it rolls without slipping for one turn.", + "", + "", + "", + "You are given C(2, 4) ~ 21.38816906.", + "", + "Find C(1, 4) + C(3, 4). Give your answer rounded to 8 digits behind the decimal point in the form ab.cdefghij." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler525() {", + " // Good luck!", + " return true;", + "}", + "", + "euler525();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fed058d9425c70af4f60", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 526: Largest prime factors of consecutive numbers", + "tests": [ + { + "text": "euler526() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler526(), TODO: MISSING ANSWER, 'euler526() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let f(n) be the largest prime factor of n.", + "Let g(n) = f(n) + f(n+1) + f(n+2) + f(n+3) + f(n+4) + f(n+5) + f(n+6) + f(n+7) + f(n+8), the sum of the largest prime factor of each of nine consecutive numbers starting with n.", + "Let h(n) be the maximum value of g(k) for 2 ≤ k ≤ n.", + "You are given:", + "f(100) = 5", + "f(101) = 101", + "g(100) = 409", + "h(100) = 417", + "h(109) = 4896292593Find h(1016)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler526() {", + " // Good luck!", + " return true;", + "}", + "", + "euler526();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fed158d9425c70af4f61", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 527: Randomized Binary Search", + "tests": [ + { + "text": "euler527() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler527(), TODO: MISSING ANSWER, 'euler527() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A secret integer t is selected at random within the range 1 ≤ t ≤ n. ", + "", + "The goal is to guess the value of t by making repeated guesses, via integer g. After a guess is made, there are three possible outcomes, in which it will be revealed that either g < t, g = t, or g > t. Then the process can repeat as necessary.", + "", + "Normally, the number of guesses required on average can be minimized with a binary search: Given a lower bound L and upper bound H (initialized to L = 1 and H = n), let g = ⌊(L+H)/2⌋ where ⌊⋅⌋ is the integer floor function. If g = t, the process ends. Otherwise, if g < t, set L = g+1, but if g > t instead, set H = g−1. After setting the new bounds, the search process repeats, and ultimately ends once t is found. Even if t can be deduced without searching, assume that a search will be required anyway to confirm the value.", + "", + "Your friend Bob believes that the standard binary search is not that much better than his randomized variant: Instead of setting g = ⌊(L+H)/2⌋, simply let g be a random integer between L and H, inclusive. The rest of the algorithm is the same as the standard binary search. This new search routine will be referred to as a random binary search.", + "", + "Given that 1 ≤ t ≤ n for random t, let B(n) be the expected number of guesses needed to find t using the standard binary search, and let R(n) be the expected number of guesses needed to find t using the random binary search. For example, B(6) = 2.33333333 and R(6) = 2.71666667 when rounded to 8 decimal places.", + "", + "Find R(1010) − B(1010) rounded to 8 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler527() {", + " // Good luck!", + " return true;", + "}", + "", + "euler527();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fed258d9425c70af4f62", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 528: Constrained Sums", + "tests": [ + { + "text": "euler528() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler528(), TODO: MISSING ANSWER, 'euler528() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let S(n,k,b) represent the number of valid solutions to x1 + x2 + ... + xk ≤ n, where 0 ≤ xm ≤ bm for all 1 ≤ m ≤ k.", + "", + "For example, S(14,3,2) = 135, S(200,5,3) = 12949440, and S(1000,10,5) mod 1 000 000 007 = 624839075.", + "", + "Find (∑10 ≤ k ≤ 15 S(10k,k,k)) mod 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler528() {", + " // Good luck!", + " return true;", + "}", + "", + "euler528();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fed358d9425c70af4f63", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 529: 10-substrings", + "tests": [ + { + "text": "euler529() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler529(), TODO: MISSING ANSWER, 'euler529() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A 10-substring of a number is a substring of its digits that sum to 10. For example, the 10-substrings of the number 3523014 are:", + "3523014", + "3523014", + "3523014", + "3523014A number is called 10-substring-friendly if every one of its digits belongs to a 10-substring. For example, 3523014 is 10-substring-friendly, but 28546 is not.", + "Let T(n) be the number of 10-substring-friendly numbers from 1 to 10n (inclusive).", + "For example T(2) = 9 and T(5) = 3492.", + "Find T(1018) mod 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler529() {", + " // Good luck!", + " return true;", + "}", + "", + "euler529();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fed458d9425c70af4f64", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 530: GCD of Divisors", + "tests": [ + { + "text": "euler530() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler530(), TODO: MISSING ANSWER, 'euler530() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Every divisor d of a number n has a complementary divisor n/d.", + "", + "Let f(n) be the sum of the greatest common divisor of d and n/d over all positive divisors d of n, that is", + "$f(n)=\\displaystyle\\sum\\limits_{d|n}\\, \\text{gcd}(d,\\frac n d)$.", + "", + "Let F be the summatory function of f, that is", + "$F(k)=\\displaystyle\\sum\\limits_{n=1}^k \\, f(n)$.", + "", + "You are given that F(10)=32 and F(1000)=12776.", + "", + "Find F(1015)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler530() {", + " // Good luck!", + " return true;", + "}", + "", + "euler530();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fed558d9425c70af4f65", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 531: Chinese leftovers", + "tests": [ + { + "text": "euler531() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler531(), TODO: MISSING ANSWER, 'euler531() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let g(a,n,b,m) be the smallest non-negative solution x to the system:x = a mod nx = b mod m", + "if such a solution exists, otherwise 0.", + "", + "", + "E.g. g(2,4,4,6)=10, but g(3,4,4,6)=0.", + "", + "", + "Let φ(n) be Euler's totient function.", + "", + "", + "Let f(n,m)=g(φ(n),n,φ(m),m)", + "", + "", + "Find ∑f(n,m) for 1000000 ≤ n < m < 1005000" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler531() {", + " // Good luck!", + " return true;", + "}", + "", + "euler531();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fed658d9425c70af4f66", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 532: Nanobots on Geodesics", + "tests": [ + { + "text": "euler532() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler532(), TODO: MISSING ANSWER, 'euler532() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Bob is a manufacturer of nanobots and wants to impress his customers by giving them a ball colored by his new nanobots as a present.", + "", + "His nanobots can be programmed to select and locate exactly one other bot precisely and, after activation, move towards this bot along the shortest possible path and draw a colored line onto the surface while moving. Placed on a plane, the bots will start to move towards their selected bots in a straight line. In contrast, being placed on a ball, they will start to move along a geodesic as the shortest possible path. However, in both cases, whenever their target moves they will adjust their direction instantaneously to the new shortest possible path. All bots will move at the same speed after their simultaneous activation until each bot reaches its goal.", + "", + "Now Bob places n bots on the ball (with radius 1) equidistantly on a small circle with radius 0.999 and programs each of them to move toward the next nanobot sitting counterclockwise on that small circle. After activation, the bots move in a sort of spiral until they finally meet at one point on the ball.", + "", + "Using three bots, Bob finds that every bot will draw a line of length 2.84, resulting in a total length of 8.52 for all three bots, each time rounded to two decimal places. The colored ball looks like this:", + "", + "", + "", + "In order to show off a little with his presents, Bob decides to use just enough bots to make sure that the line each bot draws is longer than 1000. What is the total length of all lines drawn with this number of bots, rounded to two decimal places?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler532() {", + " // Good luck!", + " return true;", + "}", + "", + "euler532();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fed758d9425c70af4f67", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 533: Minimum values of the Carmichael function", + "tests": [ + { + "text": "euler533() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler533(), TODO: MISSING ANSWER, 'euler533() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The Carmichael function λ(n) is defined as the smallest positive integer m such that am = 1 modulo n for all integers a coprime with n.", + "For example λ(8) = 2 and λ(240) = 4.", + "", + "Define L(n) as the smallest positive integer m such that λ(k) ≥ n for all k ≥ m.", + "For example, L(6) = 241 and L(100) = 20 174 525 281.", + "", + "Find L(20 000 000). Give the last 9 digits of your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler533() {", + " // Good luck!", + " return true;", + "}", + "", + "euler533();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fed858d9425c70af4f68", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 534: Weak Queens", + "tests": [ + { + "text": "euler534() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler534(), TODO: MISSING ANSWER, 'euler534() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The classical eight queens puzzle is the well known problem of placing eight chess queens on a 8×8 chessboard so that no two queens threaten each other. Allowing configurations to reappear in rotated or mirrored form, a total of 92 distinct configurations can be found for eight queens. The general case asks for the number of distinct ways of placing n queens on a n×n board, e.g. you can find 2 distinct configurations for n=4.", + "", + "Lets define a weak queen on a n×n board to be a piece which can move any number of squares if moved horizontally, but a maximum of n−1−w squares if moved vertically or diagonally, 0≤weuler535() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler535(), TODO: MISSING ANSWER, 'euler535() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the infinite integer sequence S starting with:S = 1, 1, 2, 1, 3, 2, 4, 1, 5, 3, 6, 2, 7, 8, 4, 9, 1, 10, 11, 5, ...", + "", + "Circle the first occurrence of each integer.S = ①, 1, ②, 1, ③, 2, ④, 1, ⑤, 3, ⑥, 2, ⑦, ⑧, 4, ⑨, 1, ⑩, ⑪, 5, ...", + "", + "The sequence is characterized by the following properties:", + "The circled numbers are consecutive integers starting with 1.", + "Immediately preceding each non-circled numbers ai, there are exactly ⌊√ai⌋ adjacent circled numbers, where ⌊⌋ is the floor function.", + "If we remove all circled numbers, the remaining numbers form a sequence identical to S, so S is a fractal sequence.Let T(n) be the sum of the first n elements of the sequence.", + "You are given T(1) = 1, T(20) = 86, T(103) = 364089 and T(109) = 498676527978348241.", + "", + "Find T(1018). Give the last 9 digits of your answer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler535() {", + " // Good luck!", + " return true;", + "}", + "", + "euler535();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900feda58d9425c70af4f6a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 536: Modulo power identity", + "tests": [ + { + "text": "euler536() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler536(), TODO: MISSING ANSWER, 'euler536() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let S(n) be the sum of all positive integers m not exceeding n having the following property:a m+4 ≡ a (mod m) for all integers a.", + "", + "", + "The values of m ≤ 100 that satisfy this property are 1, 2, 3, 5 and 21, thus S(100) = 1+2+3+5+21 = 32.", + "You are given S(106) = 22868117.", + "", + "", + "Find S(1012)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler536() {", + " // Good luck!", + " return true;", + "}", + "", + "euler536();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fedb58d9425c70af4f6b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 537: Counting tuples", + "tests": [ + { + "text": "euler537() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler537(), TODO: MISSING ANSWER, 'euler537() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let π(x) be the prime counting function, i.e. the number of prime numbers less than or equal to x.", + "For example, π(1)=0, π(2)=1, π(100)=25.", + "", + "", + "Let T(n,k) be the number of k-tuples (x1,…,xk) which satisfy:", + "1. every xi is a positive integer;", + "2. $\\displaystyle \\sum_{i=1}^k \\pi(x_i)=n$", + "", + "", + "For example T(3,3)=19.", + "The 19 tuples are (1,1,5), (1,5,1), (5,1,1), (1,1,6), (1,6,1), (6,1,1), (1,2,3), (1,3,2), (2,1,3), (2,3,1), (3,1,2), (3,2,1), (1,2,4), (1,4,2), (2,1,4), (2,4,1), (4,1,2), (4,2,1), (2,2,2).", + "", + "", + "You are given T(10,10) = 869 985 and T(103,103) ≡ 578 270 566 (mod 1 004 535 809).", + "", + "Find T(20 000, 20 000) mod 1 004 535 809." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler537() {", + " // Good luck!", + " return true;", + "}", + "", + "euler537();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fedc58d9425c70af4f6c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 538: Maximum quadrilaterals", + "tests": [ + { + "text": "euler538() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler538(), TODO: MISSING ANSWER, 'euler538() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider a positive integer sequence S = (s1, s2, ..., sn).", + "", + "Let f(S) be the perimeter of the maximum-area quadrilateral whose side lengths are 4 elements (si, sj, sk, sl) of S (all i, j, k, l distinct). If there are many quadrilaterals with the same maximum area, then choose the one with the largest perimeter.", + "", + "For example, if S = (8, 9, 14, 9, 27), then we can take the elements (9, 14, 9, 27) and form an isosceles trapezium with parallel side lengths 14 and 27 and both leg lengths 9. The area of this quadrilateral is 127.611470879... It can be shown that this is the largest area for any quadrilateral that can be formed using side lengths from S. Therefore, f(S) = 9 + 14 + 9 + 27 = 59.", + "", + "Let un = 2B(3n) + 3B(2n) + B(n+1), where B(k) is the number of 1 bits of k in base 2.", + "For example, B(6) = 2, B(10) = 2 and B(15) = 4, and u5 = 24 + 32 + 2 = 27.", + "", + "Also, let Un be the sequence (u1, u2, ..., un).", + "For example, U10 = (8, 9, 14, 9, 27, 16, 36, 9, 27, 28).", + "", + "It can be shown that f(U5) = 59, f(U10) = 118, f(U150) = 3223.", + "It can also be shown that Σ f(Un) = 234761 for 4 ≤ n ≤ 150.", + "Find Σ f(Un) for 4 ≤ n ≤ 3 000 000." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler538() {", + " // Good luck!", + " return true;", + "}", + "", + "euler538();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fedd58d9425c70af4f6d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 539: Odd elimination", + "tests": [ + { + "text": "euler539() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler539(), TODO: MISSING ANSWER, 'euler539() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Start from an ordered list of all integers from 1 to n. Going from left to right, remove the first number and every other number afterward until the end of the list. Repeat the procedure from right to left, removing the right most number and every other number from the numbers left. Continue removing every other numbers, alternating left to right and right to left, until a single number remains.", + "", + "", + "Starting with n = 9, we have:1 2 3 4 5 6 7 8 9", + "2 4 6 82 6", + "6", + "", + "", + "Let P(n) be the last number left starting with a list of length n.", + "Let $\\displaystyle S(n) = \\sum_{k=1}^n P(k)$.", + "You are given P(1)=1, P(9) = 6, P(1000)=510, S(1000)=268271.", + "", + "", + "Find S(1018) mod 987654321." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler539() {", + " // Good luck!", + " return true;", + "}", + "", + "euler539();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fede58d9425c70af4f6e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 540: Counting primitive Pythagorean triples", + "tests": [ + { + "text": "euler540() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler540(), TODO: MISSING ANSWER, 'euler540() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A Pythagorean triple consists of three positive integers $a, b$ and $c$ satisfying $a^2+b^2=c^2$.", + "The triple is called primitive if $a, b$ and $c$ are relatively prime.", + "Let P($n$) be the number of primitive Pythagorean triples with $a < b < c <= n$.", + "For example P(20) = 3, since there are three triples: (3,4,5), (5,12,13) and (8,15,17).", + "", + "", + "You are given that P(106) = 159139.", + "Find P(3141592653589793)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler540() {", + " // Good luck!", + " return true;", + "}", + "", + "euler540();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fedf58d9425c70af4f6f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 541: Divisibility of Harmonic Number Denominators", + "tests": [ + { + "text": "euler541() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler541(), TODO: MISSING ANSWER, 'euler541() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The nthharmonic number Hn is defined as the sum of the multiplicative inverses of the first n positive integers, and can be written as a reduced fraction an/bn.", + "$H_n = \\displaystyle \\sum_{k=1}^n \\frac 1 k = \\frac {a_n} {b_n}$, with $\\text {gcd}(a_n, b_n)=1$.", + "", + "Let M(p) be the largest value of n such that bn is not divisible by p.", + "", + "For example, M(3) = 68 because $H_{68} = \\frac {a_{68}} {b_{68}} = \\frac {14094018321907827923954201611} {2933773379069966367528193600}$, b68=2933773379069966367528193600 is not divisible by 3, but all larger harmonic numbers have denominators divisible by 3.", + "", + "You are given M(7) = 719102.", + "", + "Find M(137)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler541() {", + " // Good luck!", + " return true;", + "}", + "", + "euler541();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fee058d9425c70af4f70", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 542: Geometric Progression with Maximum Sum", + "tests": [ + { + "text": "euler542() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler542(), TODO: MISSING ANSWER, 'euler542() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let S(k) be the sum of three or more distinct positive integers having the following properties:", + "No value exceeds k.", + "The values form a geometric progression.", + "The sum is maximal.S(4) = 4 + 2 + 1 = 7S(10) = 9 + 6 + 4 = 19S(12) = 12 + 6 + 3 = 21S(1000) = 1000 + 900 + 810 + 729 = 3439", + "", + "Let $T(n) = \\sum_{k=4}^n (-1)^k S(k)$.T(1000) = 2268", + "", + "Find T(1017)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler542() {", + " // Good luck!", + " return true;", + "}", + "", + "euler542();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fee158d9425c70af4f71", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 543: Prime-Sum Numbers", + "tests": [ + { + "text": "euler543() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler543(), TODO: MISSING ANSWER, 'euler543() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Define function P(n,k) = 1 if n can be written as the sum of k prime numbers (with repetitions allowed), and P(n,k) = 0 otherwise.", + "", + "For example, P(10,2) = 1 because 10 can be written as either 3 + 7 or 5 + 5, but P(11,2) = 0 because no two primes can sum to 11.", + "", + "Let S(n) be the sum of all P(i,k) over 1 ≤ i,k ≤ n.", + "", + "For example, S(10) = 20, S(100) = 2402, and S(1000) = 248838.", + "", + "Let F(k) be the kth Fibonacci number (with F(0) = 0 and F(1) = 1).", + "", + "Find the sum of all S(F(k)) over 3 ≤ k ≤ 44" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler543() {", + " // Good luck!", + " return true;", + "}", + "", + "euler543();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fee258d9425c70af4f72", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 544: Chromatic Conundrum", + "tests": [ + { + "text": "euler544() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler544(), TODO: MISSING ANSWER, 'euler544() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let F(r,c,n) be the number of ways to color a rectangular grid with r rows and c columns using at most n colors such that no two adjacent cells share the same color. Cells that are diagonal to each other are not considered adjacent.", + "", + "For example, F(2,2,3) = 18, F(2,2,20) = 130340, and F(3,4,6) = 102923670.", + "", + "Let S(r,c,n) = $\\sum_{k=1}^{n}$ F(r,c,k).", + "", + "For example, S(4,4,15) mod 109+7 = 325951319.", + "", + "Find S(9,10,1112131415) mod 109+7." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler544() {", + " // Good luck!", + " return true;", + "}", + "", + "euler544();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fee358d9425c70af4f73", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 545: Faulhaber's Formulas", + "tests": [ + { + "text": "euler545() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler545(), TODO: MISSING ANSWER, 'euler545() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The sum of the kth powers of the first n positive integers can be expressed as a polynomial of degree k+1 with rational coefficients, the Faulhaber's Formulas:", + "$1^k + 2^k + ... + n^k = \\sum_{i=1}^n i^k = \\sum_{i=1}^{k+1} a_{i} n^i = a_{1} n + a_{2} n^2 + ... + a_{k} n^k + a_{k+1} n^{k + 1}$,", + "where ai's are rational coefficients that can be written as reduced fractions pi/qi (if ai = 0, we shall consider qi = 1).", + "", + "For example, $1^4 + 2^4 + ... + n^4 = -\\frac 1 {30} n + \\frac 1 3 n^3 + \\frac 1 2 n^4 + \\frac 1 5 n^5.$", + "", + "Define D(k) as the value of q1 for the sum of kth powers (i.e. the denominator of the reduced fraction a1).", + "Define F(m) as the mth value of k ≥ 1 for which D(k) = 20010.", + "You are given D(4) = 30 (since a1 = -1/30), D(308) = 20010, F(1) = 308, F(10) = 96404.", + "", + "Find F(105)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler545() {", + " // Good luck!", + " return true;", + "}", + "", + "euler545();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fee458d9425c70af4f74", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 546: The Floor's Revenge", + "tests": [ + { + "text": "euler546() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler546(), TODO: MISSING ANSWER, 'euler546() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Define fk(n) = $\\sum_{i=0}^{n}$ fk($\\lfloor\\frac{i}{k}\\rfloor$) where fk(0) = 1 and $\\lfloor x \\rfloor$ denotes the floor function.", + "", + "For example, f5(10) = 18, f7(100) = 1003, and f2(103) = 264830889564.", + "", + "Find $(\\sum_{k=2}^{10}$ fk(1014)$)$ mod (109+7)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler546() {", + " // Good luck!", + " return true;", + "}", + "", + "euler546();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fee558d9425c70af4f75", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 547: Distance of random points within hollow square laminae", + "tests": [ + { + "text": "euler547() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler547(), TODO: MISSING ANSWER, 'euler547() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Assuming that two points are chosen randomly (with uniform distribution) within a rectangle, it is possible to determine the expected value of the distance between these two points.", + "", + "For example, the expected distance between two random points in a unit square is about 0.521405, while the expected distance between two random points in a rectangle with side lengths 2 and 3 is about 1.317067.", + "", + "Now we define a hollow square lamina of size n to be an integer sized square with side length n ≥ 3 consisting of n2 unit squares from which a rectangle consisting of x × y unit squares (1 ≤ x,y ≤ n - 2) within the original square has been removed.", + "", + "For n = 3 there exists only one hollow square lamina:", + "", + "", + "", + "For n = 4 you can find 9 distinct hollow square laminae, allowing shapes to reappear in rotated or mirrored form:", + "", + "", + "", + "Let S(n) be the sum of the expected distance between two points chosen randomly within each of the possible hollow square laminae of size n. The two points have to lie within the area left after removing the inner rectangle, i.e. the gray-colored areas in the illustrations above.", + "", + "For example, S(3) = 1.6514 and S(4) = 19.6564, rounded to four digits after the decimal point.", + "", + "Find S(40) rounded to four digits after the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler547() {", + " // Good luck!", + " return true;", + "}", + "", + "euler547();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fee658d9425c70af4f76", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 548: Gozinta Chains", + "tests": [ + { + "text": "euler548() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler548(), TODO: MISSING ANSWER, 'euler548() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A gozinta chain for n is a sequence {1,a,b,...,n} where each element properly divides the next.", + "There are eight gozinta chains for 12:", + "{1,12} ,{1,2,12}, {1,2,4,12}, {1,2,6,12}, {1,3,12}, {1,3,6,12}, {1,4,12} and {1,6,12}. ", + "Let g(n) be the number of gozinta chains for n, so g(12)=8.", + "g(48)=48 and g(120)=132.", + "", + "", + "Find the sum of the numbers n not exceeding 1016 for which g(n)=n." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler548() {", + " // Good luck!", + " return true;", + "}", + "", + "euler548();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fee758d9425c70af4f77", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 549: Divisibility of factorials", + "tests": [ + { + "text": "euler549() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler549(), TODO: MISSING ANSWER, 'euler549() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The smallest number m such that 10 divides m! is m=5.", + "The smallest number m such that 25 divides m! is m=10.", + "", + "Let s(n) be the smallest number m such that n divides m!.", + "So s(10)=5 and s(25)=10.", + "Let S(n) be ∑s(i) for 2 ≤ i ≤ n.", + "S(100)=2012.", + "", + "", + "Find S(108)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler549() {", + " // Good luck!", + " return true;", + "}", + "", + "euler549();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fee858d9425c70af4f78", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 550: Divisor game", + "tests": [ + { + "text": "euler550() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler550(), TODO: MISSING ANSWER, 'euler550() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Two players are playing a game. There are k piles of stones.", + "When it is his turn a player has to choose a pile and replace it by two piles of stones under the following two conditions:", + "", + "", + " Both new piles must have a number of stones more than one and less than the number of stones of the original pile.", + " The number of stones of each of the new piles must be a divisor of the number of stones of the original pile.", + "The first player unable to make a valid move loses.", + "", + "Let f(n,k) be the number of winning positions for the first player, assuming perfect play, when the game is played with k piles each having between 2 and n stones (inclusively).f(10,5)=40085.", + "", + "", + "Find f(107,1012).Give your answer modulo 987654321." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler550() {", + " // Good luck!", + " return true;", + "}", + "", + "euler550();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fee958d9425c70af4f79", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 551: Sum of digits sequence", + "tests": [ + { + "text": "euler551() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler551(), TODO: MISSING ANSWER, 'euler551() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let a0, a1, a2, ... be an integer sequence defined by:", + "a0 = 1;", + "for n ≥ 1, an is the sum of the digits of all preceding terms.", + "The sequence starts with 1, 1, 2, 4, 8, 16, 23, 28, 38, 49, ...", + "You are given a106 = 31054319.", + "Find a1015." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler551() {", + " // Good luck!", + " return true;", + "}", + "", + "euler551();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900feea58d9425c70af4f7a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 552: Chinese leftovers II", + "tests": [ + { + "text": "euler552() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler552(), TODO: MISSING ANSWER, 'euler552() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let An be the smallest positive integer satisfying An mod pi = i for all 1 ≤ i ≤ n, where pi is the", + "i-th prime.", + "For example A2 = 5, since this is the smallest positive solution of the system of equations ", + " A2 mod 2 = 1 ", + " A2 mod 3 = 2", + "The system of equations for A3 adds another constraint. That is, A3 is the smallest positive solution of", + " A3 mod 2 = 1 ", + " A3 mod 3 = 2", + " A3 mod 5 = 3", + "and hence A3 = 23. Similarly, one gets A4 = 53 and A5 = 1523.", + "", + "", + "Let S(n) be the sum of all primes up to n that divide at least one element in the sequence A.", + "For example, S(50) = 69 = 5 + 23 + 41, since 5 divides A2, 23 divides A3 and 41 divides A10 = 5765999453. No other prime number up to 50 divides an element in A.", + "", + "", + "Find S(300000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler552() {", + " // Good luck!", + " return true;", + "}", + "", + "euler552();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900feeb58d9425c70af4f7b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 553: Power sets of power sets", + "tests": [ + { + "text": "euler553() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler553(), TODO: MISSING ANSWER, 'euler553() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let P(n) be the set of the first n positive integers {1, 2, ..., n}.", + "Let Q(n) be the set of all the non-empty subsets of P(n).", + "Let R(n) be the set of all the non-empty subsets of Q(n).", + "", + "An element X ∈ R(n) is a non-empty subset of Q(n), so it is itself a set.", + "From X we can construct a graph as follows:", + "", + "Each element Y ∈ X corresponds to a vertex and labeled with Y;", + "Two vertices Y1 and Y2 are connected if Y1 ∩ Y2 ≠ ∅.", + "For example, X = {{1}, {1,2,3}, {3}, {5,6}, {6,7}} results in the following graph:", + "", + "", + "", + "This graph has two connected components.", + "", + "Let C(n,k) be the number of elements of R(n) that have exactly k connected components in their graph.", + "You are given C(2,1) = 6, C(3,1) = 111, C(4,2) = 486, C(100,10) mod 1 000 000 007 = 728209718.", + "", + "Find C(104,10) mod 1 000 000 007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler553() {", + " // Good luck!", + " return true;", + "}", + "", + "euler553();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900feec58d9425c70af4f7c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 554: Centaurs on a chess board", + "tests": [ + { + "text": "euler554() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler554(), TODO: MISSING ANSWER, 'euler554() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "On a chess board, a centaur moves like a king or a knight. The diagram below shows the valid moves of a centaur (represented by an inverted king) on an 8x8 board.", + "", + "", + "", + "It can be shown that at most n2 non-attacking centaurs can be placed on a board of size 2n×2n.", + "Let C(n) be the number of ways to place n2 centaurs on a 2n×2n board so that no centaur attacks another directly.", + "For example C(1) = 4, C(2) = 25, C(10) = 1477721.", + "", + "Let Fi be the ith Fibonacci number defined as F1 = F2 = 1 and Fi = Fi-1 + Fi-2 for i > 2.", + "", + "Find $\\displaystyle \\left( \\sum_{i=2}^{90} C(F_i) \\right) \\text{mod } (10^8+7)$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler554() {", + " // Good luck!", + " return true;", + "}", + "", + "euler554();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900feed58d9425c70af4f7d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 555: McCarthy 91 function", + "tests": [ + { + "text": "euler555() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler555(), TODO: MISSING ANSWER, 'euler555() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The McCarthy 91 function is defined as follows:", + "$$", + "M_{91}(n) = ", + " \\begin{cases}", + " n - 10 & \\text{if } n > 100 \\\\", + " M_{91}(M_{91}(n+11)) & \\text{if } 0 \\leq n \\leq 100", + " \\end{cases}", + "$$", + "", + "", + "We can generalize this definition by abstracting away the constants into new variables:", + "", + "$$", + "M_{m,k,s}(n) = ", + " \\begin{cases}", + " n - s & \\text{if } n > m \\\\", + " M_{m,k,s}(M_{m,k,s}(n+k)) & \\text{if } 0 \\leq n \\leq m", + " \\end{cases}", + "$$", + "", + "", + "This way, we have $M_{91} = M_{100,11,10}$.", + "", + "", + "Let $F_{m,k,s}$ be the set of fixed points of $M_{m,k,s}$. That is, ", + "", + "$$F_{m,k,s}= \\left\\{ n \\in \\mathbb{N} \\, | \\, M_{m,k,s}(n) = n \\right\\}$$", + "", + "", + "For example, the only fixed point of $M_{91}$ is $n = 91$. In other words, $F_{100,11,10}= \\{91\\}$.", + " ", + "", + "Now, define $SF(m,k,s)$ as the sum of the elements in $F_{m,k,s}$ and let $S(p,m) = \\displaystyle \\sum_{1 \\leq s < k \\leq p}{SF(m,k,s)}$.", + "", + "", + "For example, $S(10, 10) = 225$ and $S(1000, 1000)=208724467$.", + "", + "", + "Find $S(10^6, 10^6)$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler555() {", + " // Good luck!", + " return true;", + "}", + "", + "euler555();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900feee58d9425c70af4f7e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 556: Squarefree Gaussian Integers", + "tests": [ + { + "text": "euler556() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler556(), TODO: MISSING ANSWER, 'euler556() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A Gaussian integer is a number z = a + bi where a, b are integers and i2 = -1.", + "Gaussian integers are a subset of the complex numbers, and the integers are the subset of Gaussian integers for which b = 0.", + "", + "A Gaussian integer unit is one for which a2 + b2 = 1, i.e. one of 1, i, -1, -i.", + "Let's define a proper Gaussian integer as one for which a > 0 and b ≥ 0.", + "", + "A Gaussian integer z1 = a1 + b1i is said to be divisible by z2 = a2 + b2i if z3 = a3 + b3i = z1/z2 is a Gaussian integer.", + "$\\frac {z_1} {z_2} = \\frac {a_1 + b_1 i} {a_2 + b_2 i} = \\frac {(a_1 + b_1 i)(a_2 - b_2 i)} {(a_2 + b_2 i)(a_2 - b_2 i)} = \\frac {a_1 a_2 + b_1 b_2} {a_2^2 + b_2^2} + \\frac {a_2 b_1 - a_1 b_2} {a_2^2 + b_2^2}i = a_3 + b_3 i$", + "So, z1 is divisible by z2 if $\\frac {a_1 a_2 + b_1 b_2} {a_2^2 + b_2^2}$ and $\\frac {a_2 b_1 - a_1 b_2} {a_2^2 + b_2^2}$ are integers.", + "For example, 2 is divisible by 1 + i because 2/(1 + i) = 1 - i is a Gaussian integer.", + "", + "A Gaussian prime is a Gaussian integer that is divisible only by a unit, itself or itself times a unit.", + "For example, 1 + 2i is a Gaussian prime, because it is only divisible by 1, i, -1, -i, 1 + 2i, i(1 + 2i) = i - 2, -(1 + 2i) = -1 - 2i and -i(1 + 2i) = 2 - i.", + "2 is not a Gaussian prime as it is divisible by 1 + i.", + "", + "A Gaussian integer can be uniquely factored as the product of a unit and proper Gaussian primes.", + "For example 2 = -i(1 + i)2 and 1 + 3i = (1 + i)(2 + i).", + "A Gaussian integer is said to be squarefree if its prime factorization does not contain repeated proper Gaussian primes.", + "So 2 is not squarefree over the Gaussian integers, but 1 + 3i is.", + "Units and Gaussian primes are squarefree by definition.", + "", + "Let f(n) be the count of proper squarefree Gaussian integers with a2 + b2 ≤ n.", + "For example f(10) = 7 because 1, 1 + i, 1 + 2i, 1 + 3i = (1 + i)(2 + i), 2 + i, 3 and 3 + i = -i(1 + i)(1 + 2i) are squarefree, while 2 = -i(1 + i)2 and 2 + 2i = -i(1 + i)3 are not.", + "You are given f(102) = 54, f(104) = 5218 and f(108) = 52126906.", + "", + "Find f(1014)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler556() {", + " // Good luck!", + " return true;", + "}", + "", + "euler556();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900feef58d9425c70af4f7f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 557: Cutting triangles", + "tests": [ + { + "text": "euler557() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler557(), TODO: MISSING ANSWER, 'euler557() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A triangle is cut into four pieces by two straight lines, each starting at one vertex and ending on the opposite edge. This results in forming three smaller triangular pieces, and one quadrilateral. If the original triangle has an integral area, it is often possible to choose cuts such that all of the four pieces also have integral area. For example, the diagram below shows a triangle of area 55 that has been cut in this way.", + "", + "", + "", + "Representing the areas as a, b, c and d, in the example above, the individual areas are a = 22, b = 8, c = 11 and d = 14. It is also possible to cut a triangle of area 55 such that a = 20, b = 2, c = 24, d = 9.", + "", + "Define a triangle cutting quadruple (a, b, c, d) as a valid integral division of a triangle, where a is the area of the triangle between the two cut vertices, d is the area of the quadrilateral and b and c are the areas of the two other triangles, with the restriction that b ≤ c. The two solutions described above are (22,8,11,14) and (20,2,24,9). These are the only two possible quadruples that have a total area of 55.", + "", + "", + "Define S(n) as the sum of the area of the uncut triangles represented by all valid quadruples with a+b+c+d ≤ n. For example, S(20) = 259. ", + "", + "", + "Find S(10000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler557() {", + " // Good luck!", + " return true;", + "}", + "", + "euler557();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fef058d9425c70af4f80", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 558: Irrational base", + "tests": [ + { + "text": "euler558() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler558(), TODO: MISSING ANSWER, 'euler558() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let r be the real root of the equation x3 = x2 + 1.", + "Every positive integer can be written as the sum of distinct increasing powers of r.", + "If we require the number of terms to be finite and the difference between any two exponents to be three or more, then the representation is unique.", + "For example, 3 = r -10 + r -5 + r -1 + r 2 and 10 = r -10 + r -7 + r 6.", + "Interestingly, the relation holds for the complex roots of the equation.", + "", + "Let w(n) be the number of terms in this unique representation of n. Thus w(3) = 4 and w(10) = 3.", + "", + "More formally, for all positive integers n, we have:n = $\\displaystyle \\sum_{k=-\\infty}^{\\infty}$ bk rk", + "under the conditions that:bk is 0 or 1 for all k;bk + bk+1 + bk+2 ≤ 1 for all k;w(n) = $\\displaystyle \\sum_{k=-\\infty}^{\\infty}$ bk is finite.", + "", + "Let S(m) = $\\displaystyle \\sum_{j=1}^{m}$ w(j2).", + "You are given S(10) = 61 and S(1000) = 19403.", + "", + "Find S(5 000 000)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler558() {", + " // Good luck!", + " return true;", + "}", + "", + "euler558();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fef158d9425c70af4f81", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 559: Permuted Matrices", + "tests": [ + { + "text": "euler559() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler559(), TODO: MISSING ANSWER, 'euler559() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An ascent of a column j in a matrix occurs if the value of column j is smaller than the value of column j+1 in all rows.", + "", + "Let P(k, r, n) be the number of r x n matrices with the following properties:", + "", + "The rows are permutations of {1, 2, 3, ... , n}.", + " Numbering the first column as 1, a column ascent occurs at column jeuler560() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler560(), TODO: MISSING ANSWER, 'euler560() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Coprime Nim is just like ordinary normal play Nim, but the players may only remove a number of stones from a pile that is coprime with the current size of the pile. Two players remove stones in turn. The player who removes the last stone wins.", + "", + "Let L(n, k) be the number of losing starting positions for the first player, assuming perfect play, when the game is played with k piles, each having between 1 and n - 1 stones inclusively.", + "", + "For example, L(5, 2) = 6 since the losing initial positions are (1, 1), (2, 2), (2, 4), (3, 3), (4, 2) and (4, 4).", + "You are also given L(10, 5) = 9964, L(10, 10) = 472400303, L(103, 103) mod 1 000 000 007 = 954021836.", + "", + "Find L(107, 107) mod 1 000 000 007" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler560() {", + " // Good luck!", + " return true;", + "}", + "", + "euler560();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fef358d9425c70af4f83", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 561: Divisor Pairs", + "tests": [ + { + "text": "euler561() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler561(), TODO: MISSING ANSWER, 'euler561() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let $S(n)$ be the number of pairs $(a,b)$ of distinct divisors of $n$ such that $a$ divides $b$.", + "For $n=6$ we get the following pairs: $(1,2), (1,3), (1,6),( 2,6)$ and $(3,6)$. So $S(6)=5$.", + "Let $p_m\\#$ be the product of the first $m$ prime numbers, so $p_2\\# = 2*3 = 6$.", + "Let $E(m, n)$ be the highest integer $k$ such that $2^k$ divides $S((p_m\\#)^n)$.", + "$E(2,1) = 0$ since $2^0$ is the highest power of 2 that divides S(6)=5.", + "Let $Q(n)=\\sum_{i=1}^{n} E(904961, i)$", + "$Q(8)=2714886$.", + "", + "", + "Evaluate $Q(10^{12})$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler561() {", + " // Good luck!", + " return true;", + "}", + "", + "euler561();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fef458d9425c70af4f84", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 562: Maximal perimeter", + "tests": [ + { + "text": "euler562() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler562(), TODO: MISSING ANSWER, 'euler562() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Construct triangle ABC such that:", + "Vertices A, B and C are lattice points inside or on the circle of radius r centered at the origin;", + "the triangle contains no other lattice point inside or on its edges;", + "the perimeter is maximum.Let R be the circumradius of triangle ABC and T(r) = R/r.", + "For r = 5, one possible triangle has vertices (-4,-3), (4,2) and (1,0) with perimeter $\\sqrt{13}+\\sqrt{34}+\\sqrt{89}$ and circumradius R = $\\sqrt {\\frac {19669} 2 }$, so T(5) =$\\sqrt {\\frac {19669} {50} }$.", + "You are given T(10) ~ 97.26729 and T(100) ~ 9157.64707.", + "", + "Find T(107). Give your answer rounded to the nearest integer." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler562() {", + " // Good luck!", + " return true;", + "}", + "", + "euler562();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fef558d9425c70af4f85", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 563: Robot Welders", + "tests": [ + { + "text": "euler563() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler563(), TODO: MISSING ANSWER, 'euler563() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A company specialises in producing large rectangular metal sheets, starting from unit square metal plates. The welding is performed by a range of robots of increasing size. Unfortunately, the programming options of these robots are rather limited. Each one can only process up to 25 identical rectangles of metal, which they can weld along either edge to produce a larger rectangle. The only programmable variables are the number of rectangles to be processed (up to and including 25), and whether to weld the long or short edge.", + "", + "For example, the first robot could be programmed to weld together 11 raw unit square plates to make a 11×1 strip. The next could take 10 of these 11×1 strips, and weld them either to make a longer 110×1 strip, or a 11×10 rectangle. Many, but not all, possible dimensions of metal sheets can be constructed in this way.", + "", + "One regular customer has a particularly unusual order. He always demands that the finished product should have an exact area, and that the long side must not be more than 10% larger than the short side. If these requirements can be met in more than one way, in terms of the exact dimensions of the two sides, then he demands that all variants are produced. For example, if he were to ask for metal sheet of area 889200, then there are three final dimensions that can be produced: 900×988, 912×975 and 936×950. The target area of 889200 is the smallest area which can be manufactured in three different variants, within the limitations of the robot welders.", + "", + "Let M(n) be the minimal area that can be manufactured in exactly n variants with the longer edge not greater than 10% bigger than the shorter edge. Hence M(3) = 889200.", + "", + "Find $ \\sum_{n=2}^{100} M(n)$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler563() {", + " // Good luck!", + " return true;", + "}", + "", + "euler563();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fef658d9425c70af4f86", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 564: Maximal polygons", + "tests": [ + { + "text": "euler564() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler564(), TODO: MISSING ANSWER, 'euler564() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A line segment of length $2n-3$ is randomly split into $n$ segments of integer length ($n \\ge 3$). In the sequence given by this split, the segments are then used as consecutive sides of a convex $n$-polygon, formed in such a way that its area is maximal. All of the $\\binom{2n-4} {n-1}$ possibilities for splitting up the initial line segment occur with the same probability. ", + "", + "Let $E(n)$ be the expected value of the area that is obtained by this procedure.", + "For example, for $n=3$ the only possible split of the line segment of length $3$ results in three line segments with length $1$, that form an equilateral triangle with an area of $\\frac 1 4 \\sqrt{3}$. Therefore $E(3)=0.433013$, rounded to $6$ decimal places.", + "For $n=4$ you can find $4$ different possible splits, each of which is composed of three line segments with length $1$ and one line segment with length $2$. All of these splits lead to the same maximal quadrilateral with an area of $\\frac 3 4 \\sqrt{3}$, thus $E(4)=1.299038$, rounded to $6$ decimal places.", + "", + "Let $S(k)=\\displaystyle \\sum_{n=3}^k E(n)$.", + "For example, $S(3)=0.433013$, $S(4)=1.732051$, $S(5)=4.604767$ and $S(10)=66.955511$, rounded to $6$ decimal places each.", + "", + "Find $S(50)$, rounded to $6$ decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler564() {", + " // Good luck!", + " return true;", + "}", + "", + "euler564();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fef758d9425c70af4f87", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 565: Divisibility of sum of divisors", + "tests": [ + { + "text": "euler565() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler565(), TODO: MISSING ANSWER, 'euler565() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let $\\sigma(n)$ be the sum of the divisors of $n$.", + "E.g. the divisors of 4 are 1, 2 and 4, so $\\sigma(4)=7$.", + "", + "", + "The numbers $n$ not exceeding 20 such that 7 divides $\\sigma(n)$ are: 4,12,13 and 20, the sum of these numbers being 49.", + "", + "", + "Let $S(n , d)$ be the sum of the numbers $i$ not exceeding $n$ such that $d$ divides $\\sigma(i)$.", + "So $S(20 , 7)=49$.", + "", + "", + "", + "You are given: $S(10^6,2017)=150850429$ and $S(10^9 , 2017)=249652238344557$.", + "", + "", + "Find $S(10^{11} , 2017)$" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler565() {", + " // Good luck!", + " return true;", + "}", + "", + "euler565();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fef858d9425c70af4f88", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 566: Cake Icing Puzzle", + "tests": [ + { + "text": "euler566() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler566(), TODO: MISSING ANSWER, 'euler566() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Adam plays the following game with his birthday cake.", + "", + "He cuts a piece forming a circular sector of 60 degrees and flips the piece upside down, with the icing on the bottom.", + "He then rotates the cake by 60 degrees counterclockwise, cuts an adjacent 60 degree piece and flips it upside down.", + "He keeps repeating this, until after a total of twelve steps, all the icing is back on top.", + "", + "Amazingly, this works for any piece size, even if the cutting angle is an irrational number: all the icing will be back on top after a finite number of steps.", + "", + "Now, Adam tries something different: he alternates cutting pieces of size $x=\\frac{360}{9}$ degrees, $y=\\frac{360}{10}$ degrees and $z=\\frac{360 }{\\sqrt{11}}$ degrees. The first piece he cuts has size x and he flips it. The second has size y and he flips it. The third has size z and he flips it. He repeats this with pieces of size x, y and z in that order until all the icing is back on top, and discovers he needs 60 flips altogether.", + "", + "", + "", + "Let F(a, b, c) be the minimum number of piece flips needed to get all the icing back on top for pieces of size $x=\\frac{360}{a}$ degrees, $y=\\frac{360}{b}$ degrees and $z=\\frac{360}{\\sqrt{c}}$ degrees.", + "Let $G(n) = \\sum_{9 \\le a < b < c \\le n} F(a,b,c)$, for integers a, b and c.", + "", + "You are given that F(9, 10, 11) = 60, F(10, 14, 16) = 506, F(15, 16, 17) = 785232.", + "You are also given G(11) = 60, G(14) = 58020 and G(17) = 1269260.", + "", + "Find G(53)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler566() {", + " // Good luck!", + " return true;", + "}", + "", + "euler566();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fef958d9425c70af4f89", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 567: Reciprocal games I", + "tests": [ + { + "text": "euler567() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler567(), TODO: MISSING ANSWER, 'euler567() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Tom has built a random generator that is connected to a row of $n$ light bulbs. Whenever the random generator is activated each of the $n$ lights is turned on with the probability of $\\frac 1 2$, independently of its former state or the state of the other light bulbs.", + "", + "While discussing with his friend Jerry how to use his generator, they invent two different games, they call the reciprocal games:", + "Both games consist of $n$ turns. Each turn is started by choosing a number $k$ randomly between (and including) $1$ and $n$, with equal probability of $\\frac 1 n$ for each number, while the possible win for that turn is the reciprocal of $k$, that is $\\frac 1 k$.", + "", + "In game A, Tom activates his random generator once in each turn. If the number of lights turned on is the same as the previously chosen number $k$, Jerry wins and gets $\\frac 1 k$, otherwise he will receive nothing for that turn. Jerry's expected win after playing the total game A consisting of $n$ turns is called $J_A(n)$. For example $J_A(6)=0.39505208$, rounded to 8 decimal places.", + "", + "For each turn in game B, after $k$ has been randomly selected, Tom keeps reactivating his random generator until exactly $k$ lights are turned on. After that Jerry takes over and reactivates the random generator until he, too, has generated a pattern with exactly $k$ lights turned on. If this pattern is identical to Tom's last pattern, Jerry wins and gets $\\frac 1 k$, otherwise he will receive nothing. Jerry's expected win after the total game B consisting of $n$ turns is called $J_B(n)$. For example $J_B(6)=0.43333333$, rounded to 8 decimal places.", + "", + "Let $\\displaystyle S(m)=\\sum_{n=1}^m (J_A(n)+J_B(n))$. For example $S(6)=7.58932292$, rounded to 8 decimal places.", + "", + "Find S(123456789), rounded to 8 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler567() {", + " // Good luck!", + " return true;", + "}", + "", + "euler567();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fefa58d9425c70af4f8a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 568: Reciprocal games II", + "tests": [ + { + "text": "euler568() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler568(), TODO: MISSING ANSWER, 'euler568() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Tom has built a random generator that is connected to a row of $n$ light bulbs. Whenever the random generator is activated each of the $n$ lights is turned on with the probability of $\\frac 1 2$, independently of its former state or the state of the other light bulbs.", + "", + "While discussing with his friend Jerry how to use his generator, they invent two different games, they call the reciprocal games:", + "Both games consist of $n$ turns. Each turn is started by choosing a number $k$ randomly between (and including) $1$ and $n$, with equal probability of $\\frac 1 n$ for each number, while the possible win for that turn is the reciprocal of $k$, that is $\\frac 1 k$.", + "", + "In game A, Tom activates his random generator once in each turn. If the number of lights turned on is the same as the previously chosen number $k$, Jerry wins and gets $\\frac 1 k$, otherwise he will receive nothing for that turn. Jerry's expected win after playing the total game A consisting of $n$ turns is called $J_A(n)$. For example $J_A(6)=0.39505208$, rounded to 8 decimal places.", + "", + "For each turn in game B, after $k$ has been randomly selected, Tom keeps reactivating his random generator until exactly $k$ lights are turned on. After that Jerry takes over and reactivates the random generator until he, too, has generated a pattern with exactly $k$ lights turned on. If this pattern is identical to Tom's last pattern, Jerry wins and gets $\\frac 1 k$, otherwise he will receive nothing. Jerry's expected win after the total game B consisting of $n$ turns is called $J_B(n)$. For example $J_B(6)=0.43333333$, rounded to 8 decimal places.", + "", + "Let $D(n)=J_B(n)−J_A(n)$. For example, $D(6) = 0.03828125$.", + "", + "Find the 7 most significant digits of $D(123456789)$ after removing all leading zeros.", + "(If, for example, we had asked for the 7 most significant digits of $D(6)$, the answer would have been 3828125.)" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler568() {", + " // Good luck!", + " return true;", + "}", + "", + "euler568();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fefb58d9425c70af4f8b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 569: Prime Mountain Range", + "tests": [ + { + "text": "euler569() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler569(), TODO: MISSING ANSWER, 'euler569() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A mountain range consists of a line of mountains with slopes of exactly 45°, and heights governed by the prime numbers, pn. The up-slope of the kth mountain is of height p2k−1, and the downslope is p2k. The first few foot-hills of this range are illustrated below.", + "", + "", + "", + "", + "Tenzing sets out to climb each one in turn, starting from the lowest. At the top of each peak, he looks back and counts how many of the previous peaks he can see. In the example above, the eye-line from the third mountain is drawn in red, showing that he can only see the peak of the second mountain from this viewpoint. Similarly, from the 9th mountain, he can see three peaks, those of the 5th, 7th and 8th mountain.", + "", + "Let P(k) be the number of peaks that are visible looking back from the kth mountain. Hence P(3)=1 and P(9)=3.", + "Also $\\displaystyle \\sum_{k=1}^{100} P(k) = 227$.", + "", + "Find $\\displaystyle \\sum_{k=1}^{2500000} P(k)$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler569() {", + " // Good luck!", + " return true;", + "}", + "", + "euler569();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fefc58d9425c70af4f8c", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 570: Snowflakes", + "tests": [ + { + "text": "euler570() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler570(), TODO: MISSING ANSWER, 'euler570() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A snowflake of order n is formed by overlaying an equilateral triangle (rotated by 180 degrees) onto each equilateral triangle of the same size in a snowflake of order n-1. A snowflake of order 1 is a single equilateral triangle.", + "", + "", + "", + " ", + "", + "", + "Some areas of the snowflake are overlaid repeatedly. In the above picture, blue represents the areas that are one layer thick, red two layers thick, yellow three layers thick, and so on. ", + "", + "For an order n snowflake, let A(n) be the number of triangles that are one layer thick, and let B(n) be the number of triangles that are three layers thick. Define G(n) = gcd(A(n), B(n)).", + "", + "E.g. A(3) = 30, B(3) = 6, G(3)=6", + "A(11) = 3027630, B(11) = 19862070, G(11) = 30", + "", + "Further, G(500) = 186 and $\\sum_{n=3}^{500}G(n)=5124$", + "", + "Find $\\displaystyle \\sum_{n=3}^{10^7}G(n)$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler570() {", + " // Good luck!", + " return true;", + "}", + "", + "euler570();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fefd58d9425c70af4f8d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 571: Super Pandigital Numbers", + "tests": [ + { + "text": "euler571() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler571(), TODO: MISSING ANSWER, 'euler571() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A positive number is pandigital in base b if it contains all digits from 0 to b - 1 at least once when written in base b.", + "", + "A n-super-pandigital number is a number that is simultaneously pandigital in all bases from 2 to n inclusively.", + "For example 978 = 11110100102 = 11000203 = 331024 = 124035 is the smallest 5-super-pandigital number.", + "Similarly, 1093265784 is the smallest 10-super-pandigital number.", + "The sum of the 10 smallest 10-super-pandigital numbers is 20319792309.", + "", + "What is the sum of the 10 smallest 12-super-pandigital numbers?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler571() {", + " // Good luck!", + " return true;", + "}", + "", + "euler571();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900fefe58d9425c70af4f8e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 572: Idempotent matrices", + "tests": [ + { + "text": "euler572() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler572(), TODO: MISSING ANSWER, 'euler572() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A matrix $M$ is called idempotent if $M^2 = M$.", + "Let $M$ be a three by three matrix : ", + "$M=\\begin{pmatrix} ", + " a & b & c\\\\ ", + " d & e & f\\\\", + " g &h &i\\\\", + "\\end{pmatrix}$.", + "Let C(n) be the number of idempotent three by three matrices $M$ with integer elements such that", + "$ -n \\le a,b,c,d,e,f,g,h,i \\le n$.", + "", + "C(1)=164 and C(2)=848.", + "", + "", + "Find C(200)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler572() {", + " // Good luck!", + " return true;", + "}", + "", + "euler572();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900feff58d9425c70af4f8f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 573: Unfair race", + "tests": [ + { + "text": "euler573() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler573(), TODO: MISSING ANSWER, 'euler573() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "$n$ runners in very different training states want to compete in a race. Each one of them is given a different starting number $k$ $(1\\leq k \\leq n)$ according to his (constant) individual racing speed being $v_k=\\frac{k}{n}$.", + "In order to give the slower runners a chance to win the race, $n$ different starting positions are chosen randomly (with uniform distribution) and independently from each other within the racing track of length $1$. After this, the starting position nearest to the goal is assigned to runner $1$, the next nearest starting position to runner $2$ and so on, until finally the starting position furthest away from the goal is assigned to runner $n$. The winner of the race is the runner who reaches the goal first.", + "", + "Interestingly, the expected running time for the winner is $\\frac{1}{2}$, independently of the number of runners. Moreover, while it can be shown that all runners will have the same expected running time of $\\frac{n}{n+1}$, the race is still unfair, since the winning chances may differ significantly for different starting numbers:", + "", + "Let $P_{n,k}$ be the probability for runner $k$ to win a race with $n$ runners and $E_n = \\sum_{k=1}^n k P_{n,k}$ be the expected starting number of the winner in that race. It can be shown that, for example,", + "$P_{3,1}=\\frac{4}{9}$, $P_{3,2}=\\frac{2}{9}$, $P_{3,3}=\\frac{1}{3}$ and $E_3=\\frac{17}{9}$ for a race with $3$ runners. ", + "You are given that $E_4=2.21875$, $E_5=2.5104$ and $E_{10}=3.66021568$.", + "", + "Find $E_{1000000}$ rounded to 4 digits after the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler573() {", + " // Good luck!", + " return true;", + "}", + "", + "euler573();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0058d9425c70af4f90", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 574: Verifying Primes", + "tests": [ + { + "text": "euler574() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler574(), TODO: MISSING ANSWER, 'euler574() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let $q$ be a prime and $A \\ge B >0$ be two integers with the following properties:", + " $A$ and $B$ have no prime factor in common, that is $\\text{gcd}(A,B)=1$.", + " The product $AB$ is divisible by every prime less than q.", + "", + "It can be shown that, given these conditions, any sum $A+Beuler575() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler575(), TODO: MISSING ANSWER, 'euler575() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "It was quite an ordinary day when a mysterious alien vessel appeared as if from nowhere. After waiting several hours and receiving no response it is decided to send a team to investigate, of which you are included. Upon entering the vessel you are met by a friendly holographic figure, Katharina, who explains the purpose of the vessel, Eulertopia.", + "", + "She claims that Eulertopia is almost older than time itself. Its mission was to take advantage of a combination of incredible computational power and vast periods of time to discover the answer to life, the universe, and everything. Hence the resident cleaning robot, Leonhard, along with his housekeeping responsibilities, was built with a powerful computational matrix to ponder the meaning of life as he wanders through a massive 1000 by 1000 square grid of rooms. She goes on to explain that the rooms are numbered sequentially from left to right, row by row. So, for example, if Leonhard was wandering around a 5 by 5 grid then the rooms would be numbered in the following way.", + "", + "", + "", + "", + "Many millenia ago Leonhard reported to Katharina to have found the answer and he is willing to share it with any life form who proves to be worthy of such knowledge.", + "", + "Katharina further explains that the designers of Leonhard were given instructions to program him with equal probability of remaining in the same room or travelling to an adjacent room. However, it was not clear to them if this meant (i) an equal probability being split equally between remaining in the room and the number of available routes, or, (ii) an equal probability (50%) of remaining in the same room and then the other 50% was to be split equally between the number of available routes.", + "", + "", + "", + "", + "(i) Probability of remaining related to number of exits", + "(ii) Fixed 50% probability of remaining", + "", + "", + "The records indicate that they decided to flip a coin. Heads would mean that the probability of remaining was dynamically related to the number of exits whereas tails would mean that they program Leonhard with a fixed 50% probability of remaining in a particular room. Unfortunately there is no record of the outcome of the coin, so without further information we would need to assume that there is equal probability of either of the choices being implemented.", + "", + "Katharina suggests it should not be too challenging to determine that the probability of finding him in a square numbered room in a 5 by 5 grid after unfathomable periods of time would be approximately 0.177976190476 [12 d.p.].", + "", + "In order to prove yourself worthy of visiting the great oracle you must calculate the probability of finding him in a square numbered room in the 1000 by 1000 lair in which he has been wandering.", + "(Give your answer rounded to 12 decimal places)" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler575() {", + " // Good luck!", + " return true;", + "}", + "", + "euler575();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0258d9425c70af4f92", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 576: Irrational jumps", + "tests": [ + { + "text": "euler576() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler576(), TODO: MISSING ANSWER, 'euler576() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A bouncing point moves counterclockwise along a circle with circumference $1$ with jumps of constant length $l<1$, until it hits a gap of length $g<1$, that is placed in a distance $d$ counterclockwise from the starting point. The gap does not include the starting point, that is $g+d<1$.", + "", + "Let $S(l,g,d)$ be the sum of the length of all jumps, until the point falls into the gap. It can be shown that $S(l,g,d)$ is finite for any irrational jump size $l$, regardless of the values of $g$ and $d$.", + "Examples: ", + "$S(\\sqrt{\\frac 1 2}, 0.06, 0.7)=0.7071 \\dots$, $S(\\sqrt{\\frac 1 2}, 0.06, 0.3543)=1.4142 \\dots$ and $S(\\sqrt{\\frac 1 2}, 0.06, 0.2427)=16.2634 \\dots$.", + "", + "Let $M(n, g)$ be the maximum of $ \\sum S(\\sqrt{\\frac 1 p}, g, d)$ for all primes $p \\le n$ and any valid value of $d$.", + "Examples:", + "$M(3, 0.06) =29.5425 \\dots$, since $S(\\sqrt{\\frac 1 2}, 0.06, 0.2427)+S(\\sqrt{\\frac 1 3}, 0.06, 0.2427)=29.5425 \\dots$ is the maximal reachable sum for $g=0.06$. ", + "$M(10, 0.01)=266.9010 \\dots$ ", + "", + "Find $M(100, 0.00002)$, rounded to 4 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler576() {", + " // Good luck!", + " return true;", + "}", + "", + "euler576();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0358d9425c70af4f93", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 577: Counting hexagons", + "tests": [ + { + "text": "euler577() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler577(), TODO: MISSING ANSWER, 'euler577() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "An equilateral triangle with integer side length $n \\ge 3$ is divided into $n^2$ equilateral triangles with side length 1 as shown in the diagram below.", + "The vertices of these triangles constitute a triangular lattice with $\\frac{(n+1)(n+2)} 2$ lattice points.", + "Let $H(n)$ be the number of all regular hexagons that can be found by connecting 6 of these points. ", + "", + "", + "", + "", + "For example, $H(3)=1$, $H(6)=12$ and $H(20)=966$.", + "", + "Find $\\displaystyle \\sum_{n=3}^{12345} H(n)$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler577() {", + " // Good luck!", + " return true;", + "}", + "", + "euler577();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0458d9425c70af4f94", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 578: Integers with decreasing prime powers", + "tests": [ + { + "text": "euler578() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler578(), TODO: MISSING ANSWER, 'euler578() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Any positive integer can be written as a product of prime powers: p1a1 × p2a2 × ... × pkak,", + "where pi are distinct prime integers, ai > 0 and pi < pj if i < j.", + "", + "A decreasing prime power positive integer is one for which ai ≥ aj if i < j.", + "For example, 1, 2, 15=3×5, 360=23×32×5 and 1000=23×53 are decreasing prime power integers.", + "", + "Let C(n) be the count of decreasing prime power positive integers not exceeding n.", + "C(100) = 94 since all positive integers not exceeding 100 have decreasing prime powers except 18, 50, 54, 75, 90 and 98.", + "You are given C(106) = 922052.", + "", + "Find C(1013)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler578() {", + " // Good luck!", + " return true;", + "}", + "", + "euler578();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0558d9425c70af4f95", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 579: Lattice points in lattice cubes", + "tests": [ + { + "text": "euler579() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler579(), TODO: MISSING ANSWER, 'euler579() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A lattice cube is a cube in which all vertices have integer coordinates. Let C(n) be the number of different lattice cubes in which the coordinates of all vertices range between (and including) 0 and n. Two cubes are hereby considered different if any of their vertices have different coordinates.", + "For example, C(1)=1, C(2)=9, C(4)=100, C(5)=229, C(10)=4469 and C(50)=8154671.", + "", + "Different cubes may contain different numbers of lattice points.", + "", + "For example, the cube with the vertices", + "(0, 0, 0), (3, 0, 0), (0, 3, 0), (0, 0, 3), (0, 3, 3), (3, 0, 3), (3, 3, 0), (3, 3, 3) contains 64 lattice points (56 lattice points on the surface including the 8 vertices and 8 points within the cube). ", + "In contrast, the cube with the vertices", + "(0, 2, 2), (1, 4, 4), (2, 0, 3), (2, 3, 0), (3, 2, 5), (3, 5, 2), (4, 1, 1), (5, 3, 3) contains only 40 lattice points (20 points on the surface and 20 points within the cube), although both cubes have the same side length 3.", + "", + "", + "Let S(n) be the sum of the lattice points contained in the different lattice cubes in which the coordinates of all vertices range between (and including) 0 and n.", + "", + "For example, S(1)=8, S(2)=91, S(4)=1878, S(5)=5832, S(10)=387003 and S(50)=29948928129.", + "", + "Find S(5000) mod 109." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler579() {", + " // Good luck!", + " return true;", + "}", + "", + "euler579();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0658d9425c70af4f96", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 580: Squarefree Hilbert numbers", + "tests": [ + { + "text": "euler580() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler580(), TODO: MISSING ANSWER, 'euler580() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A Hilbert number is any positive integer of the form $4k+1$ for integer $k\\geq 0$. We shall define a squarefree Hilbert number as a Hilbert number which is not divisible by the square of any Hilbert number other than one. For example, $117$ is a squarefree Hilbert number, equaling $9\\times13$. However $6237$ is a Hilbert number that is not squarefree in this sense, as it is divisible by $9^2$. The number $3969$ is also not squarefree, as it is divisible by both $9^2$ and $21^2$. ", + "", + "", + "There are $2327192$ squarefree Hilbert numbers below $10^7$. ", + "How many squarefree Hilbert numbers are there below $10^{16}$?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler580() {", + " // Good luck!", + " return true;", + "}", + "", + "euler580();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0758d9425c70af4f97", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 581: 47-smooth triangular numbers", + "tests": [ + { + "text": "euler581() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler581(), TODO: MISSING ANSWER, 'euler581() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A number is p-smooth if it has no prime factors larger than p.", + "Let T be the sequence of triangular numbers, ie T(n)=n(n+1)/2.", + "Find the sum of all indices n such that T(n) is 47-smooth." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler581() {", + " // Good luck!", + " return true;", + "}", + "", + "euler581();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0858d9425c70af4f98", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 582: Nearly isosceles 120 degree triangles", + "tests": [ + { + "text": "euler582() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler582(), TODO: MISSING ANSWER, 'euler582() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let a, b and c be the sides of an integer sided triangle with one angle of 120 degrees, a≤b≤c and b-a≤100.", + "Let T(n) be the number of such triangles with c≤n.", + "T(1000)=235 and T(108)=1245.", + "Find T(10100)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler582() {", + " // Good luck!", + " return true;", + "}", + "", + "euler582();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0958d9425c70af4f99", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 583: Heron Envelopes", + "tests": [ + { + "text": "euler583() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler583(), TODO: MISSING ANSWER, 'euler583() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A standard envelope shape is a convex figure consisting of an isosceles triangle (the flap) placed on top of a rectangle. An example of an envelope with integral sides is shown below. Note that to form a sensible envelope, the perpendicular height of the flap (BCD) must be smaller than the height of the rectangle (ABDE). ", + "", + "", + "", + "", + "", + "", + "In the envelope illustrated, not only are all the sides integral, but also all the diagonals (AC, AD, BD, BE and CE) are integral too. Let us call an envelope with these properties a Heron envelope.", + "", + "", + "", + "Let S(p) be the sum of the perimeters of all the Heron envelopes with a perimeter less than or equal to p. ", + "", + "", + "You are given that S(104) = 884680. Find S(107)." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler583() {", + " // Good luck!", + " return true;", + "}", + "", + "euler583();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0a58d9425c70af4f9a", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 584: Birthday Problem Revisited", + "tests": [ + { + "text": "euler584() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler584(), TODO: MISSING ANSWER, 'euler584() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A long long time ago in a galaxy far far away, the Wimwians, inhabitants of planet WimWi, discovered an unmanned drone that had landed on their planet. On examining the drone, they uncovered a device that sought the answer for the so called \"Birthday Problem\". The description of the problem was as follows:", + "", + "If people on your planet were to enter a very large room one by one, what will be the expected number of people in the room when you first find 3 people with Birthdays within 1 day from each other.", + "", + "The description further instructed them to enter the answer into the device and send the drone into space again. Startled by this turn of events, the Wimwians consulted their best mathematicians. Each year on Wimwi has 10 days and the mathematicians assumed equally likely birthdays and ignored leap years (leap years in Wimwi have 11 days), and found 5.78688636 to be the required answer. As such, the Wimwians entered this answer and sent the drone back into space.", + "", + "", + "After traveling light years away, the drone then landed on planet Joka. The same events ensued except this time, the numbers in the device had changed due to some unknown technical issues. The description read:", + "", + "If people on your planet were to enter a very large room one by one, what will be the expected number of people in the room when you first find 3 people with Birthdays within 7 days from each other.", + "", + "With a 100-day year on the planet, the Jokars (inhabitants of Joka) found the answer to be 8.48967364 (rounded to 8 decimal places because the device allowed only 8 places after the decimal point) assuming equally likely birthdays. They too entered the answer into the device and launched the drone into space again.", + "", + "", + "This time the drone landed on planet Earth. As before the numbers in the problem description had changed. It read:", + "", + "If people on your planet were to enter a very large room one by one, what will be the expected number of people in the room when you first find 4 people with Birthdays within 7 days from each other.", + "", + "What would be the answer (rounded to eight places after the decimal point) the people of Earth have to enter into the device for a year with 365 days? Ignore leap years. Also assume that all birthdays are equally likely and independent of each other." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler584() {", + " // Good luck!", + " return true;", + "}", + "", + "euler584();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0b58d9425c70af4f9b", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 585: Nested square roots", + "tests": [ + { + "text": "euler585() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler585(), TODO: MISSING ANSWER, 'euler585() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the term $\\small \\sqrt{x+\\sqrt{y}+\\sqrt{z}}$ that is representing a nested square root. $x$, $y$ and $z$ are positive integers and $y$ and $z$ are not allowed to be perfect squares, so the number below the outer square root is irrational. Still it can be shown that for some combinations of $x$, $y$ and $z$ the given term can be simplified into a sum and/or difference of simple square roots of integers, actually denesting the square roots in the initial expression. ", + "", + "Here are some examples of this denesting:", + "$\\small \\sqrt{3+\\sqrt{2}+\\sqrt{2}}=\\sqrt{2}+\\sqrt{1}=\\sqrt{2}+1$", + "$\\small \\sqrt{8+\\sqrt{15}+\\sqrt{15}}=\\sqrt{5}+\\sqrt{3}$", + "$\\small \\sqrt{20+\\sqrt{96}+\\sqrt{12}}=\\sqrt{9}+\\sqrt{6}+\\sqrt{3}-\\sqrt{2}=3+\\sqrt{6}+\\sqrt{3}-\\sqrt{2}$", + "$\\small \\sqrt{28+\\sqrt{160}+\\sqrt{108}}=\\sqrt{15}+\\sqrt{6}+\\sqrt{5}-\\sqrt{2}$", + "As you can see the integers used in the denested expression may also be perfect squares resulting in further simplification.", + "", + "Let F($n$) be the number of different terms $\\small \\sqrt{x+\\sqrt{y}+\\sqrt{z}}$, that can be denested into the sum and/or difference of a finite number of square roots, given the additional condition that $0euler586() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler586(), TODO: MISSING ANSWER, 'euler586() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The number 209 can be expressed as $a^2 + 3ab + b^2$ in two distinct ways:", + "", + "", + "$ \\qquad 209 = 8^2 + 3\\cdot 8\\cdot 5 + 5^2$ ", + "$ \\qquad 209 = 13^2 + 3\\cdot13\\cdot 1 + 1^2$", + "", + "", + "Let $f(n,r)$ be the number of integers $k$ not exceeding $n$ that can be expressed as $k=a^2 + 3ab + b^2$, with $a\\gt b>0$ integers, in exactly $r$ different ways.", + "", + "", + "You are given that $f(10^5, 4) = 237$ and $f(10^8, 6) = 59517$.", + "", + "", + "Find $f(10^{15}, 40)$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler586() {", + " // Good luck!", + " return true;", + "}", + "", + "euler586();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0d58d9425c70af4f9d", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 587: Concave triangle", + "tests": [ + { + "text": "euler587() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler587(), TODO: MISSING ANSWER, 'euler587() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A square is drawn around a circle as shown in the diagram below on the left.", + "We shall call the blue shaded region the L-section.", + "A line is drawn from the bottom left of the square to the top right as shown in the diagram on the right.", + "We shall call the orange shaded region a concave triangle.", + "", + "", + "", + "", + "It should be clear that the concave triangle occupies exactly half of the L-section.", + "", + "", + "", + "Two circles are placed next to each other horizontally, a rectangle is drawn around both circles, and a line is drawn from the bottom left to the top right as shown in the diagram below.", + "", + "", + "", + "", + "This time the concave triangle occupies approximately 36.46% of the L-section.", + "", + "", + "If n circles are placed next to each other horizontally, a rectangle is drawn around the n circles, and a line is drawn from the bottom left to the top right, then it can be shown that the least value of n for which the concave triangle occupies less than 10% of the L-section is n = 15.", + "", + "", + "What is the least value of n for which the concave triangle occupies less than 0.1% of the L-section?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler587() {", + " // Good luck!", + " return true;", + "}", + "", + "euler587();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0e58d9425c70af4f9e", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 588: Quintinomial coefficients", + "tests": [ + { + "text": "euler588() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler588(), TODO: MISSING ANSWER, 'euler588() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The coefficients in the expansion of $(x+1)^k$ are called binomial coefficients.", + "Analoguously the coefficients in the expansion of $(x^4+x^3+x^2+x+1)^k$ are called quintinomial coefficients. (quintus= Latin for fifth).", + "", + "", + "Consider the expansion of $(x^4+x^3+x^2+x+1)^3$:", + "$x^{12}+3x^{11}+6x^{10}+10x^9+15x^8+18x^7+19x^6+18x^5+15x^4+10x^3+6x^2+3x+1$", + "As we can see 7 out of the 13 quintinomial coefficients for $k=3$ are odd.", + "", + "", + "Let $Q(k)$ be the number of odd coefficients in the expansion of $(x^4+x^3+x^2+x+1)^k$.", + "So $Q(3)=7$.", + "", + "", + "You are given $Q(10)=17$ and $Q(100)=35$.", + "", + "Find $\\sum_{k=1}^{18}Q(10^k) $." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler588() {", + " // Good luck!", + " return true;", + "}", + "", + "euler588();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff0f58d9425c70af4f9f", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 589: Poohsticks Marathon", + "tests": [ + { + "text": "euler589() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler589(), TODO: MISSING ANSWER, 'euler589() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Christopher Robin and Pooh Bear love the game of Poohsticks so much that they invented a new version which allows them to play for longer before one of them wins and they have to go home for tea. The game starts as normal with both dropping a stick simultaneously on the upstream side of a bridge. But rather than the game ending when one of the sticks emerges on the downstream side, instead they fish their sticks out of the water, and drop them back in again on the upstream side. The game only ends when one of the sticks emerges from under the bridge ahead of the other one having also 'lapped' the other stick - that is, having made one additional journey under the bridge compared to the other stick.", + "", + "", + "On a particular day when playing this game, the time taken for a stick to travel under the bridge varies between a minimum of 30 seconds, and a maximum of 60 seconds. The time taken to fish a stick out of the water and drop it back in again on the other side is 5 seconds. The current under the bridge has the unusual property that the sticks' journey time is always an integral number of seconds, and it is equally likely to emerge at any of the possible times between 30 and 60 seconds (inclusive). It turns out that under these circumstances, the expected time for playing a single game is 1036.15 seconds (rounded to 2 decimal places). This time is measured from the point of dropping the sticks for the first time, to the point where the winning stick emerges from under the bridge having lapped the other.", + "", + "", + "The stream flows at different rates each day, but maintains the property that the journey time in seconds is equally distributed amongst the integers from a minimum, $n$, to a maximum, $m$, inclusive. Let the expected time of play in seconds be $E(m,n)$. Hence $E(60,30)=1036.15...$", + "", + "", + "Let $S(k)=\\sum_{m=2}^k\\sum_{n=1}^{m-1}E(m,n)$.", + "", + "", + "For example $S(5)=7722.82$ rounded to 2 decimal places.", + "", + "", + "Find $S(100)$ and give your answer rounded to 2 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler589() {", + " // Good luck!", + " return true;", + "}", + "", + "euler589();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1058d9425c70af4fa0", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 590: Sets with a given Least Common Multiple", + "tests": [ + { + "text": "euler590() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler590(), TODO: MISSING ANSWER, 'euler590() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let H(n) denote the number of sets of positive integers such that the least common multiple of the integers in the set equals n.", + "E.g.:", + "The integers in the following ten sets all have a least common multiple of 6:", + "{2,3}, {1,2,3}, {6}, {1,6}, {2,6} ,{1,2,6}, {3,6}, {1,3,6}, {2,3,6} and {1,2,3,6}.", + "Thus H(6)=10.", + "", + "", + "Let L(n) denote the least common multiple of the numbers 1 through n.", + "E.g. L(6) is the least common multiple of the numbers 1,2,3,4,5,6 and L(6) equals 60.", + "", + "", + "Let HL(n) denote H(L(n)).", + "You are given HL(4)=H(12)=44.", + "", + "", + "Find HL(50000). Give your answer modulo 109." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler590() {", + " // Good luck!", + " return true;", + "}", + "", + "euler590();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1158d9425c70af4fa1", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 591: Best Approximations by Quadratic Integers", + "tests": [ + { + "text": "euler591() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler591(), TODO: MISSING ANSWER, 'euler591() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Given a non-square integer $d$, any real $x$ can be approximated arbitrarily close by quadratic integers $a+b\\sqrt{d}$, where $a,b$ are integers. For example, the following inequalities approximate $\\pi$ with precision $10^{-13}$:", + "$$4375636191520\\sqrt{2}-6188084046055 < \\pi < 721133315582\\sqrt{2}-1019836515172 $$ ", + "We call $BQA_d(x,n)$ the quadratic integer closest to $x$ with the absolute values of $a,b$ not exceeding $n$. We also define the integral part of a quadratic integer as $I_d(a+b\\sqrt{d}) = a$.", + "", + "You are given that:", + "$BQA_2(\\pi,10) = 6 - 2\\sqrt{2}$", + "$BQA_5(\\pi,100)=26\\sqrt{5}-55$", + "$BQA_7(\\pi,10^6)=560323 - 211781\\sqrt{7}$", + "$I_2(BQA_2(\\pi,10^{13}))=-6188084046055$Find the sum of $|I_d(BQA_d(\\pi,10^{13}))|$ for all non-square positive integers less than 100." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler591() {", + " // Good luck!", + " return true;", + "}", + "", + "euler591();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1258d9425c70af4fa2", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 592: Factorial trailing digits 2", + "tests": [ + { + "text": "euler592() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler592(), TODO: MISSING ANSWER, 'euler592() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For any N, let f(N) be the last twelve hexadecimal digits before the trailing zeroes in N!.", + "", + "For example, the hexadecimal representation of 20! is 21C3677C82B40000,", + "so f(20) is the digit sequence 21C3677C82B4.", + "", + "Find f(20!). Give your answer as twelve hexadecimal digits, using uppercase for the digits A to F." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler592() {", + " // Good luck!", + " return true;", + "}", + "", + "euler592();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1358d9425c70af4fa3", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 593: Fleeting Medians", + "tests": [ + { + "text": "euler593() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler593(), TODO: MISSING ANSWER, 'euler593() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "We define two sequences $S = \\{S(1), S(2), ..., S(n)\\}$ and $S_2 = \\{S_2(1), S_2(2), ..., S_2(n)\\}$:", + "", + "$S(k) = (p_k)^k$ mod $10007$ where $p_k$ is the $k$th prime number.", + "", + "$S_2(k) = S(k) + S(\\lfloor\\frac{k}{10000}\\rfloor + 1)$ where $\\lfloor \\cdot \\rfloor$ denotes the floor function.", + "", + "Then let $M(i, j)$ be the median of elements $S_2(i)$ through $S_2(j)$, inclusive. For example, $M(1, 10) = 2021.5$ and $M(10^2, 10^3) = 4715.0$.", + "", + "Let $F(n, k) = \\sum_{i=1}^{n-k+1} M(i, i + k - 1)$. For example, $F(100, 10) = 463628.5$ and $F(10^5, 10^4) = 675348207.5$.", + "", + "Find $F(10^7, 10^5)$. If the sum is not an integer, use $.5$ to denote a half. Otherwise, use $.0$ instead." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler593() {", + " // Good luck!", + " return true;", + "}", + "", + "euler593();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1458d9425c70af4fa4", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 594: Rhombus Tilings", + "tests": [ + { + "text": "euler594() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler594(), TODO: MISSING ANSWER, 'euler594() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "For a polygon $P$, let $t(P)$ be the number of ways in which $P$ can be tiled using rhombi and squares with edge length 1. Distinct rotations and reflections are counted as separate tilings.", + "", + "", + "For example, if $O$ is a regular octagon with edge length 1, then $t(O) = 8$. As it happens, all these 8 tilings are rotations of one another:", + "", + "", + "", + "", + "Let $O_{a,b}$ be the equal-angled convex octagon whose edges alternate in length between $a$ and $b$.", + "", + "For example, here is $O_{2,1}$, with one of its tilings:", + "", + "", + "", + "", + "", + "You are given that $t(O_{1,1})=8$, $t(O_{2,1})=76$ and $t(O_{3,2})=456572$.", + "", + "", + "Find $t(O_{4,2})$." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler594() {", + " // Good luck!", + " return true;", + "}", + "", + "euler594();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1558d9425c70af4fa5", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 595: Incremental Random Sort", + "tests": [ + { + "text": "euler595() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler595(), TODO: MISSING ANSWER, 'euler595() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "A deck of cards numbered from 1 to n is shuffled randomly such that each permutation is equally likely.", + "", + "", + "The cards are to be sorted into ascending order using the following technique:", + " Look at the initial sequence of cards. If it is already sorted, then there is no need for further action. Otherwise, if any subsequences of cards happen to be in the correct place relative to one another (ascending with no gaps), then those subsequences are fixed by attaching the cards together. For example, with 7 cards initially in the order 4123756, the cards labelled 1, 2 and 3 would be attached together, as would 5 and 6.", + " The cards are 'shuffled' by being thrown into the air, but note that any correctly sequenced cards remain attached, so their orders are maintained. The cards (or bundles of attached cards) are then picked up randomly. You should assume that this randomisation is unbiased, despite the fact that some cards are single, and others are grouped together. ", + " Repeat steps 1 and 2 until the cards are sorted. ", + "", + " Let S(n) be the expected number of shuffles needed to sort the cards. Since the order is checked before the first shuffle, S(1) = 0. You are given that S(2) = 1, and S(5) = 4213/871.", + "", + "", + "Find S(52), and give your answer rounded to 8 decimal places." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler595() {", + " // Good luck!", + " return true;", + "}", + "", + "euler595();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1658d9425c70af4fa6", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 596: Number of lattice points in a hyperball", + "tests": [ + { + "text": "euler596() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler596(), TODO: MISSING ANSWER, 'euler596() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let T(r) be the number of integer quadruplets x, y, z, t such that x2 + y2 + z2 + t2 ≤ r2. In other words, T(r) is the number of lattice points in the four-dimensional hyperball of radius r.", + "", + "You are given that T(2) = 89, T(5) = 3121, T(100) = 493490641 and T(104) = 49348022079085897.", + "", + "Find T(108) mod 1000000007." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler596() {", + " // Good luck!", + " return true;", + "}", + "", + "euler596();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1758d9425c70af4fa7", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 597: Torpids", + "tests": [ + { + "text": "euler597() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler597(), TODO: MISSING ANSWER, 'euler597() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The Torpids are rowing races held annually in Oxford, following some curious rules:", + "", + "", + "A division consists of $n$ boats (typically 13), placed in order based on past performance.", + "", + "All boats within a division start at 40 metre intervals along the river, in order with the highest-placed boat starting furthest upstream.", + "", + "The boats all start rowing simultaneously, upstream, trying to catch the boat in front while avoiding being caught by boats behind.", + "", + "Each boat continues rowing until either it reaches the finish line or it catches up with (\"bumps\") a boat in front.", + "", + "The finish line is a distance $L$ metres (the course length, in reality about 1800 metres) upstream from the starting position of the lowest-placed boat. (Because of the staggered starting positions, higher-placed boats row a slightly shorter course than lower-placed boats.)", + "", + "When a \"bump\" occurs, the \"bumping\" boat takes no further part in the race. The \"bumped\" boat must continue, however, and may even be \"bumped\" again by boats that started two or more places behind it.", + "", + "After the race, boats are assigned new places within the division, based on the bumps that occurred. Specifically, for any boat $A$ that started in a lower place than $B$, then $A$ will be placed higher than $B$ in the new order if and only if one of the following occurred:", + " $A$ bumped $B$ directly ", + " $A$ bumped another boat that went on to bump $B$ ", + " $A$ bumped another boat, that bumped yet another boat, that bumped $B$ ", + " etc NOTE: For the purposes of this problem you may disregard the boats' lengths, and assume that a bump occurs precisely when the two boats draw level. (In reality, a bump is awarded as soon as physical contact is made, which usually occurs when there is much less than a full boat length's overlap.)", + "", + "", + "Suppose that, in a particular race, each boat $B_j$ rows at a steady speed $v_j = -$log$X_j$ metres per second, where the $X_j$ are chosen randomly (with uniform distribution) between 0 and 1, independently from one another. These speeds are relative to the riverbank: you may disregard the flow of the river.", + "", + "", + "Let $p(n,L)$ be the probability that the new order is an even permutation of the starting order, when there are $n$ boats in the division and $L$ is the course length.", + "", + "", + "For example, with $n=3$ and $L=160$, labelling the boats as $A$,$B$,$C$ in starting order with $C$ highest, the different possible outcomes of the race are as follows:", + "", + " Bumps occurring ", + " New order ", + " Permutation ", + " Probability ", + " none ", + " $A$, $B$, $C$ ", + " even ", + " $4/15$ ", + " $B$ bumps $C$ ", + " $A$, $C$, $B$ ", + " odd ", + " $8/45$ ", + " $A$ bumps $B$ ", + " $B$, $A$, $C$ ", + " odd ", + " $1/3$ ", + "     $B$ bumps $C$, then $A$ bumps $C$     ", + " $C$, $A$, $B$ ", + " even ", + " $4/27$ ", + "     $A$ bumps $B$, then $B$ bumps $C$     ", + " $C$, $B$, $A$ ", + " odd ", + " $2/27$ ", + " ", + "Therefore, $p(3,160) = 4/15 + 4/27 = 56/135$.", + "", + "", + "You are also given that $p(4,400)=0.5107843137$, rounded to 10 digits after the decimal point.", + "", + "", + "Find $p(13,1800)$ rounded to 10 digits after the decimal point." + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler597() {", + " // Good luck!", + " return true;", + "}", + "", + "euler597();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1858d9425c70af4fa8", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 598: Split Divisibilities", + "tests": [ + { + "text": "euler598() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler598(), TODO: MISSING ANSWER, 'euler598() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Consider the number 48.", + "There are five pairs of integers $a$ and $b$ ($a \\leq b$) such that $a \\times b=48$: (1,48), (2,24), (3,16), (4,12) and (6,8).", + "It can be seen that both 6 and 8 have 4 divisors.", + "So of those five pairs one consists of two integers with the same number of divisors.", + "", + "In general:", + "Let $C(n)$ be the number of pairs of positive integers $a \\times b=n$, ($a \\leq b$) such that $a$ and $b$ have the same number of divisors; so $C(48)=1$.", + "", + "", + "You are given $C(10!)=3$: (1680, 2160), (1800, 2016) and (1890,1920). ", + "Find $C(100!)$" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler598() {", + " // Good luck!", + " return true;", + "}", + "", + "euler598();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1958d9425c70af4fa9", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 599: Distinct Colourings of a Rubik's Cube", + "tests": [ + { + "text": "euler599() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler599(), TODO: MISSING ANSWER, 'euler599() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "The well-known Rubik's Cube puzzle has many fascinating mathematical properties. The 2×2×2 variant has 8 cubelets with a total of 24 visible faces, each with a coloured sticker. Successively turning faces will rearrange the cubelets, although not all arrangements of cubelets are reachable without dismantling the puzzle.", + "", + "", + "Suppose that we wish to apply new stickers to a 2×2×2 Rubik's cube in a non-standard colouring. Specifically, we have $n$ different colours available (with an unlimited supply of stickers of each colour), and we place one sticker on each of the 24 faces in any arrangement that we please. We are not required to use all the colours, and if desired the same colour may appear in more than one face of a single cubelet.", + "", + "", + "We say that two such colourings $c_1,c_2$ are essentially distinct if a cube coloured according to $c_1$ cannot be made to match a cube coloured according to $c_2$ by performing mechanically possible Rubik's Cube moves.", + "", + "", + "For example, with two colours available, there are 183 essentially distinct colourings.", + "", + "", + "How many essentially distinct colourings are there with 10 different colours available?" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler599() {", + " // Good luck!", + " return true;", + "}", + "", + "euler599();" + ], + "head": "", + "tail": "" + } + } + }, + { + "id": "5900ff1a58d9425c70af4faa", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 600: Integer sided equiangular hexagons", + "tests": [ + { + "text": "euler600() should return TODO: MISSING ANSWER.", + "testString": "assert.strictEqual(euler600(), TODO: MISSING ANSWER, 'euler600() should return TODO: MISSING ANSWER.');" + } + ], + "solutions": [], + "translations": {}, + "description": [ + "Let H(n) be the number of distinct integer sided equiangular convex hexagons with perimeter not exceeding n.", + "Hexagons are distinct if and only if they are not congruent.", + "", + "You are given H(6) = 1, H(12) = 10, H(100) = 31248.", + "Find H(55106).", + "", + "", + "Equiangular hexagons with perimeter not exceeding 12" + ], + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function euler600() {", + " // Good luck!", + " return true;", + "}", + "", + "euler600();" + ], + "head": "", + "tail": "" + } + } + } + ], + "fileName": "08-coding-interview-questions-and-take-home-assignments/project-euler-problems.json", + "superBlock": "coding-interview-questions-and-take-home-assignments", + "superOrder": 8 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/08-coding-interview-prep/rosetta-code.json b/packages/learn/seed/challenges/08-coding-interview-prep/rosetta-code.json new file mode 100644 index 0000000000..048da52937 --- /dev/null +++ b/packages/learn/seed/challenges/08-coding-interview-prep/rosetta-code.json @@ -0,0 +1,5086 @@ +{ + "name": "Rosetta Code", + "order": 5, + "time": "", + "helpRoom": "", + "nChallenges": 437, + "challenges": [ + { + "title": "100 doors", + "type": "Waypoint", + "description": [ + "

There are 100 doors in a row that are all initially closed. You make 100 passes by the doors. The first time through, visit every door and 'toggle' the door (if the door is closed, open it; if it is open, close it). The second time, only visit every 2nd door (i.e., door #2, #4, #6, ...) and toggle it. The third time, visit every 3rd door (i.e., door #3, #6, #9, ...), etc., until you only visit the 100th door.

", + "

Implement a function to determine the state of the doors after the last pass. Return the final result in an array, with only the door number included in the array if it is open.

" + ], + "solutions": [ + "function getFinalOpenedDoors (numDoors) {\n // this is the final pattern (always squares).\n // thus, the most efficient solution simply returns an array of squares up to numDoors).\n const finalState = [];\n let i = 1;\n while (Math.pow(i, 2) <= numDoors) {\n finalState.push(Math.pow(i, 2));\n i++;\n }\n return finalState;\n}\n" + ], + "tests": [ + { + "text": "getFinalOpenedDoors is a function.", + "testString": "assert(typeof getFinalOpenedDoors === 'function', 'getFinalOpenedDoors is a function.');" + }, + { + "text": "getFinalOpenedDoors should return an array.", + "testString": "assert(Array.isArray(getFinalOpenedDoors(100)), 'getFinalOpenedDoors should return an array.');" + }, + { + "text": "getFinalOpenedDoors did not produce the correct results.", + "testString": "assert.deepEqual(getFinalOpenedDoors(100), solution, 'getFinalOpenedDoors did not produce the correct results.');" + } + ], + "id": "594810f028c0303b75339acb", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function getFinalOpenedDoors (numDoors) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const solution = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100];" + } + } + }, + { + "title": "24 game", + "type": "Waypoint", + "description": [ + "

Implement a function that takes a string of four digits as its argument, with each digit from 1 ──► 9 (inclusive) with repetitions allowed, and returns an arithmetic expression that evaluates to the number 24. If no such solution exists, return \"no solution exists.\"

", + "

Rules:

", + " Only the following operators/functions are allowed: multiplication, division, addition, subtraction", + " Division should use floating point or rational arithmetic, etc, to preserve remainders.", + " Forming multiple digit numbers from the supplied digits is disallowed. (So an answer of 12+12 when given 1, 2, 2, and 1 is wrong).", + " The order of the digits when given does not have to be preserved.", + "

Example inputs:

", + "solve24(\"4878\");", + "solve24(\"1234\");", + "solve24(\"6789\");", + "solve24(\"1127\");", + "

Example outputs (strings):

", + "(7-8/8)*4", + "3*1*4*2", + "(6*8)/(9-7)", + "(1+7)*(2+1)" + ], + "solutions": [ + "// noprotect\n\nfunction solve24 (numStr) {\n const digitsArr = numStr.split('');\n const answers = [];\n\n const digitPermutations = [];\n const operatorPermutations = [];\n\n function generateDigitPermutations (digits, permutations = []) {\n if (digits.length === 0) {\n digitPermutations.push(permutations);\n }\n else {\n for (let i = 0; i < digits.length; i++) {\n const curr = digits.slice();\n const next = curr.splice(i, 1);\n generateDigitPermutations(curr.slice(), permutations.concat(next));\n }\n }\n }\n\n function generateOperatorPermutations (permutations = []) {\n const operators = ['+', '-', '*', '/'];\n if (permutations.length === 3) {\n operatorPermutations.push(permutations);\n }\n else {\n for (let i = 0; i < operators.length; i++) {\n const curr = permutations.slice();\n curr.push(operators[i]);\n generateOperatorPermutations(curr);\n }\n }\n }\n\n generateDigitPermutations(digitsArr);\n generateOperatorPermutations();\n\n interleave();\n\n return answers[0];\n\n function interleave () {\n for (let i = 0; i < digitPermutations.length; i++) {\n for (let j = 0; j < operatorPermutations.length; j++) {\n const d = digitPermutations[i];\n const o = operatorPermutations[j];\n const perm = [\n `${d[0]}${o[0]}${d[1]}${o[1]}${d[2]}${o[2]}${d[3]}`,\n `(${d[0]}${o[0]}${d[1]})${o[1]}${d[2]}${o[2]}${d[3]}`,\n `${d[0]}${o[0]}(${d[1]}${o[1]}${d[2]})${o[2]}${d[3]}`,\n `${d[0]}${o[0]}${d[1]}${o[1]}(${d[2]}${o[2]}${d[3]})`,\n `${d[0]}${o[0]}(${d[1]}${o[1]}${d[2]}${o[2]}${d[3]})`,\n `(${d[0]}${o[0]}${d[1]}${o[1]}${d[2]})${o[2]}${d[3]}`,\n `(${d[0]}${o[0]}${d[1]})${o[1]}(${d[2]}${o[2]}${d[3]})`\n ];\n\n perm.forEach(combination => {\n const res = eval(combination);\n\n if (res === 24) {\n return answers.push(combination);\n }\n });\n }\n }\n }\n}\n" + ], + "tests": [ + { + "text": "solve24 is a function.", + "testString": "assert(typeof solve24 === 'function', 'solve24 is a function.');" + }, + { + "text": "solve24(\"4878\") should return (7-8/8)*4 or 4*(7-8/8)", + "testString": "assert(include(answers[0], solve24(testCases[0])), 'solve24(\"4878\") should return (7-8/8)*4 or 4*(7-8/8)');" + }, + { + "text": "solve24(\"1234\") should return any arrangement of 1*2*3*4", + "testString": "assert(include(answers[1], solve24(testCases[1])), 'solve24(\"1234\") should return any arrangement of 1*2*3*4');" + }, + { + "text": "solve24(\"6789\") should return (6*8)/(9-7) or (8*6)/(9-7)", + "testString": "assert(include(answers[2], solve24(testCases[2])), 'solve24(\"6789\") should return (6*8)/(9-7) or (8*6)/(9-7)');" + }, + { + "text": "solve24(\"1127\") should return a permutation of (1+7)*(1*2)", + "testString": "assert(include(answers[3], solve24(testCases[3])), 'solve24(\"1127\") should return a permutation of (1+7)*(1*2)');" + } + ], + "id": "5951e88f64ebf159166a1176", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function solve24 (numStr) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const testCases = [\n '4878',\n '1234',\n '6789',\n '1127'\n];\n\nconst answers = [\n ['(7-8/8)*4', '4*(7-8/8)', '(4-8+7)*8', '(4+7-8)*8', '(7+4-8)*8', '(7-8+4)*8', '8*(4-8+7)', '8*(4+7-8)', '8*(7+4-8)', '8*(7-8+4)'],\n ['1*2*3*4', '1*2*4*3', '1*3*2*4', '1*3*4*2', '1*4*2*3', '1*4*3*2', '2*1*3*4', '2*1*4*3', '2*3*1*4', '2*3*4*1', '2*4*3*1', '2*4*1*3', '3*1*2*4', '3*1*4*2', '3*2*1*4', '3*2*4*1', '3*4*1*2', '3*4*2*1', '4*1*2*3', '4*1*3*2', '4*2*1*3', '4*2*3*1', '4*3*1*2', '4*3*2*1', '(1+2+3)*4', '(1+3+2)*4', '(2+1+3)*4', '(2+3+1)*4', '(3+1+2)*4', '(3+2+1)*4', '4*(1+2+3)', '4*(2+1+3)', '4*(2+3+1)', '4*(3+1+2)', '4*(3+2+1)'],\n ['(6*8)/(9-7)', '(8*6)/(9-7)', '6*8/(9-7)', '8*6/(9-7)'],\n ['(1+7)*(2+1)', '(1+7)*(1+2)', '(1+2)*(1+7)', '(1+2)*(7+1)', '(2+1)*(1+7)', '(7+1)*(2+1)']\n];\n\nfunction include(ansArr, res) {\n const index = ansArr.indexOf(res);\n return index >= 0;\n}" + } + } + }, + { + "title": "9 billion names of God the integer", + "type": "Waypoint", + "description": [ + "

This task is a variation of the short story by Arthur C. Clarke.

", + "

(Solvers should be aware of the consequences of completing this task.)

", + "

In detail, to specify what is meant by a “name”:

", + "

The integer 1 has 1 name “1”.

", + "

The integer 2 has 2 names “1+1”, and “2”.

", + "

The integer 3 has 3 names “1+1+1”, “2+1”, and “3”.

", + "

The integer 4 has 5 names “1+1+1+1”, “2+1+1”, “2+2”, “3+1”, “4”.

", + "

The integer 5 has 7 names “1+1+1+1+1”, “2+1+1+1”, “2+2+1”, “3+1+1”, “3+2”, “4+1”, “5”.

", + "

This can be visualized in the following form:

", + "
",
+        "          1",
+        "        1   1",
+        "      1   1   1",
+        "    1   2   1   1",
+        "  1   2   2   1   1",
+        "1   3   3   2   1   1",
+        "
", + "

Where row $n$ corresponds to integer $n$, and each column $C$ in row $m$ from left to right corresponds to the number of names beginning with $C$.

", + "

Optionally note that the sum of the $n$-th row $P(n)$ is the integer partition function.

", + "Task", + "

Implement a function that returns the sum of the $n$-th row.

" + ], + "solutions": [ + "function numberOfNames (num) {\n const cache = [\n [1]\n ];\n for (let l = cache.length; l < num + 1; l++) {\n let Aa;\n let Mi;\n const r = [0];\n for (let x = 1; x < l + 1; x++) {\n 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]);\n }\n cache.push(r);\n }\n return cache[num][cache[num].length - 1];\n}\n" + ], + "tests": [ + { + "text": "numberOfNames is a function.", + "testString": "assert(typeof numberOfNames === 'function', 'numberOfNames is a function.');" + }, + { + "text": "numberOfNames(5) should equal 7.", + "testString": "assert.equal(numberOfNames(5), 7, 'numberOfNames(5) should equal 7.');" + }, + { + "text": "numberOfNames(12) should equal 77.", + "testString": "assert.equal(numberOfNames(12), 77, 'numberOfNames(12) should equal 77.');" + }, + { + "text": "numberOfNames(18) should equal 385.", + "testString": "assert.equal(numberOfNames(18), 385, 'numberOfNames(18) should equal 385.');" + }, + { + "text": "numberOfNames(23) should equal 1255.", + "testString": "assert.equal(numberOfNames(23), 1255, 'numberOfNames(23) should equal 1255.');" + }, + { + "text": "numberOfNames(42) should equal 53174.", + "testString": "assert.equal(numberOfNames(42), 53174, 'numberOfNames(42) should equal 53174.');" + }, + { + "text": "numberOfNames(123) should equal 2552338241.", + "testString": "assert.equal(numberOfNames(123), 2552338241, 'numberOfNames(123) should equal 2552338241.');" + } + ], + "id": "5949b579404977fbaefcd736", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function numberOfNames (num) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "ABC Problem", + "type": "Waypoint", + "description": [ + "

You are given a collection of ABC blocks (e.g., childhood alphabet blocks). There are 20 blocks with two letters on each block. A complete alphabet is guaranteed amongst all sides of the blocks. The sample collection of blocks:

", + "

(B O)

", + "

(X K)

", + "

(D Q)

", + "

(C P)

", + "

(N A)

", + "

(G T)

", + "

(R E)

", + "

(T G)

", + "

(Q D)

", + "

(F S)

", + "

(J W)

", + "

(H U)

", + "

(V I)

", + "

(A N)

", + "

(O B)

", + "

(E R)

", + "

(F S)

", + "

(L Y)

", + "

(P C)

", + "

(Z M)

", + "

Some rules to keep in mind:

", + "Once a letter on a block is used, that block cannot be used again.", + "The function should be case-insensitive.", + "

Implement a function that takes a string (word) and determines whether the word can be spelled with the given collection of blocks.

" + ], + "solutions": [ + "function canMakeWord (word) {\n const characters = 'BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY PC ZM';\n const blocks = characters.split(' ').map(pair => pair.split(''));\n\n const letters = [...word.toUpperCase()];\n let length = letters.length;\n const copy = new Set(blocks);\n\n letters.forEach(letter => {\n for (let block of copy) {\n const index = block.indexOf(letter);\n\n if (index !== -1) {\n length--;\n copy.delete(block);\n break;\n }\n }\n });\n return !length;\n}\n" + ], + "tests": [ + { + "text": "canMakeWord is a function.", + "testString": "assert(typeof canMakeWord === 'function', 'canMakeWord is a function.');" + }, + { + "text": "canMakeWord should return a boolean.", + "testString": "assert(typeof canMakeWord('hi') === 'boolean', 'canMakeWord should return a boolean.');" + }, + { + "text": "canMakeWord(\"bark\") should return true.", + "testString": "assert(canMakeWord(words[0]), 'canMakeWord(\"bark\") should return true.');" + }, + { + "text": "canMakeWord(\"BooK\") should return false.", + "testString": "assert(!canMakeWord(words[1]), 'canMakeWord(\"BooK\") should return false.');" + }, + { + "text": "canMakeWord(\"TReAT\") should return true.", + "testString": "assert(canMakeWord(words[2]), 'canMakeWord(\"TReAT\") should return true.');" + }, + { + "text": "canMakeWord(\"COMMON\") should return false.", + "testString": "assert(!canMakeWord(words[3]), 'canMakeWord(\"COMMON\") should return false.');" + }, + { + "text": "canMakeWord(\"squAD\") should return true.", + "testString": "assert(canMakeWord(words[4]), 'canMakeWord(\"squAD\") should return true.');" + }, + { + "text": "canMakeWord(\"conFUSE\") should return true.", + "testString": "assert(canMakeWord(words[5]), 'canMakeWord(\"conFUSE\") should return true.');" + } + ], + "id": "594810f028c0303b75339acc", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function canMakeWord (word) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const words = ['bark', 'BooK', 'TReAT', 'COMMON', 'squAD', 'conFUSE'];" + } + } + }, + { + "title": "Abundant, deficient and perfect number classifications", + "type": "Waypoint", + "description": [ + "

These define three classifications of positive integers based on their proper divisors.

", + "

Let $P(n)$ be the sum of the proper divisors of n where proper divisors are all positive integers n other than n itself.

", + "

If P(n) < n then n is classed as \"deficient\"

", + "

If P(n) === n then n is classed as \"perfect\"

", + "

If P(n) > n then n is classed as \"abundant\"

", + "

Example:

", + "

6 has proper divisors of 1, 2, and 3.

", + "

1 + 2 + 3 = 6, so 6 is classed as a perfect number.

", + "

Implement a function that calculates how many of the integers from 1 to 20,000 (inclusive) are in each of the three classes. Output the result as an array in the following format [deficient, perfect, abundant].

" + ], + "solutions": [ + "function getDPA (num) {\n const dpa = [1, 0, 0];\n for (let n = 2; n <= num; n += 1) {\n let ds = 1;\n const e = Math.sqrt(n);\n for (let d = 2; d < e; d += 1) {\n if (n % d === 0) {\n ds += d + (n / d);\n }\n }\n if (n % e === 0) {\n ds += e;\n }\n dpa[ds < n ? 0 : ds === n ? 1 : 2] += 1;\n }\n return dpa;\n}\n" + ], + "tests": [ + { + "text": "getDPA is a function.", + "testString": "assert(typeof getDPA === 'function', 'getDPA is a function.');" + }, + { + "text": "getDPA should return an array.", + "testString": "assert(Array.isArray(getDPA(100)), 'getDPA should return an array.');" + }, + { + "text": "getDPA return value should have a length of 3.", + "testString": "assert(getDPA(100).length === 3, 'getDPA return value should have a length of 3.');" + }, + { + "text": "getDPA(20000) should equal [15043, 4, 4953]", + "testString": "assert.deepEqual(getDPA(20000), solution, 'getDPA(20000) should equal [15043, 4, 4953]');" + } + ], + "id": "594810f028c0303b75339acd", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function getDPA (num) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const solution = [15043, 4, 4953];" + } + } + }, + { + "title": "Accumulator factory", + "type": "Waypoint", + "description": [ + "

Create a function that takes a single (numeric) argument and returns another function that is an accumulator. The returned accumulator function in turn also takes a single numeric argument, and returns the sum of all the numeric values passed in so far to that accumulator (including the initial value passed when the accumulator was created).

", + "

Rules:

", + "

Do not use global variables.

", + "

Hint:

", + "

Closures save outer state.

" + ], + "solutions": [ + "function accumulator (sum) {\n return function (n) {\n return sum += n;\n };\n}\n" + ], + "tests": [ + { + "text": "accumulator is a function.", + "testString": "assert(typeof accumulator === 'function', 'accumulator is a function.');" + }, + { + "text": "accumulator(0) should return a function.", + "testString": "assert(typeof accumulator(0) === 'function', 'accumulator(0) should return a function.');" + }, + { + "text": "accumulator(0)(2) should return a number.", + "testString": "assert(typeof accumulator(0)(2) === 'number', 'accumulator(0)(2) should return a number.');" + }, + { + "text": "Passing in the values 3, -4, 1.5, and 5 should return 5.5.", + "testString": "assert(testFn(5) === 5.5, 'Passing in the values 3, -4, 1.5, and 5 should return 5.5.');" + } + ], + "id": "594810f028c0303b75339ace", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function accumulator (sum) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const testFn = typeof accumulator(3) === 'function' && accumulator(3);\nif (testFn) {\n testFn(-4);\n testFn(1.5);\n}" + } + } + }, + { + "title": "Ackermann function", + "type": "Waypoint", + "description": [ + "

The Ackermann function is a classic example of a recursive function, notable especially because it is not a primitive recursive function. It grows very quickly in value, as does the size of its call tree.

", + "

The Ackermann function is usually defined as follows:

", + "$$A(m, n) =", + " \\begin{cases}", + " n+1 & \\mbox{if } m = 0 \\\\", + " A(m-1, 1) & \\mbox{if } m > 0 \\mbox{ and } n = 0 \\\\", + " A(m-1, A(m, n-1)) & \\mbox{if } m > 0 \\mbox{ and } n > 0.", + " \\end{cases}$$", + "

Its arguments are never negative and it always terminates. Write a function which returns the value of $A(m, n)$. Arbitrary precision is preferred (since the function grows so quickly), but not required.

" + ], + "solutions": [ + "function ack (m, n) {\n return m === 0 ? n + 1 : ack(m - 1, n === 0 ? 1 : ack(m, n - 1));\n}\n" + ], + "tests": [ + { + "text": "ack is a function.", + "testString": "assert(typeof ack === 'function', 'ack is a function.');" + }, + { + "text": "ack(0, 0) should return 1.", + "testString": "assert(ack(0, 0) === 1, 'ack(0, 0) should return 1.');" + }, + { + "text": "ack(1, 1) should return 3.", + "testString": "assert(ack(1, 1) === 3, 'ack(1, 1) should return 3.');" + }, + { + "text": "ack(2, 5) should return 13.", + "testString": "assert(ack(2, 5) === 13, 'ack(2, 5) should return 13.');" + }, + { + "text": "ack(3, 3) should return 61.", + "testString": "assert(ack(3, 3) === 61, 'ack(3, 3) should return 61.');" + } + ], + "id": "594810f028c0303b75339acf", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function ack (m, n) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Align columns", + "type": "Waypoint", + "description": [ + "

Given a text file of many lines, where fields within a line are delineated by a single $ 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.

", + "

Use the following text to test your programs:

", + "
",
+        "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.",
+        "
", + "

Note that:

", + "The example input texts lines may, or may not, have trailing dollar characters.", + "All columns should share the same alignment.", + "Consecutive space characters produced adjacent to the end of lines are insignificant for the purposes of the task.", + "Output text will be viewed in a mono-spaced font on a plain text editor or basic terminal.", + "The minimum space between columns should be computed from the text and not hard-coded.", + "It is not a requirement to add separating characters between or around columns." + ], + "solutions": [ + "const testArr = [\n 'Given$a$text$file$of$many$lines',\n 'where$fields$within$a$line$',\n 'are$delineated$by$a$single$\"dollar\"$character',\n 'write$a$program',\n 'that$aligns$each$column$of$fields$',\n 'by$ensuring$that$words$in$each$',\n 'column$are$separated$by$at$least$one$space.',\n 'Further,$allow$for$each$word$in$a$column$to$be$either$left$',\n 'justified,$right$justified',\n 'or$center$justified$within$its$column.'\n];\n\nString.prototype.repeat = function (n) { return new Array(1 + parseInt(n)).join(this); };\n\nfunction formatText (input, justification) {\n let x, y, max, cols = 0, diff, left, right;\n for (x = 0; x < input.length; x++) {\n input[x] = input[x].split('$');\n if (input[x].length > cols) {\n cols = input[x].length;\n }\n }\n for (x = 0; x < cols; x++) {\n max = 0;\n for (y = 0; y < input.length; y++) {\n if (input[y][x] && max < input[y][x].length) {\n max = input[y][x].length;\n }\n }\n for (y = 0; y < input.length; y++) {\n if (input[y][x]) {\n diff = (max - input[y][x].length) / 2;\n left = ' '.repeat(Math.floor(diff));\n right = ' '.repeat(Math.ceil(diff));\n if (justification === 'left') {\n right += left; left = '';\n }\n if (justification === 'right') {\n left += right; right = '';\n }\n input[y][x] = left + input[y][x] + right;\n }\n }\n }\n for (x = 0; x < input.length; x++) {\n input[x] = input[x].join(' ');\n }\n input = input.join('\\n');\n return input;\n}\n" + ], + "tests": [ + { + "text": "formatText is a function.", + "testString": "assert(typeof formatText === 'function', 'formatText is a function.');" + }, + { + "text": "formatText with the above input and \"right\" justification should produce the following: ", + "testString": "assert.strictEqual(formatText(testInput, 'right'), rightAligned, 'formatText with the above input and \"right\" justification should produce the following: ');" + }, + { + "text": "formatText with the above input and \"left\" justification should produce the following: ", + "testString": "assert.strictEqual(formatText(testInput, 'left'), leftAligned, 'formatText with the above input and \"left\" justification should produce the following: ');" + }, + { + "text": "formatText with the above input and \"center\" justification should produce the following: ", + "testString": "assert.strictEqual(formatText(testInput, 'center'), centerAligned, 'formatText with the above input and \"center\" justification should produce the following: ');" + } + ], + "id": "594810f028c0303b75339ad0", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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!", + "}" + ], + "head": "", + "tail": "const testInput = [\n 'Given$a$text$file$of$many$lines',\n 'where$fields$within$a$line$',\n 'are$delineated$by$a$single$\"dollar\"$character',\n 'write$a$program',\n 'that$aligns$each$column$of$fields$',\n 'by$ensuring$that$words$in$each$',\n 'column$are$separated$by$at$least$one$space.',\n 'Further,$allow$for$each$word$in$a$column$to$be$either$left$',\n 'justified,$right$justified',\n 'or$center$justified$within$its$column.'\n];\n\nconst rightAligned = ` Given a text file of many lines\n where fields within a line \n are delineated by a single \"dollar\" character\n write a program\n that aligns each column of fields \n by ensuring that words in each \n column are separated by at least one space.\n Further, allow for each word in a column to be either left \njustified, right justified\n or center justified within its column.`;\n\nconst leftAligned = `Given a text file of many lines \nwhere fields within a line \nare delineated by a single \"dollar\" character\nwrite a program \nthat aligns each column of fields \nby ensuring that words in each \ncolumn are separated by at least one space.\nFurther, allow for each word in a column to be either left \njustified, right justified\nor center justified within its column. `;\n\nconst centerAligned = ` Given a text file of many lines \n where fields within a line \n are delineated by a single \"dollar\" character\n write a program \n that aligns each column of fields \n by ensuring that words in each \n column are separated by at least one space.\n Further, allow for each word in a column to be either left \njustified, right justified\n or center justified within its column. `;" + } + } + }, + { + "title": "Amicable pairs", + "type": "Waypoint", + "description": [ + "Two integers $N$ and $M$ are said to be amicable pairs if $N \\neq M$ and the sum of the proper divisors of $N$ ($\\mathrm{sum}(\\mathrm{propDivs}(N))$) $= M$ as well as $\\mathrm{sum}(\\mathrm{propDivs}(M)) = N$.", + "Example:", + "1184 and 1210 are an amicable pair, with proper divisors:", + " 1, 2, 4, 8, 16, 32, 37, 74, 148, 296, 592 and ", + " 1, 2, 5, 10, 11, 22, 55, 110, 121, 242, 605 respectively.", + "Task:", + "Calculate and show here the Amicable pairs below 20,000 (there are eight).", + "Related tasks", + "Proper divisors", + "Abundant, deficient and perfect number classifications", + "Aliquot sequence classifications and its amicable classification." + ], + "solutions": [ + "// amicablePairsUpTo :: Int -> [(Int, Int)]\nfunction amicablePairsUpTo (maxNum) {\n return range(1, maxNum)\n .map(x => properDivisors(x)\n .reduce((a, b) => a + b, 0))\n .reduce((a, m, i, lst) => {\n const n = i + 1;\n\n return (m > n) && lst[m - 1] === n ?\n a.concat([\n [n, m]\n ]) : a;\n }, []);\n}\n\n// properDivisors :: Int -> [Int]\nfunction properDivisors (n) {\n if (n < 2) return [];\n\n const rRoot = Math.sqrt(n);\n const intRoot = Math.floor(rRoot);\n const blnPerfectSquare = rRoot === intRoot;\n const lows = range(1, intRoot)\n .filter(x => (n % x) === 0);\n\n return lows.concat(lows.slice(1)\n .map(x => n / x)\n .reverse()\n .slice(blnPerfectSquare | 0));\n}\n\n// Int -> Int -> Maybe Int -> [Int]\nfunction range (m, n, step) {\n const d = (step || 1) * (n >= m ? 1 : -1);\n\n return Array.from({\n length: Math.floor((n - m) / d) + 1\n }, (_, i) => m + (i * d));\n}\n" + ], + "tests": [ + { + "text": "amicablePairsUpTo is a function.", + "testString": "assert(typeof amicablePairsUpTo === 'function', 'amicablePairsUpTo is a function.');" + }, + { + "text": "amicablePairsUpTo(300) should return [[220,284]].", + "testString": "assert.deepEqual(amicablePairsUpTo(300), answer300, 'amicablePairsUpTo(300) should return [[220,284]].');" + }, + { + "text": "amicablePairsUpTo(3000) should return [[220,284],[1184,1210],[2620,2924]].", + "testString": "assert.deepEqual(amicablePairsUpTo(3000), answer3000, 'amicablePairsUpTo(3000) should return [[220,284],[1184,1210],[2620,2924]].');" + }, + { + "text": "amicablePairsUpTo(20000) should return [[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]].", + "testString": "assert.deepEqual(amicablePairsUpTo(20000), answer20000, 'amicablePairsUpTo(20000) should return [[220,284],[1184,1210],[2620,2924],[5020,5564],[6232,6368],[10744,10856],[12285,14595],[17296,18416]].');" + } + ], + "id": "5949b579404977fbaefcd737", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function amicablePairsUpTo (maxNum) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const answer300 = [[220, 284]];\nconst answer3000 = [\n [220, 284],\n [1184, 1210],\n [2620, 2924]\n];\nconst answer20000 = [\n [220, 284],\n [1184, 1210],\n [2620, 2924],\n [5020, 5564],\n [6232, 6368],\n [10744, 10856],\n [12285, 14595],\n [17296, 18416]\n];" + } + } + }, + { + "title": "Averages/Mode", + "type": "Waypoint", + "description": [ + "

Write a program to find the mode value of a collection.

The case where the collection is empty may be ignored. Care must be taken to handle the case where the mode is non-unique.

If it is not appropriate or possible to support a general collection, use a vector (array), if possible. If it is not appropriate or possible to support an unspecified value type, use integers.

" + ], + "solutions": [ + "function mode(arr) {\n const counter = {};\n let result = [];\n let max = 0;\n // for (const i in arr) {\n arr.forEach(el => {\n if (!(el in counter)) {\n counter[el] = 0;\n }\n counter[el]++;\n\n if (counter[el] === max) {\n result.push(el);\n }\n else if (counter[el] > max) {\n max = counter[el];\n result = [el];\n }\n });\n return result;\n}\n" + ], + "tests": [ + { + "text": "mode is a function.", + "testString": "assert(typeof mode === 'function', 'mode is a function.');" + }, + { + "text": "mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]) should equal [6]", + "testString": "assert.deepEqual(mode(arr1), [6], 'mode([1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17]) should equal [6]');" + }, + { + "text": "mode([1, 2, 4, 4, 1]) should equal [1, 4].", + "testString": "assert.deepEqual(mode(arr2).sort(), [1, 4], 'mode([1, 2, 4, 4, 1]) should equal [1, 4].');" + } + ], + "id": "594d8d0ab97724821379b1e6", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function mode (arr) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const arr1 = [1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17];\nconst arr2 = [1, 2, 4, 4, 1];" + } + } + }, + { + "title": "Averages/Pythagorean means", + "type": "Waypoint", + "description": [ + "

Compute all three of the Pythagorean means of the set of integers 1 through 10 (inclusive).

Show that $A(x_1,\\ldots,x_n) \\geq G(x_1,\\ldots,x_n) \\geq H(x_1,\\ldots,x_n)$ for this set of positive integers.

The most common of the three means, the arithmetic mean, is the sum of the list divided by its length: $ A(x_1, \\ldots, x_n) = \\frac{x_1 + \\cdots + x_n}{n}$The geometric mean is the $n$th root of the product of the list: $ G(x_1, \\ldots, x_n) = \\sqrt[n]{x_1 \\cdots x_n} $The harmonic mean is $n$ divided by the sum of the reciprocal of each item in the list: $ H(x_1, \\ldots, x_n) = \\frac{n}{\\frac{1}{x_1} + \\cdots + \\frac{1}{x_n}} $", + "

Assume the input is an ordered array of all inclusive numbers.

", + "

For the answer, please output an object in the following format:

", + "
",
+        "{",
+        "  values: {",
+        "    Arithmetic: 5.5,",
+        "    Geometric: 4.528728688116765,",
+        "    Harmonic: 3.414171521474055",
+        "  },",
+        "  test: 'is A >= G >= H ? yes'",
+        "}",
+        "
" + ], + "solutions": [ + "function pythagoreanMeans (rangeArr) {\n // arithmeticMean :: [Number] -> Number\n const arithmeticMean = xs =>\n foldl((sum, n) => sum + n, 0, xs) / length(xs);\n\n // geometricMean :: [Number] -> Number\n const geometricMean = xs =>\n raise(foldl((product, x) => product * x, 1, xs), 1 / length(xs));\n\n // harmonicMean :: [Number] -> Number\n const harmonicMean = xs =>\n length(xs) / foldl((invSum, n) => invSum + (1 / n), 0, xs);\n\n // GENERIC FUNCTIONS ------------------------------------------------------\n\n // A list of functions applied to a list of arguments\n // <*> :: [(a -> b)] -> [a] -> [b]\n const ap = (fs, xs) => //\n Array.prototype.concat(...fs.map(f => //\n Array.prototype.concat(...xs.map(x => [f(x)]))));\n\n // foldl :: (b -> a -> b) -> b -> [a] -> b\n const foldl = (f, a, xs) => xs.reduce(f, a);\n\n // length :: [a] -> Int\n const length = xs => xs.length;\n\n // mapFromList :: [(k, v)] -> Dictionary\n const mapFromList = kvs =>\n foldl((a, [k, v]) =>\n (a[(typeof k === 'string' && k)] = v, a), {}, kvs);\n\n // raise :: Num -> Int -> Num\n const raise = (n, e) => Math.pow(n, e);\n/*\n // show :: a -> String\n // show :: a -> Int -> String\n const show = (...x) =>\n JSON.stringify.apply(\n null, x.length > 1 ? [x[0], null, x[1]] : x\n );\n*/\n // zip :: [a] -> [b] -> [(a,b)]\n const zip = (xs, ys) =>\n xs.slice(0, Math.min(xs.length, ys.length))\n .map((x, i) => [x, ys[i]]);\n\n // TEST -------------------------------------------------------------------\n // mean :: Dictionary\n const mean = mapFromList(zip(\n ['Arithmetic', 'Geometric', 'Harmonic'],\n ap([arithmeticMean, geometricMean, harmonicMean], [\n rangeArr\n ])\n ));\n\n return {\n values: mean,\n test: `is A >= G >= H ? ${mean.Arithmetic >= mean.Geometric &&\n mean.Geometric >= mean.Harmonic ? 'yes' : 'no'}`\n };\n}\n" + ], + "tests": [ + { + "text": "pythagoreanMeans is a function.", + "testString": "assert(typeof pythagoreanMeans === 'function', 'pythagoreanMeans is a function.');" + }, + { + "text": "pythagoreanMeans([1, 2, ..., 10]) should equal the same output above.", + "testString": "assert.deepEqual(pythagoreanMeans(range1), answer1, 'pythagoreanMeans([1, 2, ..., 10]) should equal the same output above.');" + } + ], + "id": "594d966a1467eb84194f0086", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function pythagoreanMeans (rangeArr) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const range1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nconst answer1 = {\n values: {\n Arithmetic: 5.5,\n Geometric: 4.528728688116765,\n Harmonic: 3.414171521474055\n },\n test: 'is A >= G >= H ? yes'\n};\n" + } + } + }, + { + "title": "Averages/Root mean square", + "type": "Waypoint", + "description": [ + "

Compute the Root mean square of the numbers 1 through 10 inclusive.

", + "

The root mean square is also known by its initials RMS (or rms), and as the quadratic mean.

The RMS is calculated as the mean of the squares of the numbers, square-rooted:

", + "

$$x_{\\mathrm{rms}} = \\sqrt {{{x_1}^2 + {x_2}^2 + \\cdots + {x_n}^2} \\over n}. $$

" + ], + "solutions": [ + "function rms (arr) {\n const sumOfSquares = arr.reduce((s, x) => s + x * x, 0);\n return Math.sqrt(sumOfSquares / arr.length);\n}\n" + ], + "tests": [ + { + "text": "rms is a function.", + "testString": "assert(typeof rms === 'function', 'rms is a function.');" + }, + { + "text": "rms([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) should equal 6.2048368229954285.", + "testString": "assert.equal(rms(arr1), answer1, 'rms([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) should equal 6.2048368229954285.');" + } + ], + "id": "594da033de4190850b893874", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function rms (arr) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nconst answer1 = 6.2048368229954285;" + } + } + }, + { + "title": "Babbage problem", + "type": "Waypoint", + "description": [ + "

Charles Babbage, looking ahead to the sorts of problems his Analytical Engine would be able to solve, gave this example:

", + "
What is the smallest positive integer whose square ends in the digits 269,696?
", + "

- Babbage, letter to Lord Bowden, 1837; see Hollingdale and Tootill, Electronic Computers, second edition, 1970, p. 125.

", + "

He thought the answer might be 99,736, whose square is 9,947,269,696; but he couldn't be certain.

", + "

The task is to find out if Babbage had the right answer.

", + "

Implement a function to return the lowest integer that satisfies the Babbage problem. If Babbage was right, return Babbage's number.

" + ], + "solutions": [ + "function babbage (babbageAns, endDigits) {\n const babbageNum = Math.pow(babbageAns, 2);\n const babbageStartDigits = parseInt(babbageNum.toString().replace('269696', ''));\n let answer = 99736;\n\n // count down from this answer and save any sqrt int result. return lowest one\n for (let i = babbageStartDigits; i >= 0; i--) {\n const num = parseInt(i.toString().concat('269696'));\n const result = Math.sqrt(num);\n if (result === Math.floor(Math.sqrt(num))) {\n answer = result;\n }\n }\n\n return answer;\n}\n" + ], + "tests": [ + { + "text": "babbage is a function.", + "testString": "assert(typeof babbage === 'function', 'babbage is a function.');" + }, + { + "text": "babbage(99736, 269696) should not return 99736 (there is a smaller answer).", + "testString": "assert.equal(babbage(babbageAns, endDigits), answer, 'babbage(99736, 269696) should not return 99736 (there is a smaller answer).');" + } + ], + "id": "594db4d0dedb4c06a2a4cefd", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function babbage (babbageNum, endDigits) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const babbageAns = 99736;\nconst endDigits = 269696;\nconst answer = 25264;" + } + } + }, + { + "title": "Balanced brackets", + "type": "Waypoint", + "description": [ + "

Determine whether a generated string of brackets is balanced; that is, whether it consists entirely of pairs of opening/closing brackets (in that order), none of which mis-nest.

", + "Examples:", + "

(empty) true

", + "

[] true

", + "

][ false

", + "

[][] true

", + "

][][ false

", + "

[]][[] false

", + "

[[[[]]]] true

" + ], + "solutions": [ + "function isBalanced (str) {\n if (str === '') return true;\n let a = str;\n let b;\n do {\n b = a;\n a = a.replace(/\\[\\]/g, '');\n } while (a !== b);\n return !a;\n}\n" + ], + "tests": [ + { + "text": "isBalanced is a function.", + "testString": "assert(typeof isBalanced === 'function', 'isBalanced is a function.');" + }, + { + "text": "isBalanced(\"[]\") should return true.", + "testString": "assert(isBalanced(testCases[0]), 'isBalanced(\"[]\") should return true.');" + }, + { + "text": "isBalanced(\"]][[[][][][]][\") should return false.", + "testString": "assert(!isBalanced(testCases[1]), 'isBalanced(\"]][[[][][][]][\") should return false.');" + }, + { + "text": "isBalanced(\"[][[[[][][[[]]]]]]\") should return true.", + "testString": "assert(isBalanced(testCases[2]), 'isBalanced(\"[][[[[][][[[]]]]]]\") should return true.');" + }, + { + "text": "isBalanced(\"][\") should return true.", + "testString": "assert(!isBalanced(testCases[3]), 'isBalanced(\"][\") should return true.');" + }, + { + "text": "isBalanced(\"[[[]]]][[]\") should return true.", + "testString": "assert(!isBalanced(testCases[4]), 'isBalanced(\"[[[]]]][[]\") should return true.');" + }, + { + "text": "isBalanced(\"][[]\") should return true.", + "testString": "assert(!isBalanced(testCases[5]), 'isBalanced(\"][[]\") should return true.');" + }, + { + "text": "isBalanced(\"][[][]][[[]]\") should return true.", + "testString": "assert(!isBalanced(testCases[6]), 'isBalanced(\"][[][]][[[]]\") should return true.');" + }, + { + "text": "isBalanced(\"[[][]]][\") should return true.", + "testString": "assert(!isBalanced(testCases[7]), 'isBalanced(\"[[][]]][\") should return true.');" + }, + { + "text": "isBalanced(\"[[[]]][[]]]][][[\") should return true.", + "testString": "assert(!isBalanced(testCases[8]), 'isBalanced(\"[[[]]][[]]]][][[\") should return true.');" + }, + { + "text": "isBalanced(\"[]][[]]][[[[][]]\") should return true.", + "testString": "assert(!isBalanced(testCases[9]), 'isBalanced(\"[]][[]]][[[[][]]\") should return true.');" + }, + { + "text": "isBalanced(\"][]][[][\") should return true.", + "testString": "assert(!isBalanced(testCases[10]), 'isBalanced(\"][]][[][\") should return true.');" + }, + { + "text": "isBalanced(\"[[]][[][]]\") should return true.", + "testString": "assert(isBalanced(testCases[11]), 'isBalanced(\"[[]][[][]]\") should return true.');" + }, + { + "text": "isBalanced(\"[[]]\") should return true.", + "testString": "assert(isBalanced(testCases[12]), 'isBalanced(\"[[]]\") should return true.');" + }, + { + "text": "isBalanced(\"]][]][[]][[[\") should return true.", + "testString": "assert(!isBalanced(testCases[13]), 'isBalanced(\"]][]][[]][[[\") should return true.');" + }, + { + "text": "isBalanced(\"][]][][[\") should return true.", + "testString": "assert(!isBalanced(testCases[14]), 'isBalanced(\"][]][][[\") should return true.');" + }, + { + "text": "isBalanced(\"][][\") should return true.", + "testString": "assert(!isBalanced(testCases[15]), 'isBalanced(\"][][\") should return true.');" + }, + { + "text": "isBalanced(\"[[]]][][][[]][\") should return true.", + "testString": "assert(!isBalanced(testCases[16]), 'isBalanced(\"[[]]][][][[]][\") should return true.');" + }, + { + "text": "isBalanced(\"\") should return true.", + "testString": "assert(isBalanced(testCases[17]), 'isBalanced(\"\") should return true.');" + } + ], + "id": "594dc6c729e5700999302b45", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function isBalanced (str) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const testCases = [\n '[]',\n ']][[[][][][]][',\n '[][[[[][][[[]]]]]]',\n '][',\n '[[[]]]][[]',\n '][[]',\n '][[][]][[[]]',\n '[[][]]][',\n '[[[]]][[]]]][][[',\n '[]][[]]][[[[][]]',\n '][]][[][',\n '[[]][[][]]',\n '[[]]',\n ']][]][[]][[[',\n '][]][][[',\n '][][',\n '[[]]][][][[]][',\n ''\n];" + } + } + }, + { + "title": "Circles of given radius through two points", + "type": "Waypoint", + "description": [ + "

Given two points on a plane and a radius, usually two circles of given radius can be drawn through the points.

", + "Exceptions:", + "A radius of zero should be treated as never describing circles (except in the case where the points are coincident).", + "If the points are coincident then an infinite number of circles with the point on their circumference can be drawn, unless the radius is equal to zero as well which then collapses the circles to a point.", + "If the points form a diameter then return a single circle.", + "If the points are too far apart then no circles can be drawn.Task:", + "Implement a function that takes two points and a radius and returns the two circles through those points. For each resulting circle, provide the coordinates for the center of each circle rounded to four decimal digits. Return each coordinate as an array, and coordinates as an array of arrays.", + "For edge cases, return the following:", + "If points are on the diameter, return one point. If the radius is also zero however, return \"Radius Zero\".", + "If points are coincident, return \"Coincident point. Infinite solutions\".", + "If points are farther apart than the diameter, return \"No intersection. Points further apart than circle diameter\".", + "Sample inputs:", + "
",
+        "      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",
+        "
", + "Ref:", + "Finding the Center of a Circle from 2 Points and Radius from Math forum @ Drexel" + ], + "solutions": [ + "const hDist = (p1, p2) => Math.hypot(...p1.map((e, i) => e - p2[i])) / 2;\nconst pAng = (p1, p2) => Math.atan(p1.map((e, i) => e - p2[i]).reduce((p, c) => c / p, 1));\nconst solveF = (p, r) => t => [parseFloat((r * Math.cos(t) + p[0]).toFixed(4)), parseFloat((r * Math.sin(t) + p[1]).toFixed(4))];\nconst diamPoints = (p1, p2) => p1.map((e, i) => parseFloat((e + (p2[i] - e) / 2).toFixed(4)));\n\nfunction getCircles (...args) {\n const [p1, p2, s] = args;\n const solve = solveF(p1, s);\n const halfDist = hDist(p1, p2);\n\n let msg = [];\n switch (Math.sign(s - halfDist)) {\n case 0:\n msg = s ? diamPoints(p1, p2) :\n 'Radius Zero';\n break;\n case 1:\n if (!halfDist) {\n msg = 'Coincident point. Infinite solutions';\n }\n else {\n const theta = pAng(p1, p2);\n const theta2 = Math.acos(halfDist / s);\n [1, -1].map(e => solve(theta + e * theta2)).forEach(\n e => msg.push(e));\n }\n break;\n case -1:\n msg = 'No intersection. Points further apart than circle diameter';\n break;\n default:\n msg = 'Reached the default';\n }\n return msg;\n}\n" + ], + "tests": [ + { + "text": "getCircles is a function.", + "testString": "assert(typeof getCircles === 'function', 'getCircles is a function.');" + }, + { + "text": "getCircles([0.1234, 0.9876], [0.8765, 0.2345], 2.0) should return [[1.8631, 1.9742], [-0.8632, -0.7521]].", + "testString": "assert.deepEqual(getCircles(...testCases[0]), answers[0], 'getCircles([0.1234, 0.9876], [0.8765, 0.2345], 2.0) should return [[1.8631, 1.9742], [-0.8632, -0.7521]].');" + }, + { + "text": "getCircles([0.0000, 2.0000], [0.0000, 0.0000], 1.0) should return [0, 1]", + "testString": "assert.deepEqual(getCircles(...testCases[1]), answers[1], 'getCircles([0.0000, 2.0000], [0.0000, 0.0000], 1.0) should return [0, 1]');" + }, + { + "text": "getCircles([0.1234, 0.9876], [0.1234, 0.9876], 2.0) should return Coincident point. Infinite solutions", + "testString": "assert.deepEqual(getCircles(...testCases[2]), answers[2], 'getCircles([0.1234, 0.9876], [0.1234, 0.9876], 2.0) should return Coincident point. Infinite solutions');" + }, + { + "text": "getCircles([0.1234, 0.9876], [0.8765, 0.2345], 0.5) should return No intersection. Points further apart than circle diameter", + "testString": "assert.deepEqual(getCircles(...testCases[3]), answers[3], 'getCircles([0.1234, 0.9876], [0.8765, 0.2345], 0.5) should return No intersection. Points further apart than circle diameter');" + }, + { + "text": "getCircles([0.1234, 0.9876], [0.1234, 0.9876], 0.0) should return Radius Zero", + "testString": "assert.deepEqual(getCircles(...testCases[4]), answers[4], 'getCircles([0.1234, 0.9876], [0.1234, 0.9876], 0.0) should return Radius Zero');" + } + ], + "id": "5951815dd895584b06884620", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function getCircles (...args) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const testCases = [\n [[0.1234, 0.9876], [0.8765, 0.2345], 2.0],\n [[0.0000, 2.0000], [0.0000, 0.0000], 1.0],\n [[0.1234, 0.9876], [0.1234, 0.9876], 2.0],\n [[0.1234, 0.9876], [0.8765, 0.2345], 0.5],\n [[0.1234, 0.9876], [0.1234, 0.9876], 0.0]\n];\nconst answers = [\n [[1.8631, 1.9742], [-0.8632, -0.7521]],\n [0, 1],\n 'Coincident point. Infinite solutions',\n 'No intersection. Points further apart than circle diameter',\n 'Radius Zero'\n];" + } + } + }, + { + "title": "Closest-pair problem", + "type": "Waypoint", + "description": [ + "Task:", + "

Provide a function to find the closest two points among a set of given points in two dimensions, i.e. to solve the Closest pair of points problem in the planar case.

The straightforward solution is a O(n2) algorithm (which we can call brute-force algorithm); the pseudo-code (using indexes) could be simply:

", + "
",
+        "bruteForceClosestPair of P(1), P(2), ... P(N)",
+        "if N < 2 then",
+        "  return ∞",
+        "else",
+        "  minDistance ← |P(1) - P(2)|",
+        "  minPoints ← { P(1), P(2) }",
+        "  foreach i ∈ [1, N-1]",
+        "    foreach j ∈ [i+1, N]",
+        "      if |P(i) - P(j)| < minDistance then",
+        "        minDistance ← |P(i) - P(j)|",
+        "        minPoints ← { P(i), P(j) }",
+        "      endif",
+        "    endfor",
+        "  endfor",
+        "  return minDistance, minPoints",
+        "endif",
+        "
", + "

A better algorithm is based on the recursive divide&conquer approach, as explained also at Wikipedia's Closest pair of points problem, which is O(n log n); a pseudo-code could be:

", + "
",
+        "closestPair of (xP, yP)",
+        "  where xP is P(1) .. P(N) sorted by x coordinate, and",
+        "  yP is P(1) .. P(N) sorted by y coordinate (ascending order)",
+        "if N ≤ 3 then",
+        "  return closest points of xP using brute-force algorithm",
+        "else",
+        "  xL ← points of xP from 1 to ⌈N/2⌉",
+        "  xR ← points of xP from ⌈N/2⌉+1 to N",
+        "  xm ← xP(⌈N/2⌉)x",
+        "  yL ← { p ∈ yP : px ≤ xm }",
+        "  yR ← { p ∈ yP : px > xm }",
+        "  (dL, pairL) ← closestPair of (xL, yL)",
+        "  (dR, pairR) ← closestPair of (xR, yR)",
+        "  (dmin, pairMin) ← (dR, pairR)",
+        "  if dL < dR then",
+        "    (dmin, pairMin) ← (dL, pairL)",
+        "  endif",
+        "  yS ← { p ∈ yP : |xm - px| < dmin }",
+        "  nS ← number of points in yS",
+        "  (closest, closestPair) ← (dmin, pairMin)",
+        "  for i from 1 to nS - 1",
+        "    k ← i + 1",
+        "    while k ≤ nS and yS(k)y - yS(i)y < dmin",
+        "      if |yS(k) - yS(i)| < closest then",
+        "        (closest, closestPair) ← (|yS(k) - yS(i)|, {yS(k), yS(i)})",
+        "      endif",
+        "      k ← k + 1",
+        "    endwhile",
+        "  endfor",
+        "  return closest, closestPair",
+        "endif",
+        "
", + "References and further readings:", + " Closest pair of points problem", + " Closest Pair (McGill)", + " Closest Pair (UCSB)", + " Closest pair (WUStL)", + " Closest pair (IUPUI) ", + "

For the input, expect the argument to be an array of objects (points) with x and y members set to numbers. For the output, return an object containing the key:value pairs for distance and pair (i.e., the pair of two closest points).

" + ], + "solutions": [ + "const Point = function (x, y) {\n this.x = x;\n this.y = y;\n};\nPoint.prototype.getX = function () {\n return this.x;\n};\nPoint.prototype.getY = function () {\n return this.y;\n};\n\nconst mergeSort = function mergeSort(points, comp) {\n\tif(points.length < 2) return points;\n\n\tvar n = points.length,\n\t\ti = 0,\n\t\tj = 0,\n\t\tleftN = Math.floor(n / 2),\n\t\trightN = leftN;\n\n\tvar leftPart = mergeSort( points.slice(0, leftN), comp),\n\t\trightPart = mergeSort( points.slice(rightN), comp );\n\n\tvar sortedPart = [];\n\n\twhile((i < leftPart.length) && (j < rightPart.length)) {\n\t\tif(comp(leftPart[i], rightPart[j]) < 0) {\n\t\t\tsortedPart.push(leftPart[i]);\n\t\t\ti += 1;\n\t\t}\n\t\telse {\n\t\t\tsortedPart.push(rightPart[j]);\n\t\t\tj += 1;\n\t\t}\n\t}\n\twhile(i < leftPart.length) {\n\t\tsortedPart.push(leftPart[i]);\n\t\ti += 1;\n\t}\n\twhile(j < rightPart.length) {\n\t\tsortedPart.push(rightPart[j]);\n\t\tj += 1;\n\t}\n\treturn sortedPart;\n};\n\nconst closestPair = function _closestPair(Px, Py) {\n\tif(Px.length < 2) return { distance: Infinity, pair: [ new Point(0, 0), new Point(0, 0) ] };\n\tif(Px.length < 3) {\n\t\t//find euclid distance\n\t\tvar 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) );\n\t\treturn {\n\t\t\tdistance: d,\n\t\t\tpair: [ Px[0], Px[1] ]\n\t\t};\n\t}\n\n\tvar\tn = Px.length,\n\t\tleftN = Math.floor(n / 2),\n\t\trightN = leftN;\n\n\tvar Xl = Px.slice(0, leftN),\n\t\tXr = Px.slice(rightN),\n\t\tXm = Xl[leftN - 1],\n\t\tYl = [],\n\t\tYr = [];\n\t//separate Py\n\tfor(var i = 0; i < Py.length; i += 1) {\n\t\tif(Py[i].x <= Xm.x)\n\t\t\tYl.push(Py[i]);\n\t\telse\n\t\t\tYr.push(Py[i]);\n\t}\n\n\tvar dLeft = _closestPair(Xl, Yl),\n\t\tdRight = _closestPair(Xr, Yr);\n\n\tvar minDelta = dLeft.distance,\n\t\tclosestPair = dLeft.pair;\n\tif(dLeft.distance > dRight.distance) {\n\t\tminDelta = dRight.distance;\n\t\tclosestPair = dRight.pair;\n\t}\n\n\t//filter points around Xm within delta (minDelta)\n\tvar closeY = [];\n\tfor(i = 0; i < Py.length; i += 1) {\n\t\tif(Math.abs(Py[i].x - Xm.x) < minDelta) closeY.push(Py[i]);\n\t}\n\t//find min within delta. 8 steps max\n\tfor(i = 0; i < closeY.length; i += 1) {\n\t\tfor(var j = i + 1; j < Math.min( (i + 8), closeY.length ); j += 1) {\n\t\t\tvar 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) );\n\t\t\tif(d < minDelta) {\n\t\t\t\tminDelta = d;\n\t\t\t\tclosestPair = [ closeY[i], closeY[j] ]\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tdistance: minDelta,\n\t\tpair: closestPair\n\t};\n};\n\nfunction getClosestPair (points) {\n const sortX = function (a, b) { return (a.x < b.x) ? -1 : ((a.x > b.x) ? 1 : 0); }\n const sortY = function (a, b) { return (a.y < b.y) ? -1 : ((a.y > b.y) ? 1 : 0); }\n\n const Px = mergeSort(points, sortX);\n const Py = mergeSort(points, sortY);\n\n return closestPair(Px, Py);\n}\n" + ], + "tests": [ + { + "text": "getClosestPair is a function.", + "testString": "assert(typeof getClosestPair === 'function', 'getClosestPair is a function.');" + }, + { + "text": "Distance should be the following.", + "testString": "assert.equal(getClosestPair(points1).distance, answer1.distance, 'Distance should be the following.');" + }, + { + "text": "Points should be the following.", + "testString": "assert.deepEqual(JSON.parse(JSON.stringify(getClosestPair(points1))).pair, answer1.pair, 'Points should be the following.');" + }, + { + "text": "Distance should be the following.", + "testString": "assert.equal(getClosestPair(points2).distance, answer2.distance, 'Distance should be the following.');" + }, + { + "text": "Points should be the following.", + "testString": "assert.deepEqual(JSON.parse(JSON.stringify(getClosestPair(points2))).pair, answer2.pair, 'Points should be the following.');" + } + ], + "id": "5951a53863c8a34f02bf1bdc", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "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;", + "}" + ], + "head": "", + "tail": "const points1 = [\n\tnew Point(0.748501, 4.09624),\n\tnew Point(3.00302, 5.26164),\n\tnew Point(3.61878, 9.52232),\n\tnew Point(7.46911, 4.71611),\n\tnew Point(5.7819, 2.69367),\n\tnew Point(2.34709, 8.74782),\n\tnew Point(2.87169, 5.97774),\n\tnew Point(6.33101, 0.463131),\n\tnew Point(7.46489, 4.6268),\n\tnew Point(1.45428, 0.087596)\n];\n\nconst points2 = [\n new Point(37100, 13118),\n new Point(37134, 1963),\n new Point(37181, 2008),\n new Point(37276, 21611),\n new Point(37307, 9320)\n];\n\nconst answer1 = {\n distance: 0.0894096443343775,\n pair: [\n {\n x: 7.46489,\n y: 4.6268\n },\n {\n x: 7.46911,\n y: 4.71611\n }\n ]\n};\n\nconst answer2 = {\n distance: 65.06919393998976,\n pair: [\n {\n x: 37134,\n y: 1963\n },\n {\n x: 37181,\n y: 2008\n }\n ]\n};\n\nconst benchmarkPoints = [\n new Point(16909, 54699),\n new Point(14773, 61107),\n new Point(95547, 45344),\n new Point(95951, 17573),\n new Point(5824, 41072),\n new Point(8769, 52562),\n new Point(21182, 41881),\n new Point(53226, 45749),\n new Point(68180, 887),\n new Point(29322, 44017),\n new Point(46817, 64975),\n new Point(10501, 483),\n new Point(57094, 60703),\n new Point(23318, 35472),\n new Point(72452, 88070),\n new Point(67775, 28659),\n new Point(19450, 20518),\n new Point(17314, 26927),\n new Point(98088, 11164),\n new Point(25050, 56835),\n new Point(8364, 6892),\n new Point(37868, 18382),\n new Point(23723, 7701),\n new Point(55767, 11569),\n new Point(70721, 66707),\n new Point(31863, 9837),\n new Point(49358, 30795),\n new Point(13041, 39745),\n new Point(59635, 26523),\n new Point(25859, 1292),\n new Point(1551, 53890),\n new Point(70316, 94479),\n new Point(48549, 86338),\n new Point(46413, 92747),\n new Point(27186, 50426),\n new Point(27591, 22655),\n new Point(10905, 46153),\n new Point(40408, 84202),\n new Point(52821, 73520),\n new Point(84865, 77388),\n new Point(99819, 32527),\n new Point(34404, 75657),\n new Point(78457, 96615),\n new Point(42140, 5564),\n new Point(62175, 92342),\n new Point(54958, 67112),\n new Point(4092, 19709),\n new Point(99415, 60298),\n new Point(51090, 52158),\n new Point(48953, 58567)\n];" + } + } + }, + { + "title": "Combinations", + "type": "Waypoint", + "description": [ + "Task:", + "

Given non-negative integers m and n, generate all size m combinations of the integers from 0 (zero) to n-1 in sorted order (each combination is sorted and the entire table is sorted).

", + "Example:", + "

3 comb 5 is:

", + "
",
+        "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",
+        "
" + ], + "solutions": [ + "function combinations (m, n) {\n const nArr = [...Array(n).keys()];\n\n return (function generateCombinations (size, numArr) {\n const ret = [];\n\n for (let i = 0; i < numArr.length; i++) {\n if (size === 1) {\n ret.push([numArr[i]]);\n }\n else {\n const sub = generateCombinations(size - 1, numArr.slice(i + 1, numArr.length));\n for (let subI = 0; subI < sub.length; subI++) {\n const next = sub[subI];\n next.unshift(numArr[i]);\n ret.push(next);\n }\n }\n }\n return ret;\n }(m, nArr));\n}\n" + ], + "tests": [ + { + "text": "combinations is a function.", + "testString": "assert(typeof combinations === 'function', 'combinations is a function.');" + }, + { + "text": "combinations(3, 5) should return [[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]].", + "testString": "assert.deepEqual(combinations(testInput1[0], testInput1[1]), testOutput1, 'combinations(3, 5) should return [[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]].');" + }, + { + "text": "combinations(4, 6) should return [[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]]", + "testString": "assert.deepEqual(combinations(testInput2[0], testInput2[1]), testOutput2, 'combinations(4, 6) should return [[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]]');" + } + ], + "id": "5958469238c0d8d2632f46db", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function combinations (m, n) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const testInput1 = [3, 5];\nconst testOutput1 = [[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]];\n\nconst testInput2 = [4, 6];\nconst testOutput2 = [[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]];" + } + } + }, + { + "title": "Comma quibbling", + "type": "Waypoint", + "description": [ + "

Comma quibbling is a task originally set by Eric Lippert in his blog.

", + "Task:

Write a function to generate a string output which is the concatenation of input words from a list/sequence where:

", + "An input of no words produces the output string of just the two brace characters \"{}\".", + "An input of just one word, e.g. [\"ABC\"], produces the output string of the word inside the two braces, e.g. \"{ABC}\".", + "An input of two words, e.g. [\"ABC\", \"DEF\"], produces the output string of the two words inside the two braces with the words separated by the string \" and \", e.g. \"{ABC and DEF}\".", + "An input of three or more words, e.g. [\"ABC\", \"DEF\", \"G\", \"H\"], produces the output string of all but the last word separated by \", \" with the last word separated by \" and \" and all within braces; e.g. \"{ABC, DEF, G and H}\".", + "

Test your function with the following series of inputs showing your output here on this page:

", + "[] # (No input words).", + "[\"ABC\"]", + "[\"ABC\", \"DEF\"]", + "[\"ABC\", \"DEF\", \"G\", \"H\"]", + "

Note: Assume words are non-empty strings of uppercase characters for this task.

" + ], + "solutions": [ + "function quibble (words) {\n return \"{\" +\n words.slice(0, words.length - 1).join(\",\") +\n (words.length > 1 ? \" and \" : \"\") +\n (words[words.length - 1] || '') +\n \"}\";\n}\n" + ], + "tests": [ + { + "text": "quibble is a function.", + "testString": "assert(typeof quibble === 'function', 'quibble is a function.');" + }, + { + "text": "quibble([\"ABC\"]) should return a string.", + "testString": "assert(typeof quibble([\"ABC\"]) === 'string', 'quibble([\"ABC\"]) should return a string.');" + }, + { + "text": "quibble([]) should return \"{}\".", + "testString": "assert.equal(quibble(testCases[0]), results[0], 'quibble([]) should return \"{}\".');" + }, + { + "text": "quibble([\"ABC\"]) should return \"{ABC}\".", + "testString": "assert.equal(quibble(testCases[1]), results[1], 'quibble([\"ABC\"]) should return \"{ABC}\".');" + }, + { + "text": "quibble([\"ABC\", \"DEF\"]) should return \"{ABC and DEF}\".", + "testString": "assert.equal(quibble(testCases[2]), results[2], 'quibble([\"ABC\", \"DEF\"]) should return \"{ABC and DEF}\".');" + }, + { + "text": "quibble([\"ABC\", \"DEF\", \"G\", \"H\"]) should return \"{ABC,DEF,G and H}\".", + "testString": "assert.equal(quibble(testCases[3]), results[3], 'quibble([\"ABC\", \"DEF\", \"G\", \"H\"]) should return \"{ABC,DEF,G and H}\".');" + } + ], + "id": "596e414344c3b2872167f0fe", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function quibble (words) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const testCases = [[], [\"ABC\"], [\"ABC\", \"DEF\"], [\"ABC\", \"DEF\", \"G\", \"H\"]];\nconst results = [\"{}\", \"{ABC}\", \"{ABC and DEF}\", \"{ABC,DEF,G and H}\"];" + } + } + }, + { + "title": "Compare a list of strings", + "type": "Waypoint", + "description": [ + "

Given a list of arbitrarily many strings, implement a function for each of the following conditions:

test if they are all lexically equal", + " test if every string is lexically less than the one after it (i.e. whether the list is in strict ascending order)" + ], + "solutions": [ + "function allEqual(a) {\n let out = true;\n let i = 0;\n while (++i < a.length) {\n out = out && (a[i - 1] === a[i]);\n } return out;\n}\n\nfunction azSorted(a) {\n let out = true;\n let i = 0;\n while (++i < a.length) {\n out = out && (a[i - 1] < a[i]);\n } return out;\n}\n" + ], + "tests": [ + { + "text": "allEqual is a function.", + "testString": "assert(typeof allEqual === 'function', 'allEqual is a function.');" + }, + { + "text": "azSorted is a function.", + "testString": "assert(typeof azSorted === 'function', 'azSorted is a function.');" + }, + { + "text": "allEqual([\"AA\", \"AA\", \"AA\", \"AA\"]) returns true.", + "testString": "assert(allEqual(testCases[0]), 'allEqual([\"AA\", \"AA\", \"AA\", \"AA\"]) returns true.');" + }, + { + "text": "azSorted([\"AA\", \"AA\", \"AA\", \"AA\"]) returns false.", + "testString": "assert(!azSorted(testCases[0]), 'azSorted([\"AA\", \"AA\", \"AA\", \"AA\"]) returns false.');" + }, + { + "text": "allEqual([\"AA\", \"ACB\", \"BB\", \"CC\"]) returns false.", + "testString": "assert(!allEqual(testCases[1]), 'allEqual([\"AA\", \"ACB\", \"BB\", \"CC\"]) returns false.');" + }, + { + "text": "azSorted([\"AA\", \"ACB\", \"BB\", \"CC\"]) returns true.", + "testString": "assert(azSorted(testCases[1]), 'azSorted([\"AA\", \"ACB\", \"BB\", \"CC\"]) returns true.');" + }, + { + "text": "allEqual([]) returns true.", + "testString": "assert(allEqual(testCases[2]), 'allEqual([]) returns true.');" + }, + { + "text": "azSorted([]) returns true.", + "testString": "assert(azSorted(testCases[2]), 'azSorted([]) returns true.');" + }, + { + "text": "allEqual([\"AA\"]) returns true.", + "testString": "assert(allEqual(testCases[3]), 'allEqual([\"AA\"]) returns true.');" + }, + { + "text": "azSorted([\"AA\"]) returns true.", + "testString": "assert(azSorted(testCases[3]), 'azSorted([\"AA\"]) returns true.');" + }, + { + "text": "allEqual([\"BB\", \"AA\"]) returns false.", + "testString": "assert(!allEqual(testCases[4]), 'allEqual([\"BB\", \"AA\"]) returns false.');" + }, + { + "text": "azSorted([\"BB\", \"AA\"]) returns false.", + "testString": "assert(!azSorted(testCases[4]), 'azSorted([\"BB\", \"AA\"]) returns false.');" + } + ], + "id": "596e457071c35c882915b3e4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function allEqual (arr) {", + " // Good luck!", + " return true;", + "}", + "", + "function azSorted (arr) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const testCases = [['AA', 'AA', 'AA', 'AA'], ['AA', 'ACB', 'BB', 'CC'], [], ['AA'], ['BB', 'AA']];" + } + } + }, + { + "title": "Convert seconds to compound duration", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement a function which:

", + "takes a positive integer representing a duration in seconds as input (e.g., 100), and", + "returns a string which shows the same duration decomposed into weeks, days, hours, minutes, and seconds as detailed below (e.g., \"1 min, 40 sec\").", + "

Demonstrate that it passes the following three test-cases:

Test Cases

", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "
input numberoutput number
72592 hr, 59 sec
864001 d
60000009 wk, 6 d, 10 hr, 40 min
", + "

Details

", + "The following five units should be used:", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "
unitsuffix used in outputconversion
weekwk1 week = 7 days
dayd1 day = 24 hours
hourhr1 hour = 60 minutes
minutemin1 minute = 60 seconds
secondsec
", + "However, only include quantities with non-zero values in the output (e.g., return \"1 d\" and not \"0 wk, 1 d, 0 hr, 0 min, 0 sec\").Give larger units precedence over smaller ones as much as possible (e.g., return 2 min, 10 sec and not 1 min, 70 sec or 130 sec)Mimic the formatting shown in the test-cases (quantities sorted from largest unit to smallest and separated by comma+space; value and unit of each quantity separated by space).", + "


" + ], + "solutions": [ + "function convertSeconds (sec) {\n const localNames = ['wk', 'd', 'hr', 'min', 'sec'];\n // compoundDuration :: [String] -> Int -> String\n const compoundDuration = (labels, intSeconds) =>\n weekParts(intSeconds)\n .map((v, i) => [v, labels[i]])\n .reduce((a, x) =>\n a.concat(x[0] ? [`${x[0]} ${x[1] || '?'}`] : []), []\n )\n .join(', ');\n\n // weekParts :: Int -> [Int]\n const weekParts = intSeconds => [0, 7, 24, 60, 60]\n .reduceRight((a, x) => {\n const r = a.rem;\n const mod = x !== 0 ? r % x : r;\n\n return {\n rem: (r - mod) / (x || 1),\n parts: [mod].concat(a.parts)\n };\n }, {\n rem: intSeconds,\n parts: []\n })\n .parts;\n\n return compoundDuration(localNames, sec);\n}\n" + ], + "tests": [ + { + "text": "convertSeconds is a function.", + "testString": "assert(typeof convertSeconds === 'function', 'convertSeconds is a function.');" + }, + { + "text": "convertSeconds(7259) should return 2 hr, 59 sec.", + "testString": "assert.equal(convertSeconds(testCases[0]), results[0], 'convertSeconds(7259) should return 2 hr, 59 sec.');" + }, + { + "text": "convertSeconds(86400) should return 1 d.", + "testString": "assert.equal(convertSeconds(testCases[1]), results[1], 'convertSeconds(86400) should return 1 d.');" + }, + { + "text": "convertSeconds(6000000) should return 9 wk, 6 d, 10 hr, 40 min.", + "testString": "assert.equal(convertSeconds(testCases[2]), results[2], 'convertSeconds(6000000) should return 9 wk, 6 d, 10 hr, 40 min.');" + } + ], + "id": "596fd036dc1ab896c5db98b1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function convertSeconds (sec) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const testCases = [7259, 86400, 6000000];\nconst results = ['2 hr, 59 sec', '1 d', '9 wk, 6 d, 10 hr, 40 min'];" + } + } + }, + { + "title": "Count occurrences of a substring", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a function, or show a built-in function, to count the number of non-overlapping occurrences of a substring inside a string.

The function should take two arguments:

", + "the first argument being the string to search, and", + "the second a substring to be searched for.", + "

It should return an integer count.

", + "

The matching should yield the highest number of non-overlapping matches.

In general, this essentially means matching from left-to-right or right-to-left.

" + ], + "solutions": [ + "function countSubstring(str, subStr) {\n const escapedSubStr = subStr.replace(/[.+*?^$[\\]{}()|/]/g, '\\\\$&');\n const matches = str.match(new RegExp(escapedSubStr, 'g'));\n return matches ? matches.length : 0;\n}\n" + ], + "tests": [ + { + "text": "countSubstring is a function.", + "testString": "assert(typeof countSubstring === 'function', 'countSubstring is a function.');" + }, + { + "text": "countSubstring(\"the three truths\", \"th\") should return 3.", + "testString": "assert.equal(countSubstring(testCases[0], searchString[0]), results[0], 'countSubstring(\"the three truths\", \"th\") should return 3.');" + }, + { + "text": "countSubstring(\"ababababab\", \"abab\") should return 2.", + "testString": "assert.equal(countSubstring(testCases[1], searchString[1]), results[1], 'countSubstring(\"ababababab\", \"abab\") should return 2.');" + }, + { + "text": "countSubstring(\"abaabba*bbaba*bbab\", \"a*b\") should return 2.", + "testString": "assert.equal(countSubstring(testCases[2], searchString[2]), results[2], 'countSubstring(\"abaabba*bbaba*bbab\", \"a*b\") should return 2.');" + } + ], + "id": "596fda99c69f779975a1b67d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function countSubstring (str, subStr) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const testCases = ['the three truths', 'ababababab', 'abaabba*bbaba*bbab'];\nconst searchString = ['th', 'abab', 'a*b'];\nconst results = [3, 2, 2];" + } + } + }, + { + "title": "Count the coins", + "type": "Waypoint", + "description": [ + "

There are four types of common coins in US currency:

", + "quarters (25 cents)", + "dimes (10 cents)", + "nickels (5 cents), and ", + "pennies (1 cent) ", + "

There are six ways to make change for 15 cents:

", + "A dime and a nickel ", + "A dime and 5 pennies", + "3 nickels", + "2 nickels and 5 pennies", + "A nickel and 10 pennies", + "15 pennies", + "Task:", + "

Implement a function to determine how many ways there are to make change for a dollar using these common coins? (1 dollar = 100 cents).

", + "Reference:", + " an algorithm from MIT Press. " + ], + "solutions": [ + "function countCoins () {\n let t = 100;\n const operands = [1, 5, 10, 25];\n const targetsLength = t + 1;\n const operandsLength = operands.length;\n t = [1];\n\n for (let a = 0; a < operandsLength; a++) {\n for (let b = 1; b < targetsLength; b++) {\n // initialise undefined target\n t[b] = t[b] ? t[b] : 0;\n\n // accumulate target + operand ways\n t[b] += (b < operands[a]) ? 0 : t[b - operands[a]];\n }\n }\n\n return t[targetsLength - 1];\n}\n" + ], + "tests": [ + { + "text": "countCoins is a function.", + "testString": "assert(typeof countCoins === 'function', 'countCoins is a function.');" + }, + { + "text": "countCoints() should return 242.", + "testString": "assert.equal(countCoins(), 242, 'countCoints() should return 242.');" + } + ], + "id": "59713bd26bdeb8a594fb9413", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function countCoins () {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Cramer's rule", + "type": "Waypoint", + "description": [ + "

In linear algebra, Cramer's rule is an explicit formula for the solution of a system of linear equations with as many equations as unknowns, valid whenever the system has a unique solution. It expresses the solution in terms of the determinants of the (square) coefficient matrix and of matrices obtained from it by replacing one column by the vector of right hand sides of the equations.

", + "

Given

", + "

", + "

$\\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{red}d_3}\\end{matrix}\\right.$

", + "

which in matrix format is

", + "

$\\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{red}d_1} \\\\ {\\color{red}d_2} \\\\ {\\color{red}d_3} \\end{bmatrix}.$

", + "

Then the values of $x, y$ and $z$ can be found as follows:

", + "

$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}} {\\begin{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{red}d_1} \\\\ a_2 & b_2 & {\\color{red}d_2} \\\\ a_3 & b_3 & {\\color{red}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} }.$

", + "
", + "Task", + "

Given the following system of equations:

", + "$\\begin{cases}", + "2w-x+5y+z=-3 \\\\", + "3w+2x+2y-6z=-32 \\\\", + "w+3x+3y-z=-47 \\\\", + "5w-2x-3y+3z=49 \\\\", + "\\end{cases}$", + "

", + "

solve for $w$, $x$, $y$ and $z$, using Cramer's rule.

" + ], + "solutions": [ + "/**\n * Compute Cramer's Rule\n * @param {array} matrix x,y,z, etc. terms\n * @param {array} freeTerms\n * @return {array} solution for x,y,z, etc.\n */\nfunction cramersRule(matrix, freeTerms) {\n const det = detr(matrix);\n const returnArray = [];\n let i;\n\n for (i = 0; i < matrix[0].length; i++) {\n const tmpMatrix = insertInTerms(matrix, freeTerms, i);\n returnArray.push(detr(tmpMatrix) / det);\n }\n return returnArray;\n}\n\n/**\n * Inserts single dimensional array into\n * @param {array} matrix multidimensional array to have ins inserted into\n * @param {array} ins single dimensional array to be inserted vertically into matrix\n * @param {array} at zero based offset for ins to be inserted into matrix\n * @return {array} New multidimensional array with ins replacing the at column in matrix\n */\nfunction insertInTerms(matrix, ins, at) {\n const tmpMatrix = clone(matrix);\n let i;\n for (i = 0; i < matrix.length; i++) {\n tmpMatrix[i][at] = ins[i];\n }\n return tmpMatrix;\n}\n/**\n * Compute the determinate of a matrix. No protection, assumes square matrix\n * function borrowed, and adapted from MIT Licensed numericjs library (www.numericjs.com)\n * @param {array} m Input Matrix (multidimensional array)\n * @return {number} result rounded to 2 decimal\n */\nfunction detr(m) {\n let ret = 1;\n let j;\n let k;\n const A = clone(m);\n const n = m[0].length;\n let alpha;\n\n for (j = 0; j < n - 1; j++) {\n k = j;\n for (let i = j + 1; i < n; i++) { if (Math.abs(A[i][j]) > Math.abs(A[k][j])) { k = i; } }\n if (k !== j) {\n const temp = A[k]; A[k] = A[j]; A[j] = temp;\n ret *= -1;\n }\n const Aj = A[j];\n for (let i = j + 1; i < n; i++) {\n const Ai = A[i];\n alpha = Ai[j] / Aj[j];\n for (k = j + 1; k < n - 1; k += 2) {\n const k1 = k + 1;\n Ai[k] -= Aj[k] * alpha;\n Ai[k1] -= Aj[k1] * alpha;\n }\n if (k !== n) { Ai[k] -= Aj[k] * alpha; }\n }\n if (Aj[j] === 0) { return 0; }\n ret *= Aj[j];\n }\n return Math.round(ret * A[j][j] * 100) / 100;\n}\n\n/**\n * Clone two dimensional Array using ECMAScript 5 map function and EcmaScript 3 slice\n * @param {array} m Input matrix (multidimensional array) to clone\n * @return {array} New matrix copy\n */\nfunction clone(m) {\n return m.map(a => a.slice());\n}\n" + ], + "tests": [ + { + "text": "cramersRule is a function.", + "testString": "assert(typeof cramersRule === 'function', 'cramersRule is a function.');" + }, + { + "text": "cramersRule([[2, -1, 5, 1], [3, 2, 2, -6], [1, 3, 3, -1], [5, -2, -3, 3]], [-3, -32, -47, 49]) should return [2, -12, -4, 1].", + "testString": "assert.deepEqual(cramersRule(matrices[0], freeTerms[0]), answers[0], 'cramersRule([[2, -1, 5, 1], [3, 2, 2, -6], [1, 3, 3, -1], [5, -2, -3, 3]], [-3, -32, -47, 49]) should return [2, -12, -4, 1].');" + }, + { + "text": "cramersRule([[3, 1, 1], [2, 2, 5], [1, -3, -4]], [3, -1, 2]) should return [1, 1, -1].", + "testString": "assert.deepEqual(cramersRule(matrices[1], freeTerms[1]), answers[1], 'cramersRule([[3, 1, 1], [2, 2, 5], [1, -3, -4]], [3, -1, 2]) should return [1, 1, -1].');" + } + ], + "id": "59713da0a428c1a62d7db430", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function cramersRule (matrix, freeTerms) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const matrices = [\n [\n [2, -1, 5, 1],\n [3, 2, 2, -6],\n [1, 3, 3, -1],\n [5, -2, -3, 3]\n ],\n [\n [3, 1, 1],\n [2, 2, 5],\n [1, -3, -4]\n ]\n];\nconst freeTerms = [[-3, -32, -47, 49], [3, -1, 2]];\n\nconst answers = [[2, -12, -4, 1], [1, 1, -1]];" + } + } + }, + { + "title": "Date format", + "type": "Waypoint", + "description": [ + "Task:", + "

Return an array with the current date in the formats:

", + "

- 2007-11-23 and

", + "

- Sunday, November 23, 2007

", + "

Example output: ['2007-11-23', 'Sunday, November 23, 2007']

" + ], + "solutions": [ + "function getDateFormats () {\n const date = new Date();\n const weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\n const fmt1 = `${date.getFullYear()}-${(1 + date.getMonth())}-${date.getDate()}`;\n const fmt2 = `${weekdays[date.getDay()]}, ${months[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;\n return [fmt1, fmt2];\n}\n" + ], + "tests": [ + { + "text": "getDateFormats is a function.", + "testString": "assert(typeof getDateFormats === 'function', 'getDateFormats is a function.');" + }, + { + "text": "Should return an object.", + "testString": "assert(Array.isArray(getDateFormats()), 'Should return an Array.');" + }, + { + "text": "Should returned an array with 2 elements.", + "testString": "assert(getDateFormats().length === 2, 'Should returned an array with 2 elements.');" + }, + { + "text": "Should return todays date in the correct format. ", + "testString": "assert.deepEqual(getDateFormats(), dates, equalsMessage);" + } + ], + "id": "59669d08d75b60482359409f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function getDateFormats () {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const getDateSolution = () => {\n const date = new Date();\n const weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\n const fmt1 = `${date.getFullYear()}-${(1 + date.getMonth())}-${date.getDate()}`;\n const fmt2 = `${weekdays[date.getDay()]}, ${months[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;\n return [fmt1, fmt2];\n};\n\nconst dates = getDateSolution();\nconst equalsMessage = `getDataFormats() should return [\"${dates[0]}\", \"${dates[1]}\"].`;" + } + } + }, + { + "title": "Date manipulation", + "type": "Waypoint", + "description": [ + "Task:", + "

Given a date string in EST, output the given date as a string with 12 hours added to the time.

", + "

Time zone should be preserved.

", + "

Example input:

", + "

\"March 7 2009 7:30pm EST\"

", + "

Example output:

", + "

\"March 8 2009 7:30am EST\"

" + ], + "solutions": [ + "function add12Hours (dateString) {\n const months = ['January', 'February', 'March', 'April', 'May', 'June',\n 'July', 'August', 'September', 'October', 'November', 'December'];\n // Get the parts of the string\n const parts = dateString.split(' ');\n const month = months.indexOf(parts[0]);\n const day = parseInt(parts[1], 10);\n const year = parseInt(parts[2], 10);\n const time = parts[3].split(':');\n let hours = parseInt(time[0], 10);\n if (time[1].slice(-2) === 'pm') {\n hours += 12;\n }\n const minutes = parseInt(time[1].slice(0, -2), 10);\n\n // Create a date with given parts, and updated hours\n const date = new Date();\n date.setFullYear(year, month, day);\n date.setHours(hours + 12); // Add 12 hours\n date.setMinutes(minutes);\n\n let hoursOutput = date.getHours();\n let abbreviation = 'am';\n if (hoursOutput > 12) {\n hoursOutput -= 12;\n abbreviation = 'pm';\n }\n\n return `${months[date.getMonth()]} ${date.getDate()} ${date.getFullYear()} ${hoursOutput}:${date.getMinutes()}${abbreviation} EST`;\n}\n" + ], + "tests": [ + { + "text": "add12Hours is a function.", + "testString": "assert(typeof add12Hours === 'function', 'add12Hours is a function.');" + }, + { + "text": "add12Hours(dateString) should return a string.", + "testString": "assert(typeof add12Hours(tests[0]) === 'string', 'add12Hours(dateString) should return a string.');" + }, + { + "text": "add12Hours(\"' + tests[0] + '\") should return \"' + answers[0] + '\"", + "testString": "assert(add12Hours(tests[0]) === answers[0], 'add12Hours(\"' + tests[0] + '\") should return \"' + answers[0] + '\"');" + }, + { + "text": "Should handel day change. add12Hours(\"' + tests[1] + '\") should return \"' + answers[1] + '\"", + "testString": "assert(add12Hours(tests[1]) === answers[1], 'Should handel day change. add12Hours(\"' + tests[1] + '\") should return \"' + answers[1] + '\"');" + }, + { + "text": "Should handel month change in a leap years. add12Hours(\"' + tests[2] + '\") should return \"' + answers[2] + '\"", + "testString": "assert(add12Hours(tests[2]) === answers[2], 'Should handel month change in a leap years. add12Hours(\"' + tests[2] + '\") should return \"' + answers[2] + '\"');" + }, + { + "text": "Should handel month change in a common years. add12Hours(\"' + tests[3] + '\") should return \"' + answers[3] + '\"", + "testString": "assert(add12Hours(tests[3]) === answers[3], 'Should handel month change in a common years. add12Hours(\"' + tests[3] + '\") should return \"' + answers[3] + '\"');" + }, + { + "text": "Should handel year change. add12Hours(\"' + tests[4] + '\") should return \"' + answers[4] + '\"", + "testString": "assert(add12Hours(tests[4]) === answers[4], 'Should handel year change. add12Hours(\"' + tests[4] + '\") should return \"' + answers[4] + '\"');" + } + ], + "id": "5966c21cf732a95f1b67dd28", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function add12Hours (dateString) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const tests = [\n 'January 17 2017 11:43am EST',\n 'March 7 2009 7:30pm EST',\n 'February 29 2004 9:15pm EST',\n 'February 28 1999 3:15pm EST',\n 'December 31 2020 1:45pm EST'\n];\nconst answers = [\n 'January 17 2017 11:43pm EST',\n 'March 8 2009 7:30am EST',\n 'March 1 2004 9:15am EST',\n 'March 1 1999 3:15am EST',\n 'January 1 2021 1:45am EST'\n];" + } + } + }, + { + "title": "Day of the week", + "type": "Waypoint", + "description": [ + "

A company decides that whenever Xmas falls on a Sunday they will give their workers all extra paid holidays so that, together with any public holidays, workers will not have to work the following week (between the 25th of December and the first of January).

", + "

Task:

", + "

Write a function that takes a start year and an end year and return an array of all the years where the 25th of December will be a Sunday.

" + ], + "solutions": [ + "function findXmasSunday (start, end) {\n const xmasSunday = [];\n for (let year = start; year <= end; year++) {\n const xmas = new Date(year, 11, 25);\n if (xmas.getDay() === 0) {\n xmasSunday.push(year);\n }\n }\n return xmasSunday;\n}\n" + ], + "tests": [ + { + "text": "findXmasSunday is a function.", + "testString": "assert(typeof findXmasSunday === 'function', 'findXmasSunday is a function.');" + }, + { + "text": "findChristmasSunday(2000, 2100) should return an array.", + "testString": "assert(typeof findXmasSunday(2000, 2100) === 'object', 'findChristmasSunday(2000, 2100) should return an array.');" + }, + { + "text": "findChristmasSunday(2008, 2121 should return [1977, 1983, 1988, 1994, 2005, 2011, 2016]", + "testString": "assert.deepEqual(findXmasSunday(1970, 2017), firstSolution, 'findChristmasSunday(2008, 2121 should return [1977, 1983, 1988, 1994, 2005, 2011, 2016]');" + }, + { + "text": "findChristmasSunday(2008, 2121 should return [2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]", + "testString": "assert.deepEqual(findXmasSunday(2008, 2121), secondSolution, 'findChristmasSunday(2008, 2121 should return [2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118]');" + } + ], + "id": "5966f99c45e8976909a85575", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function findXmasSunday (start, end) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const firstSolution = [1977, 1983, 1988, 1994, 2005, 2011, 2016];\nconst secondSolution = [2011, 2016, 2022, 2033, 2039, 2044, 2050, 2061, 2067, 2072, 2078, 2089, 2095, 2101, 2107, 2112, 2118];" + } + } + }, + { + "title": "Deal cards for FreeCell", + "type": "Waypoint", + "description": [ + "

Free Cell is the solitaire card game that Paul Alfille introduced to the PLATO system in 1978. Jim Horne, at Microsoft, changed the name to FreeCell and reimplemented the game for DOS, then Windows.

", + "

This version introduced 32000 numbered deals. (The FreeCell FAQ tells this history.)

As the game became popular, Jim Horne disclosed the algorithm, and other implementations of FreeCell began to reproduce the Microsoft deals.

", + "

These deals are numbered from 1 to 32000.

", + "

Newer versions from Microsoft have 1 million deals, numbered from 1 to 1000000; some implementations allow numbers outside that range.

The algorithm uses this linear congruential generator from Microsoft C:

$state_{n + 1} \\equiv 214013 \\times state_n + 2531011 \\pmod{2^{31}}$", + "$rand_n = state_n \\div 2^{16}$", + "$rand_n$ is in range 0 to 32767.", + "

The algorithm follows:

Seed the RNG with the number of the deal.", + "Create an array of 52 cards: Ace of Clubs, Ace of Diamonds, Ace of Hearts, Ace of Spades, 2 of Clubs, 2 of Diamonds, and so on through the ranks: Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King. The array indexes are 0 to 51, with Ace of Clubs at 0, and King of Spades at 51.", + "Until the array is empty:", + " Choose a random card at index ≡ next random number (mod array length). ", + " Swap this random card with the last card of the array.", + " Remove this random card from the array. (Array length goes down by 1.)", + " Deal this random card.", + "Deal all 52 cards, face up, across 8 columns. The first 8 cards go in 8 columns, the next 8 cards go on the first 8 cards, and so on.", + "Example:", + "

Order to deal cards

", + "

 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

", + "

Game #1

", + "

[",
+        "['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']",
+        "]

", + "

Game #617

", + "

[",
+        "['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']",
+        "]

", + "Task:", + "

Write a function to take a deal number and deal cards in the same order as this algorithm.

", + "

The function must return a two dimentional array representing the FreeCell board.

", + "

Deals can also be checked against FreeCell solutions to 1000000 games.

", + "

(Summon a video solution, and it displays the initial deal.)

" + ], + "solutions": [ + "// RNG\nfunction FreeCellRNG (seed) {\n return {\n lastNum: seed,\n next() {\n this.lastNum = ((214013 * this.lastNum) + 2531011) % (Math.pow(2, 31));\n return this.lastNum >> 16;\n }\n };\n}\n// Get cards\nfunction getDeck() {\n const ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'];\n const suits = ['C', 'D', 'H', 'S'];\n const cards = [];\n for (let i = 0; i < ranks.length; i += 1) {\n for (let j = 0; j < suits.length; j += 1) {\n cards.push(`${ranks[i]}${suits[j]}`);\n }\n }\n return cards;\n}\nfunction dealFreeCell(seed) {\n const rng = FreeCellRNG(seed);\n const deck = getDeck();\n\n const deltCards = [[], [], [], [], [], [], []];\n let currentColumn = 0;\n let currentRow = 0;\n\n let rand;\n let temp;\n let card;\n while (deck.length > 0) {\n // Choose a random card\n rand = rng.next() % deck.length;\n\n // Swap this random card with the last card in the array\n temp = deck[deck.length - 1];\n deck[deck.length - 1] = deck[rand];\n deck[rand] = temp;\n\n // Remove this card from the array\n card = deck.pop();\n\n // Deal this card\n deltCards[currentRow].push(card);\n currentColumn += 1;\n if (currentColumn === 8) {\n currentColumn = 0;\n currentRow += 1;\n }\n }\n\n return deltCards;\n}\n" + ], + "tests": [ + { + "text": "dealFreeCell is a function.", + "testString": "assert(typeof dealFreeCell === 'function', 'dealFreeCell is a function.');" + }, + { + "text": "dealFreeCell(seed) should return an object.", + "testString": "assert(typeof dealFreeCell(1) === 'object', 'dealFreeCell(seed) should return an object.');" + }, + { + "text": "dealFreeCell(seed) should return an array of length 7.", + "testString": "assert(dealFreeCell(1).length === 7, 'dealFreeCell(seed) should return an array of length 7.');" + }, + { + "text": "dealFreeCell(1) should return an array identical to example \"Game #1\"", + "testString": "assert.deepEqual(dealFreeCell(1), game1, 'dealFreeCell(1) should return an array identical to example \"Game #1\"');" + }, + { + "text": "dealFreeCell(617) should return an array identical to example \"Game #617\"", + "testString": "assert.deepEqual(dealFreeCell(617), game617, 'dealFreeCell(617) should return an array identical to example \"Game #617\"');" + } + ], + "id": "59694356a6e7011f7f1c5f4e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function dealFreeCell (seed) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const replaceThis = 3;\nconst game1 = [\n ['JD', '2D', '9H', 'JC', '5D', '7H', '7C', '5H'],\n ['KD', 'KC', '9S', '5S', 'AD', 'QC', 'KH', '3H'],\n ['2S', 'KS', '9D', 'QD', 'JS', 'AS', 'AH', '3C'],\n ['4C', '5C', 'TS', 'QH', '4H', 'AC', '4D', '7S'],\n ['3S', 'TD', '4S', 'TH', '8H', '2C', 'JH', '7D'],\n ['6D', '8S', '8D', 'QS', '6C', '3D', '8C', 'TC'],\n ['6S', '9C', '2H', '6H']\n];\nconst game617 = [\n ['7D', 'AD', '5C', '3S', '5S', '8C', '2D', 'AH'],\n ['TD', '7S', 'QD', 'AC', '6D', '8H', 'AS', 'KH'],\n ['TH', 'QC', '3H', '9D', '6S', '8D', '3D', 'TC'],\n ['KD', '5H', '9S', '3C', '8S', '7H', '4D', 'JS'],\n ['4C', 'QS', '9C', '9H', '7C', '6H', '2C', '2S'],\n ['4S', 'TS', '2H', '5D', 'JC', '6C', 'JH', 'QH'],\n ['JD', 'KS', 'KC', '4H']\n];" + } + } + }, + { + "title": "Deepcopy", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a function that returns a deep copy of a given object.

", + "

The copy must not be the same object that was given.

", + "

This task will not test for:

", + "Objects with properties that are functions", + "Date objects or object with properties that are Date objects", + "RegEx or object with properties that are RegEx objects", + "Prototype copying" + ], + "null": [], + "solutions": [ + "function deepcopy(obj) {\n return JSON.parse(JSON.stringify(obj));\n}\n\n" + ], + "tests": [ + { + "text": "deepcopy should be a function.", + "testString": "assert(typeof deepcopy === 'function', 'deepcopy should be a function.');" + }, + { + "text": "deepcopy({test: \"test\"}) should return an object.", + "testString": "assert(typeof deepcopy(obj1) === 'object', 'deepcopy({test: \"test\"}) should return an object.');" + }, + { + "text": "Should not return the same object that was provided.", + "testString": "assert(deepcopy(obj2) != obj2, 'Should not return the same object that was provided.');" + }, + { + "text": "When passed an object containing an array, should return a deep copy of the object.", + "testString": "assert.deepEqual(deepcopy(obj2), obj2, 'When passed an object containing an array, should return a deep copy of the object.');" + }, + { + "text": "When passed an object containing another object, should return a deep copy of the object.", + "testString": "assert.deepEqual(deepcopy(obj3), obj3, 'When passed an object containing another object, should return a deep copy of the object.');" + } + ], + "id": "596a8888ab7c01048de257d5", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function deepcopy (obj) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const obj1 = { test: 'test' };\nconst obj2 = {\n t: 'test',\n a: ['an', 'array']\n};\nconst obj3 = {\n t: 'try',\n o: obj2\n};" + } + } + }, + { + "title": "Define a primitive data type", + "type": "Waypoint", + "description": [ + "Task:", + "

Define a type that behaves like an integer but has a lowest valid value of 1 and a highest valid value of 10.

", + "Errors:", + "If you try to instantiate a Num with a value outside of 1 - 10", + "it should throw a TypeError with an error message of 'Out of range'.", + "If you try to instantiate a Num with a value that is not a number", + "it should throw a TypeError with an error message of 'Not a Number'." + ], + "solutions": [ + "function Num(n) {\n const num = Math.floor(n);\n if (isNaN(num)) {\n throw new TypeError('Not a Number');\n }\n if (num < 1 || num > 10) {\n throw new TypeError('Out of range');\n }\n\n this._value = num;\n}\nNum.prototype.valueOf = function() { return this._value; };\nNum.prototype.toString = function () { return this._value.toString(); };\n\nfunction throws(func, errorType, msg) {\n let hasThrown = false;\n let errorMsg = '';\n let correctType = false;\n try {\n func();\n }\n catch (e) {\n hasThrown = true;\n errorMsg = e.message;\n if (e instanceof errorType) {\n correctType = true;\n }\n }\n return hasThrown && correctType && msg === errorMsg;\n}\n" + ], + "tests": [ + { + "text": "Num should be a function.", + "testString": "assert(typeof Num === 'function', 'Num should be a function.');" + }, + { + "text": "new Num(4) should return an object.", + "testString": "assert(typeof (new Num(4)) === 'object', 'new Num(4) should return an object.');" + }, + { + "text": "new Num(\\'test\\') should throw a TypeError with message \\'Not a Number\\'.", + "testString": "assert(throws(() => new Num('test'), TypeError, 'Not a Number'), 'new Num(\\'test\\') should throw a TypeError with message \\'Not a Number\\'.');" + }, + { + "text": "new Num(0) should throw a TypeError with message \\'Out of range\\'.", + "testString": "assert(throws(() => new Num(0), TypeError, 'Out of range'), 'new Num(0) should throw a TypeError with message \\'Out of range\\'.');" + }, + { + "text": "new Num(-5) should throw a TypeError with message \\'Out of range\\'.", + "testString": "assert(throws(() => new Num(-5), TypeError, 'Out of range'), 'new Num(-5) should throw a TypeError with message \\'Out of range\\'.');" + }, + { + "text": "new Num(10) should throw a TypeError with message \\'Out of range\\'.", + "testString": "assert(throws(() => new Num(11), TypeError, 'Out of range'), 'new Num(10) should throw a TypeError with message \\'Out of range\\'.');" + }, + { + "text": "new Num(20) should throw a TypeError with message \\'Out of range\\'.", + "testString": "assert(throws(() => new Num(20), TypeError, 'Out of range'), 'new Num(20) should throw a TypeError with message \\'Out of range\\'.');" + }, + { + "text": "new Num(3) + new Num(4) should equal 7.", + "testString": "assert.equal(new Num(3) + new Num(4), 7, 'new Num(3) + new Num(4) should equal 7.');" + }, + { + "text": "new Num(3) - new Num(4) should equal -1.", + "testString": "assert.equal(new Num(3) - new Num(4), -1, 'new Num(3) - new Num(4) should equal -1.');" + }, + { + "text": "new Num(3) * new Num(4) should equal 12.", + "testString": "assert.equal(new Num(3) * new Num(4), 12, 'new Num(3) * new Num(4) should equal 12.');" + }, + { + "text": "new Num(3) / new Num(4) should equal 0.75.", + "testString": "assert.equal(new Num(3) / new Num(4), 0.75, 'new Num(3) / new Num(4) should equal 0.75.');" + }, + { + "text": "new Num(3) < new Num(4) should be true.", + "testString": "assert(new Num(3) < new Num(4), 'new Num(3) < new Num(4) should be true.');" + }, + { + "text": "new Num(3) > new Num(4) should be false.", + "testString": "assert(!(new Num(3) > new Num(4)), 'new Num(3) > new Num(4) should be false.');" + }, + { + "text": "(new Num(5)).toString() should return \\'5\\'", + "testString": "assert.equal((new Num(5)).toString(), '5', '(new Num(5)).toString() should return \\'5\\'');" + } + ], + "id": "597089c87eec450c68aa1643", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function Num (n) {", + " // Good luck!", + " return n;", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Department Numbers", + "type": "Waypoint", + "description": [ + "

There is a highly organized city that has decided to assign a number to each of their departments:

", + "Police department", + "Sanitation department", + "Fire department ", + "

Each department can have a number between 1 and 7 (inclusive).

The three department numbers are to be unique (different from each other) and must add up to the number 12.

The Chief of the Police doesn't like odd numbers and wants to have an even number for his department.

", + "Task:", + "

Write a program which outputs all valid combinations:

", + "

[2, 3, 7]

", + "

[2, 4, 6]

", + "

[2, 6, 4]

", + "

[2, 7, 3]

", + "

[4, 1, 7]

", + "

[4, 2, 6]

", + "

[4, 3, 5]

", + "

[4, 5, 3]

", + "

[4, 6, 2]

", + "

[4, 7, 1]

", + "

[6, 1, 5]

", + "

[6, 2, 4]

", + "

[6, 4, 2]

", + "

[6, 5, 1]

" + ], + "solutions": [ + "function combinations (possibleNumbers, total) {\n let firstNumber;\n let secondNumber;\n let thridNumber;\n const allCombinations = [];\n\n for (let i = 0; i < possibleNumbers.length; i += 1) {\n firstNumber = possibleNumbers[i];\n\n if (firstNumber % 2 === 0) {\n for (let j = 0; j < possibleNumbers.length; j += 1) {\n secondNumber = possibleNumbers[j];\n\n if (j !== i && firstNumber + secondNumber <= total) {\n thridNumber = total - firstNumber - secondNumber;\n\n if (thridNumber !== firstNumber && thridNumber !== secondNumber && possibleNumbers.includes(thridNumber)) {\n allCombinations.push([firstNumber, secondNumber, thridNumber]);\n }\n }\n }\n }\n }\n return allCombinations;\n}\n" + ], + "tests": [ + { + "text": "combinations should be a function.", + "testString": "assert(typeof combinations === 'function', 'combinations should be a function.');" + }, + { + "text": "combinations([1, 2, 3], 6) should return an Array.", + "testString": "assert(Array.isArray(combinations([1, 2, 3], 6)), 'combinations([1, 2, 3], 6) should return an Array.');" + }, + { + "text": "combinations([1, 2, 3, 4, 5, 6, 7], 12) should return an array of length 14.", + "testString": "assert(combinations(nums, total).length === len, 'combinations([1, 2, 3, 4, 5, 6, 7], 12) should return an array of length 14.');" + }, + { + "text": "combinations([1, 2, 3, 4, 5, 6, 7], 12) should return all valid combinations.", + "testString": "assert.deepEqual(combinations(nums, total), result, 'combinations([1, 2, 3, 4, 5, 6, 7], 12) should return all valid combinations.');" + } + ], + "id": "59f40b17e79dbf1ab720ed7a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function combinations (possibleNumbers, total) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const nums = [1, 2, 3, 4, 5, 6, 7];\nconst total = 12;\nconst len = 14;\nconst result = [\n [2, 3, 7],\n [2, 4, 6],\n [2, 6, 4],\n [2, 7, 3],\n [4, 1, 7],\n [4, 2, 6],\n [4, 3, 5],\n [4, 5, 3],\n [4, 6, 2],\n [4, 7, 1],\n [6, 1, 5],\n [6, 2, 4],\n [6, 4, 2],\n [6, 5, 1]\n];" + } + } + }, + { + "title": "Discordian date", + "type": "Waypoint", + "description": [ + "Task:", + "

Convert a given date from the Gregorian calendar to the Discordian calendar.

" + ], + "solutions": [ + "/**\n * All Hail Discordia! - this script prints Discordian date using system date.\n *\n * lang: JavaScript\n * author: jklu\n * contributors: JamesMcGuigan\n *\n * source: https://rosettacode.org/wiki/Discordian_date#JavaScript\n */\nconst seasons = [\n 'Chaos', 'Discord', 'Confusion',\n 'Bureaucracy', 'The Aftermath'\n];\nconst weekday = [\n 'Sweetmorn', 'Boomtime', 'Pungenday',\n 'Prickle-Prickle', 'Setting Orange'\n];\n\nconst apostle = [\n 'Mungday', 'Mojoday', 'Syaday',\n 'Zaraday', 'Maladay'\n];\n\nconst holiday = [\n 'Chaoflux', 'Discoflux', 'Confuflux',\n 'Bureflux', 'Afflux'\n];\n\n\nDate.prototype.isLeapYear = function() {\n const year = this.getFullYear();\n if ((year & 3) !== 0) { return false; }\n return ((year % 100) !== 0 || (year % 400) === 0);\n};\n\n// Get Day of Year\nDate.prototype.getDOY = function() {\n const dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n const mn = this.getMonth();\n const dn = this.getDate();\n let dayOfYear = dayCount[mn] + dn;\n if (mn > 1 && this.isLeapYear()) { dayOfYear += 1; }\n return dayOfYear;\n};\n\nDate.prototype.isToday = function() {\n const today = new Date();\n return this.getDate() === today.getDate()\n && this.getMonth() === today.getMonth()\n && this.getFullYear() === today.getFullYear()\n ;\n};\n\nfunction discordianDate(date) {\n if (!date) { date = new Date(); }\n\n const y = date.getFullYear();\n const yold = y + 1166;\n let dayOfYear = date.getDOY();\n let celebrateHoliday = null;\n\n if (date.isLeapYear()) {\n if (dayOfYear === 60) {\n celebrateHoliday = 'St. Tib\\'s Day';\n }\n else if (dayOfYear > 60) {\n dayOfYear--;\n }\n }\n dayOfYear--;\n\n const divDay = Math.floor(dayOfYear / 73);\n\n const seasonDay = (dayOfYear % 73) + 1;\n if (seasonDay === 5) {\n celebrateHoliday = apostle[divDay];\n }\n if (seasonDay === 50) {\n celebrateHoliday = holiday[divDay];\n }\n\n const season = seasons[divDay];\n const dayOfWeek = weekday[dayOfYear % 5];\n\n const nth = (seasonDay % 10 === 1) ? 'st'\n : (seasonDay % 10 === 2) ? 'nd'\n : (seasonDay % 10 === 3) ? 'rd'\n : 'th';\n\n return ''\n + dayOfWeek\n + ', the ' + seasonDay + nth\n + ' day of ' + season\n + ' in the YOLD ' + yold\n + (celebrateHoliday ? '. Celebrate ' + celebrateHoliday + '!' : '')\n ;\n}\n\n" + ], + "tests": [ + { + "text": "discordianDate is a function.", + "testString": "assert(typeof discordianDate === 'function', 'discordianDate is a function.');" + }, + { + "text": "discordianDate(new Date(2010, 6, 22)) should return \"Pungenday, the 57th day of Confusion in the YOLD 3176\".", + "testString": "assert(discordianDate(new Date(2010, 6, 22)) === 'Pungenday, the 57th day of Confusion in the YOLD 3176', 'discordianDate(new Date(2010, 6, 22)) should return \"Pungenday, the 57th day of Confusion in the YOLD 3176\".');" + }, + { + "text": "discordianDate(new Date(2012, 1, 28)) should return \"Prickle-Prickle, the 59th day of Chaos in the YOLD 3178\".", + "testString": "assert(discordianDate(new Date(2012, 1, 28)) === 'Prickle-Prickle, the 59th day of Chaos in the YOLD 3178', 'discordianDate(new Date(2012, 1, 28)) should return \"Prickle-Prickle, the 59th day of Chaos in the YOLD 3178\".');" + }, + { + "text": "discordianDate(new Date(2012, 1, 29)) should return \"Setting Orange, the 60th day of Chaos in the YOLD 3178. Celebrate St. Tib\\'s Day!\".", + "testString": "assert(discordianDate(new Date(2012, 1, 29)) === 'Setting Orange, the 60th day of Chaos in the YOLD 3178. Celebrate St. Tib\\'s Day!', 'discordianDate(new Date(2012, 1, 29)) should return \"Setting Orange, the 60th day of Chaos in the YOLD 3178. Celebrate St. Tib\\'s Day!\".');" + }, + { + "text": "discordianDate(new Date(2012, 2, 1)) should return \"Setting Orange, the 60th day of Chaos in the YOLD 3178\".", + "testString": "assert(discordianDate(new Date(2012, 2, 1)) === 'Setting Orange, the 60th day of Chaos in the YOLD 3178', 'discordianDate(new Date(2012, 2, 1)) should return \"Setting Orange, the 60th day of Chaos in the YOLD 3178\".');" + }, + { + "text": "discordianDate(new Date(2010, 0, 5)) should return \"Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!\".", + "testString": "assert(discordianDate(new Date(2010, 0, 5)) === 'Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!', 'discordianDate(new Date(2010, 0, 5)) should return \"Setting Orange, the 5th day of Chaos in the YOLD 3176. Celebrate Mungday!\".');" + }, + { + "text": "discordianDate(new Date(2011, 4, 3)) should return \"Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!\".", + "testString": "assert(discordianDate(new Date(2011, 4, 3)) === 'Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!', 'discordianDate(new Date(2011, 4, 3)) should return \"Pungenday, the 50th day of Discord in the YOLD 3177. Celebrate Discoflux!\".');" + }, + { + "text": "discordianDate(new Date(2015, 9, 19)) should return \"Boomtime, the 73rd day of Bureaucracy in the YOLD 3181\".", + "testString": "assert(discordianDate(new Date(2015, 9, 19)) === 'Boomtime, the 73rd day of Bureaucracy in the YOLD 3181', 'discordianDate(new Date(2015, 9, 19)) should return \"Boomtime, the 73rd day of Bureaucracy in the YOLD 3181\".');" + } + ], + "id": "59f4eafba0343628bb682785", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function discordianDate (date) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Element-wise operations", + "type": "Waypoint", + "description": [ + "

Implement basic element-wise matrix-matrix and scalar-matrix operations.

Implement:

", + "

::* addition

", + "

::* subtraction

", + "

::* multiplication

", + "

::* division

", + "

::* exponentiation

", + "

The first parameter will be the operation to be performed, for example : \"m_add\" for matrix addition and \"s_add\" for scalar addition. The second and third parameters will be the matrices on which the operations are to be performed." + ], + "solutions": [ + "function operation(op, arr1, arr2) {\n const ops = {\n add: ((a, b) => a + b),\n sub: ((a, b) => a - b),\n mult: ((a, b) => a * b),\n div: ((a, b) => a / b),\n exp: ((a, b) => Math.pow(a, b))\n };\n const ifm = op.startsWith('m');\n const doOp = ops[op.substring(2)];\n for (let i = 0; i < arr1.length; i++) {\n for (let j = 0; j < arr1[0].length; j++) {\n arr1[i][j] = doOp(arr1[i][j], (ifm) ? (arr2[i][j]) : (arr2));\n }\n }\n return arr1;\n}\n" + ], + "tests": [ + { + "text": "operation is a function.", + "testString": "assert(typeof operation === 'function', 'operation is a function.');" + }, + { + "text": "operation(\"m_add\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[2,4],[6,8]].", + "testString": "assert.deepEqual(operation('m_add', [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[2, 4], [6, 8]], 'operation(\"m_add\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[2,4],[6,8]].');" + }, + { + "text": "operation(\"s_add\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[3,4],[5,6]].", + "testString": "assert.deepEqual(operation('s_add', [[1, 2], [3, 4]], 2), [[3, 4], [5, 6]], 'operation(\"s_add\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[3,4],[5,6]].');" + }, + { + "text": "operation(\"m_sub\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[0,0],[0,0]].", + "testString": "assert.deepEqual(operation('m_sub', [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[0, 0], [0, 0]], 'operation(\"m_sub\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[0,0],[0,0]].');" + }, + { + "text": "operation(\"m_mult\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[1,4],[9,16]].", + "testString": "assert.deepEqual(operation('m_mult', [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[1, 4], [9, 16]], 'operation(\"m_mult\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[1,4],[9,16]].');" + }, + { + "text": "operation(\"m_div\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[1,1],[1,1]].", + "testString": "assert.deepEqual(operation('m_div', [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[1, 1], [1, 1]], 'operation(\"m_div\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[1,1],[1,1]].');" + }, + { + "text": "operation(\"m_exp\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[1,4],[27,256]].", + "testString": "assert.deepEqual(operation('m_exp', [[1, 2], [3, 4]], [[1, 2], [3, 4]]), [[1, 4], [27, 256]], 'operation(\"m_exp\",[[1,2],[3,4]],[[1,2],[3,4]]) should return [[1,4],[27,256]].');" + }, + { + "text": "operation(\"m_add\",[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]]) should return [[10,12,14,16],[18,20,22,24]].", + "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]], 'operation(\"m_add\",[[1,2,3,4],[5,6,7,8]],[[9,10,11,12],[13,14,15,16]]) should return [[10,12,14,16],[18,20,22,24]].');" + } + ], + "id": "599c333915e0ea32d04d4bec", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function operation (op, arr1, arr2) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Emirp primes", + "type": "Waypoint", + "description": [ + "

An emirp (prime spelled backwards) are primes that when reversed (in their decimal representation) are a different prime.

", + "

Write a function that should be able to : Show the first n eprimes numbers.Show the eprimes numbers in a range.Show the number of eprimes in a range.Show the nth eprimes number.

The function should have two paramters. The first will recieve n or the range as an array. The second will recieve a boolean, that specifies if the function returns the eprimes as an array or a single number(the number of primes in the range or the nth prime). According to the parameters the function should return an array or a number." + ], + "null": [], + "solutions": [ + "// noprotect\nfunction emirps(num, showEmirps)\n{\n const is_prime = function(n)\n\t{\n if (!(n % 2) || !(n % 3)) return false;\n let p = 1;\n while (p * p < n)\n\t\t\t { if (n % (p += 4) == 0 || n % (p += 2) == 0)\n\t\t\t { return false; } }\n return true;\n };\n const is_emirp = function(n) {\n const r = parseInt(n.toString().split('').reverse().join(''));\n return r != n && is_prime(n) && is_prime(r);\n };\n\n let i,\n arr = [];\n if (typeof num === 'number') {\n for (i = 0; arr.length < num; i++) if (is_emirp(i)) arr.push(i);\n // first x emirps\n if (showEmirps) return arr;\n // xth emirp\n return arr.pop();\n }\n\n if (Array.isArray(num)) {\n for (i = num[0]; i <= num[1]; i++) if (is_emirp(i)) arr.push(i);\n // emirps between x .. y\n if (showEmirps) return arr;\n // number of emirps between x .. y\n return arr.length;\n }\n}\n" + ], + "tests": [ + { + "text": "emirps is a function.", + "testString": "assert(typeof emirps === 'function', 'emirps is a function.');" + }, + { + "text": "emirps(20,true) should return [13,17,31,37,71,73,79,97,107,113,149,157,167,179,199,311,337,347,359,389]", + "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], 'emirps(20,true) should return [13,17,31,37,71,73,79,97,107,113,149,157,167,179,199,311,337,347,359,389]');" + }, + { + "text": "emirps(10000) should return 948349", + "testString": "assert.deepEqual(emirps(10000), 948349, 'emirps(10000) should return 948349');" + }, + { + "text": "emirps([7700,8000],true) should return [7717,7757,7817,7841,7867,7879,7901,7927,7949,7951,7963]", + "testString": "assert.deepEqual(emirps([7700, 8000], true), [7717, 7757, 7817, 7841, 7867, 7879, 7901, 7927, 7949, 7951, 7963], 'emirps([7700,8000],true) should return [7717,7757,7817,7841,7867,7879,7901,7927,7949,7951,7963]');" + }, + { + "text": "emirps([7700,8000],true) should return 11", + "testString": "assert.deepEqual(emirps([7700, 8000], false), 11, 'emirps([7700,8000],true) should return 11');" + } + ], + "id": "599d0ba974141b0f508b37d5", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function emirps(n) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Entropy", + "type": "Waypoint", + "description": [ + "Task:", + "

Calculate the Shannon entropy H of a given input string.

Given the discreet random variable $X$ that is a string of $N$ \"symbols\" (total characters) consisting of $n$ different characters (n=2 for binary), the Shannon entropy of X in bits/symbol is :

", + "

$H_2(X) = -\\sum_{i=1}^n \\frac{count_i}{N} \\log_2 \\left(\\frac{count_i}{N}\\right)$

where $count_i$ is the count of character $n_i$.

" + ], + "solutions": [ + "function entropy(s) {\n\t// Create a dictionary of character frequencies and iterate over it.\n function process(s, evaluator) {\n let h = Object.create(null),\n k;\n s.split('').forEach(c => {\n h[c] && h[c]++ || (h[c] = 1); });\n if (evaluator) for (k in h) evaluator(k, h[k]);\n return h;\n }\n\t// Measure the entropy of a string in bits per symbol.\n\n let sum = 0,\n len = s.length;\n process(s, (k, f) => {\n const p = f / len;\n sum -= p * Math.log(p) / Math.log(2);\n });\n return sum;\n}\n" + ], + "tests": [ + { + "text": "entropy is a function.", + "testString": "assert(typeof entropy === 'function', 'entropy is a function.');" + }, + { + "text": "entropy(\"0\") should return 0", + "testString": "assert.equal(entropy('0'), 0, 'entropy(\"0\") should return 0');" + }, + { + "text": "entropy(\"01\") should return 1", + "testString": "assert.equal(entropy('01'), 1, 'entropy(\"01\") should return 1');" + }, + { + "text": "entropy(\"0123\") should return 2", + "testString": "assert.equal(entropy('0123'), 2, 'entropy(\"0123\") should return 2');" + }, + { + "text": "entropy(\"01234567\") should return 3", + "testString": "assert.equal(entropy('01234567'), 3, 'entropy(\"01234567\") should return 3');" + }, + { + "text": "entropy(\"0123456789abcdef\") should return 4", + "testString": "assert.equal(entropy('0123456789abcdef'), 4, 'entropy(\"0123456789abcdef\") should return 4');" + }, + { + "text": "entropy(\"1223334444\") should return 1.8464393446710154", + "testString": "assert.equal(entropy('1223334444'), 1.8464393446710154, 'entropy(\"1223334444\") should return 1.8464393446710154');" + } + ], + "id": "599d15309e88c813a40baf58", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function entropy (s) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Equilibrium index", + "type": "Waypoint", + "description": [ + "

An equilibrium index of a sequence is an index into the sequence such that the sum of elements at lower indices is equal to the sum of elements at higher indices.

", + "

For example, in a sequence $A$:

:::: $A_0 = -7$

", + "

:::: $A_1 = 1$

", + "

:::: $A_2 = 5$

", + "

:::: $A_3 = 2$

", + "

:::: $A_4 = -4$

", + "

:::: $A_5 = 3$

", + "

:::: $A_6 = 0$

3 is an equilibrium index, because:

:::: $A_0 + A_1 + A_2 = A_4 + A_5 + A_6$

6 is also an equilibrium index, because:

:::: $A_0 + A_1 + A_2 + A_3 + A_4 + A_5 = 0$

(sum of zero elements is zero)

7 is not an equilibrium index, because it is not a valid index of sequence $A$.

", + "

Write a function that, given a sequence, returns its equilibrium indices (if any).

Assume that the sequence may be very long.

" + ], + "solutions": [ + "function equilibrium(a) {\n let N = a.length,\n i,\n l = [],\n r = [],\n e = [];\n for (l[0] = a[0], r[N - 1] = a[N - 1], i = 1; i < N; i++)\n { l[i] = l[i - 1] + a[i], r[N - i - 1] = r[N - i] + a[N - i - 1]; }\n for (i = 0; i < N; i++)\n { if (l[i] === r[i]) e.push(i); }\n return e;\n}\n" + ], + "tests": [ + { + "text": "equilibrium is a function.", + "testString": "assert(typeof equilibrium === 'function', 'equilibrium is a function.');" + }, + { + "text": "equilibrium([-7, 1, 5, 2, -4, 3, 0]) should return [3,6].", + "testString": "assert.deepEqual(equilibrium(tests[0]), ans[0], 'equilibrium([-7, 1, 5, 2, -4, 3, 0]) should return [3,6].');" + }, + { + "text": "equilibrium([2, 4, 6]) should return [].", + "testString": "assert.deepEqual(equilibrium(tests[1]), ans[1], 'equilibrium([2, 4, 6]) should return [].');" + }, + { + "text": "equilibrium([2, 9, 2]) should return [1].", + "testString": "assert.deepEqual(equilibrium(tests[2]), ans[2], 'equilibrium([2, 9, 2]) should return [1].');" + }, + { + "text": "equilibrium([1, -1, 1, -1, 1, -1, 1]) should return [0,1,2,3,4,5,6].", + "testString": "assert.deepEqual(equilibrium(tests[3]), ans[3], 'equilibrium([1, -1, 1, -1, 1, -1, 1]) should return [0,1,2,3,4,5,6].');" + }, + { + "text": "equilibrium([1]) should return [0].", + "testString": "assert.deepEqual(equilibrium(tests[4]), ans[4], 'equilibrium([1]) should return [0].');" + }, + { + "text": "equilibrium([]) should return [].", + "testString": "assert.deepEqual(equilibrium(tests[5]), ans[5], 'equilibrium([]) should return [].');" + } + ], + "id": "5987fd532b954e0f21b5d3f6", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function equilibrium (a) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const tests =\n [[-7, 1, 5, 2, -4, 3, 0], // 3, 6\n [2, 4, 6], // empty\n [2, 9, 2], // 1\n [1, -1, 1, -1, 1, -1, 1], // 0,1,2,3,4,5,6\n [1], // 0\n [] // empty\n ];\nconst ans = [[3, 6], [], [1], [0, 1, 2, 3, 4, 5, 6], [0], []];" + } + } + }, + { + "title": "Ethiopian multiplication", + "type": "Waypoint", + "description": [ + "

Ethiopian multiplication is a method of multiplying integers using only addition, doubling, and halving.

", + "

Method:

", + "Take two numbers to be multiplied and write them down at the top of two columns.", + "In the left-hand column repeatedly halve the last number, discarding any remainders, and write the result below the last in the same column, until you write a value of 1.", + "In the right-hand column repeatedly double the last number and write the result below. stop when you add a result in the same row as where the left hand column shows 1.", + "Examine the table produced and discard any row where the value in the left column is even.", + "Sum the values in the right-hand column that remain to produce the result of multiplying the original two numbers together", + "

For example: 17 × 34

", + "

17 34

", + "

Halving the first column:

", + "

17 34

", + "

8

", + "

4

", + "

2

", + "

1

", + "

Doubling the second column:

", + "

17 34

", + "

8 68

", + "

4 136

", + "

2 272

", + "

1 544

", + "

Strike-out rows whose first cell is even:

", + "

17 34

", + "

8 68

", + "

4 136

", + "

2 272

", + "

1 544

", + "

Sum the remaining numbers in the right-hand column:

", + "

17 34

", + "

8 --

", + "

4 ---

", + "

2 ---

", + "

1 544

", + "

====

", + "

578

", + "

So 17 multiplied by 34, by the Ethiopian method is 578.

", + "Task:", + "

The task is to define three named functions/methods/procedures/subroutines:

", + "one to halve an integer,", + "one to double an integer, and", + "one to state if an integer is even.", + "

Use these functions to create a function that does Ethiopian multiplication.

" + ], + "solutions": [ + "function eth_mult(a, b) {\n let sum = 0; a = [a]; b = [b];\n\n let half = a => a / 2,\n double = a => a * 2,\n is_even = a => a % 2 == 0;\n\n while (a[0] !== 1) {\n a.unshift(Math.floor(half(a[0])));\n b.unshift(double(b[0]));\n }\n\n for (let i = a.length - 1; i > 0; i -= 1) {\n if (!is_even(a[i])) {\n sum += b[i];\n }\n }\n return sum + b[0];\n}" + ], + "tests": [ + { + "text": "eth_mult is a function.", + "testString": "assert(typeof eth_mult === 'function', 'eth_mult is a function.');" + }, + { + "text": "eth_mult(17,34) should return 578.", + "testString": "assert.equal(eth_mult(17, 34), 578, 'eth_mult(17,34) should return 578.');" + }, + { + "text": "eth_mult(23,46) should return 1058.", + "testString": "assert.equal(eth_mult(23, 46), 1058, 'eth_mult(23,46) should return 1058.');" + }, + { + "text": "eth_mult(12,27) should return 324.", + "testString": "assert.equal(eth_mult(12, 27), 324, 'eth_mult(12,27) should return 324.');" + }, + { + "text": "eth_mult(56,98) should return 5488.", + "testString": "assert.equal(eth_mult(56, 98), 5488, 'eth_mult(56,98) should return 5488.');" + }, + { + "text": "eth_mult(63,74) should return 4662.", + "testString": "assert.equal(eth_mult(63, 74), 4662, 'eth_mult(63,74) should return 4662.');" + } + ], + "id": "599d1566a02b571412643b84", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function eth_mult (a, b) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Euler method", + "type": "Waypoint", + "description": [ + "

Euler's method numerically approximates solutions of first-order ordinary differential equations (ODEs) with a given initial value. It is an explicit method for solving initial value problems (IVPs), as described in the wikipedia page.

The ODE has to be provided in the following form:

:: $\\frac{dy(t)}{dt} = f(t,y(t))$

with an initial value

:: $y(t_0) = y_0$

To get a numeric solution, we replace the derivative on the LHS with a finite difference approximation:

:: $\\frac{dy(t)}{dt} \\approx \\frac{y(t+h)-y(t)}{h}$

then solve for $y(t+h)$:

:: $y(t+h) \\approx y(t) + h \\, \\frac{dy(t)}{dt}$

which is the same as

:: $y(t+h) \\approx y(t) + h \\, f(t,y(t))$

The iterative solution rule is then:

:: $y_{n+1} = y_n + h \\, f(t_n, y_n)$

where $h$ is the step size, the most relevant parameter for accuracy of the solution. A smaller step size increases accuracy but also the computation cost, so it has always has to be hand-picked according to the problem at hand.

", + "

Example: Newton's Cooling Law

Newton's cooling law describes how an object of initial temperature $T(t_0) = T_0$ cools down in an environment of temperature $T_R$:

:: $\\frac{dT(t)}{dt} = -k \\, \\Delta T$

", + "

or

", + "

:: $\\frac{dT(t)}{dt} = -k \\, (T(t) - T_R)$

", + "

It says that the cooling rate $\\frac{dT(t)}{dt}$ of the object is proportional to the current temperature difference $\\Delta T = (T(t) - T_R)$ to the surrounding environment.

The analytical solution, which we will compare to the numerical approximation, is

", + "

:: $T(t) = T_R + (T_0 - T_R) \\; e^{-k t}$

", + "Task:", + "

Implement a routine of Euler's method and then to use it to solve the given example of Newton's cooling law with it for three different step sizes of:

", + "

::* 2 s

", + "

::* 5 s and

", + "

::* 10 s

", + "

and to compare with the analytical solution.

", + "Initial values:", + "

::* initial temperature $T_0$ shall be 100 °C

", + "

::* room temperature $T_R$ shall be 20 °C

", + "

::* cooling constant $k$ shall be 0.07

", + "

::* time interval to calculate shall be from 0 s ──► 100 s

" + ], + "solutions": [ + "function eulersMethod(x1, y1, x2, h) {\n let x = x1;\n let y = y1;\n\n while ((x < x2 && x1 < x2) || (x > x2 && x1 > x2)) {\n y += h * (-0.07 * (y - 20));\n x += h;\n }\n\n return y;\n}\n" + ], + "tests": [ + { + "text": "eulersMethod is a function.", + "testString": "assert(typeof eulersMethod === 'function', 'eulersMethod is a function.');" + }, + { + "text": "eulersMethod(0, 100, 100, 10) should return a number.", + "testString": "assert(typeof eulersMethod(0, 100, 100, 10) === 'number', 'eulersMethod(0, 100, 100, 10) should return a number.');" + }, + { + "text": "eulersMethod(0, 100, 100, 10) should return 20.0424631833732.", + "testString": "assert.equal(eulersMethod(0, 100, 100, 2), 20.0424631833732, 'eulersMethod(0, 100, 100, 10) should return 20.0424631833732.');" + }, + { + "text": "eulersMethod(0, 100, 100, 10) should return 20.01449963666907.", + "testString": "assert.equal(eulersMethod(0, 100, 100, 5), 20.01449963666907, 'eulersMethod(0, 100, 100, 10) should return 20.01449963666907.');" + }, + { + "text": "eulersMethod(0, 100, 100, 10) should return 20.000472392.", + "testString": "assert.equal(eulersMethod(0, 100, 100, 10), 20.000472392, 'eulersMethod(0, 100, 100, 10) should return 20.000472392.');" + } + ], + "id": "59880443fb36441083c6c20e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function eulersMethod (x1, y1, x2, h) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Evaluate binomial coefficients", + "type": "Waypoint", + "description": [ + "

Write a function to calculate the binomial coefficient for the given value of n and k.

This formula is recommended:

", + "$\\binom{n}{k} = \\frac{n!}{(n-k)!k!} = \\frac{n(n-1)(n-2)\\ldots(n-k+1)}{k(k-1)(k-2)\\ldots 1}$" + ], + "solutions": [ + "function binom(n, k) {\n let coeff = 1;\n for (let i = n - k + 1; i <= n; i++) coeff *= i;\n for (let i = 1; i <= k; i++) coeff /= i;\n return coeff;\n}\n" + ], + "tests": [ + { + "text": "binom is a function.", + "testString": "assert(typeof binom === 'function', 'binom is a function.');" + }, + { + "text": "binom(5,3) should return 10.", + "testString": "assert.equal(binom(5, 3), 10, 'binom(5,3) should return 10.');" + }, + { + "text": "binom(7,2) should return 21.", + "testString": "assert.equal(binom(7, 2), 21, 'binom(7,2) should return 21.');" + }, + { + "text": "binom(10,4) should return 210.", + "testString": "assert.equal(binom(10, 4), 210, 'binom(10,4) should return 210.');" + }, + { + "text": "binom(6,1) should return 6.", + "testString": "assert.equal(binom(6, 1), 6, 'binom(6,1) should return 6.');" + }, + { + "text": "binom(12,8) should return 495.", + "testString": "assert.equal(binom(12, 8), 495, 'binom(12,8) should return 495.');" + } + ], + "id": "598de241872ef8353c58a7a2", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function binom (n, k) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Execute a Markov algorithm", + "type": "Waypoint", + "description": [ + "Task:", + "

Create an interpreter for a Markov Algorithm.

Rules have the syntax:

", + "

::= (( | ) +)*

", + "

::= # {}

", + "

::= -> [.]

", + "

::= ( | ) []

", + "

There is one rule per line.

If there is a . (period) present before the , then this is a terminating rule in which case the interpreter must halt execution.

A ruleset consists of a sequence of rules, with optional comments.

", + "

Rulesets

Use the following tests on entries:

", + "Ruleset 1:", + "
",
+        "This rules file is extracted from Wikipedia:",
+        "http://en.wikipedia.org/wiki/Markov_AlgorithmA -> apple",
+        "B -> bag",
+        "S -> shop",
+        "T -> the",
+        "the shop -> my brother",
+        "a never used -> .terminating rule",
+        "
", + "

Sample text of:

", + "

I bought a B of As from T S.

", + "

Should generate the output:

", + "

I bought a bag of apples from my brother.

", + "Ruleset 2:", + "

A test of the terminating rule

", + "
",
+        "Slightly modified from the rules on WikipediaA -> apple",
+        "B -> bag",
+        "S -> .shop",
+        "T -> the",
+        "the shop -> my brother",
+        "a never used -> .terminating rule
", + "

Sample text of:

", + "

I bought a B of As from T S.

", + "

Should generate:

", + "

I bought a bag of apples from T shop.

", + "Ruleset 3:", + "

This tests for correct substitution order and may trap simple regexp based replacement routines if special regexp characters are not escaped.

", + "
",
+        "BNF Syntax testing rulesA -> apple",
+        "WWWW -> with",
+        "Bgage -> ->.*",
+        "B -> bag",
+        "->.* -> money",
+        "W -> WW",
+        "S -> .shop",
+        "T -> the",
+        "the shop -> my brother",
+        "a never used -> .terminating rule",
+        "
", + "

Sample text of:

", + "

I bought a B of As W my Bgage from T S.

", + "

Should generate:

", + "

I bought a bag of apples with my money from T shop.

", + "Ruleset 4:", + "

This tests for correct order of scanning of rules, and may trap replacement routines that scan in the wrong order. It implements a general unary multiplication engine. (Note that the input expression must be placed within underscores in this implementation.)

", + "
",
+        "## Unary Multiplication Engine, for testing Markov Algorithm implementations",
+        "## By Donal Fellows.",
+        "Unary addition engine_+1 -> _1+",
+        "1+1 -> 11+",
+        "Pass for converting from the splitting of multiplication into ordinary",
+        "addition1! -> !1",
+        ",! -> !+",
+        "_! -> _",
+        "Unary multiplication by duplicating left side, right side times1*1 -> x,@y",
+        "1x -> xX",
+        "X, -> 1,1",
+        "X1 -> 1X",
+        "_x -> _X",
+        ",x -> ,X",
+        "y1 -> 1y",
+        "y_ -> _",
+        "Next phase of applying1@1 -> x,@y",
+        "1@_ -> @_",
+        ",@_ -> !_",
+        "++ -> +",
+        "Termination cleanup for addition_1 -> 1",
+        "1+_ -> 1",
+        "_+_ -> ",
+        "
", + "

Sample text of:

", + "

_1111*11111_

", + "

should generate the output:

", + "

11111111111111111111

", + "Ruleset 5:", + "

A simple Turing machine,

", + "

implementing a three-state busy beaver.

The tape consists of 0s and 1s, the states are A, B, C and H (for Halt), and the head position is indicated by writing the state letter before the character where the head is.

", + "

All parts of the initial tape the machine operates on have to be given in the input.

Besides demonstrating that the Markov algorithm is Turing-complete, it also made me catch a bug in the C++ implementation which wasn't caught by the first four rulesets.

", + "
",
+        "Turing machine: three-state busy beaver",
+        "# state A, symbol 0 => write 1, move right, new state BA0 -> 1B",
+        "state A, symbol 1 => write 1, move left, new state C0A1 -> C01",
+        "1A1 -> C11",
+        "state B, symbol 0 => write 1, move left, new state A0B0 -> A01",
+        "1B0 -> A11",
+        "state B, symbol 1 => write 1, move right, new state BB1 -> 1B",
+        "state C, symbol 0 => write 1, move left, new state B0C0 -> B01",
+        "1C0 -> B11",
+        "state C, symbol 1 => write 1, move left, halt0C1 -> H01",
+        "1C1 -> H11",
+        "
", + "

This ruleset should turn

", + "

000000A000000

", + "

into

", + "

00011H1111000

" + ], + "solutions": [ + "function markov(rules,test) {\n let pattern = new RegExp(\"^([^#]*?)\\\\s+->\\\\s+(\\\\.?)(.*)\");\n let origTest = test;\n\n let captures = [];\n \n rules.forEach(function(rule){\n\t\tlet m = pattern.exec(rule);\n\t\tfor (let j = 0; j < m.length; j++)\n\t\t m[j] = m[j + 1];\n\t\tcaptures.push(m);\n });\n\n test = origTest;\n let copy = test;\n for (let j = 0; j < captures.length; j++) {\n let c = captures[j];\n test = test.replace(c[0], c[2]);\n if (c[1]==\".\")\n break;\n if (test!=copy) {\n j = -1;\n copy = test;\n }\n }\n return test;\n}\n\n// tail:\nlet rules=[[\"A -> apple\",\"B -> bag\",\"S -> shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\n\t\t\t[\"A -> apple\",\"B -> bag\",\"S -> .shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\n\t\t\t[\"A -> apple\",\"WWWW -> with\",\"Bgage -> ->.*\",\"B -> bag\",\"->.* -> money\",\"W -> WW\",\"S -> .shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\n\t\t\t[\"_+1 -> _1+\",\"1+1 -> 11+\",\"1! -> !1\",\",! -> !+\",\"_! -> _\",\"1*1 -> x,@y\",\"1x -> xX\",\"X, -> 1,1\",\"X1 -> 1X\",\"_x -> _X\",\",x -> ,X\",\"y1 -> 1y\",\"y_ -> _\",\"1@1 -> x,@y\",\"1@_ -> @_\",\",@_ -> !_\",\"++ -> +\",\"_1 -> 1\",\"1+_ -> 1\",\"_+_ -> \"],\n\t\t\t[\"A0 -> 1B\",\"0A1 -> C01\",\"1A1 -> C11\",\"0B0 -> A01\",\"1B0 -> A11\",\"B1 -> 1B\",\"0C0 -> B01\",\"1C0 -> B11\",\"0C1 -> H01\",\"1C1 -> H11\"]];\nlet tests=[\"I bought a B of As from T S.\",\n\t\t\t\"I bought a B of As from T S.\",\n\t\t\t\"I bought a B of As W my Bgage from T S.\",\n\t\t\t\"_1111*11111_\",\n\t\t\t\"000000A000000\"];\nlet outputs=[\"I bought a bag of apples from my brother.\",\n\t\t\t\"I bought a bag of apples from T shop.\",\n\t\t\t\"I bought a bag of apples with my money from T shop.\",\n\t\t\t\"11111111111111111111\",\n\t\t\t\"00011H1111000\"];" + ], + "tests": [ + { + "text": "markov is a function.", + "testString": "assert(typeof markov === 'function', 'markov is a function.');" + }, + { + "text": "markov([\"A -> apple\",\"B -> bag\",\"S -> shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As from T S.\") should return \"I bought a bag of apples from my brother.\".", + "testString": "assert.deepEqual(markov(rules[0],tests[0]),outputs[0],'markov([\"A -> apple\",\"B -> bag\",\"S -> shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As from T S.\") should return \"I bought a bag of apples from my brother.\".');" + }, + { + "text": "markov([\"A -> apple\",\"B -> bag\",\"S -> .shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As from T S.\") should return \"I bought a bag of apples from T shop.\".", + "testString": "assert.deepEqual(markov(rules[1],tests[1]),outputs[1],'markov([\"A -> apple\",\"B -> bag\",\"S -> .shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As from T S.\") should return \"I bought a bag of apples from T shop.\".');" + }, + { + "text": "markov([\"A -> apple\",\"WWWW -> with\",\"Bgage -> ->.*\",\"B -> bag\",\"->.* -> money\",\"W -> WW\",\"S -> .shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As W my Bgage from T S.\") should return \"I bought a bag of apples with my money from T shop.\".", + "testString": "assert.deepEqual(markov(rules[2],tests[2]),outputs[2],'markov([\"A -> apple\",\"WWWW -> with\",\"Bgage -> ->.*\",\"B -> bag\",\"->.* -> money\",\"W -> WW\",\"S -> .shop\",\"T -> the\",\"the shop -> my brother\",\"a never used -> .terminating rule\"],\"I bought a B of As W my Bgage from T S.\") should return \"I bought a bag of apples with my money from T shop.\".');" + }, + { + "text": "markov([\"_+1 -> _1+\",\"1+1 -> 11+\",\"1! -> !1\",\",! -> !+\",\"_! -> _\",\"1*1 -> x,@y\",\"1x -> xX\",\"X, -> 1,1\",\"X1 -> 1X\",\"_x -> _X\",\",x -> ,X\",\"y1 -> 1y\",\"y_ -> _\",\"1@1 -> x,@y\",\"1@_ -> @_\",\",@_ -> !_\",\"++ -> +\",\"_1 -> 1\",\"1+_ -> 1\",\"_+_ -> \"],\"_1111*11111_\") should return \"11111111111111111111\".", + "testString": "assert.deepEqual(markov(rules[3],tests[3]),outputs[3],'markov([\"_+1 -> _1+\",\"1+1 -> 11+\",\"1! -> !1\",\",! -> !+\",\"_! -> _\",\"1*1 -> x,@y\",\"1x -> xX\",\"X, -> 1,1\",\"X1 -> 1X\",\"_x -> _X\",\",x -> ,X\",\"y1 -> 1y\",\"y_ -> _\",\"1@1 -> x,@y\",\"1@_ -> @_\",\",@_ -> !_\",\"++ -> +\",\"_1 -> 1\",\"1+_ -> 1\",\"_+_ -> \"],\"_1111*11111_\") should return \"11111111111111111111\".');" + }, + { + "text": "markov([\"A0 -> 1B\",\"0A1 -> C01\",\"1A1 -> C11\",\"0B0 -> A01\",\"1B0 -> A11\",\"B1 -> 1B\",\"0C0 -> B01\",\"1C0 -> B11\",\"0C1 -> H01\",\"1C1 -> H11\"],\"\") should return \"00011H1111000\".", + "testString": "assert.deepEqual(markov(rules[4],tests[4]),outputs[4],'markov([\"A0 -> 1B\",\"0A1 -> C01\",\"1A1 -> C11\",\"0B0 -> A01\",\"1B0 -> A11\",\"B1 -> 1B\",\"0C0 -> B01\",\"1C0 -> B11\",\"0C1 -> H01\",\"1C1 -> H11\"],\"\") should return \"00011H1111000\".');" + } + ], + "id": "59e09e6d412c5939baa02d16", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function markov (rules,test) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Execute Brain****", + "type": "Waypoint", + "description": [ + "

Write a function to implement a Brain**** interpreter. The function will take a string as a parameter and should return a string as the output. More details are given below :

", + "

RCBF is a set of Brainf*** compilers and interpreters written for Rosetta Code in a variety of languages.

Below are links to each of the versions of RCBF.

An implementation need only properly implement the following instructions:

", + "

{|

", + "

!Command

", + "

!Description

", + "

|-

", + "

| style=\"text-align:center\"| > || Move the pointer to the right

", + "

|-

", + "

| style=\"text-align:center\"| < || Move the pointer to the left

", + "

|-

", + "

| style=\"text-align:center\"| + || Increment the memory cell under the pointer

", + "

|-

", + "

| style=\"text-align:center\"| - || Decrement the memory cell under the pointer

", + "

|-

", + "

| style=\"text-align:center\"| . || Output the character signified by the cell at the pointer

", + "

|-

", + "

| style=\"text-align:center\"| , || Input a character and store it in the cell at the pointer

", + "

|-

", + "

| style=\"text-align:center\"| [ || Jump past the matching ] if the cell under the pointer is 0

", + "

|-

", + "

| style=\"text-align:center\"| ] || Jump back to the matching [ if the cell under the pointer is nonzero

", + "

|}

", + "

Any cell size is allowed, EOF (End-O-File) support is optional, as is whether you have bounded or unbounded memory.

", + " " + ], + "solutions": [ + "function brain(prog){\n var output=\"\";\n\tvar code; // formatted code\n var ip = 0; // current instruction within code\n var nest = 0; // current bracket nesting (for Out button)\n var ahead = []; // locations of matching brackets\n\n var data = [0]; // data array (mod by +, -)\n var dp = 0; // index into data (mod by <, >)\n\n var inp = 0; // current input character (fetch with ,)\n var quit = 0;\n\tvar commands = {\n\t'>':function() { if (++dp >= data.length) data[dp]=0 },\n\t'<':function() { if (--dp < 0) quit++ },\n\t'+':function() { ++data[dp] },\n\t'-':function() { --data[dp] },\n\t'[':function() { if (!data[dp]) ip = ahead[ip]; else ++nest },\n\t']':function() { if ( data[dp]) ip = ahead[ip]; else --nest },\n\t',':function() {\n\t\tvar c = document.getElementById(\"input\").value.charCodeAt(inp++);\n\t\tdata[dp] = isNaN(c) ? 0 : c; // EOF: other options are -1 or no change\n\t},\n\t'.':function() {\n \t\toutput+=String.fromCharCode(data[dp]);\n \t\t/*var s = document.getElementById(\"output\").innerHTML)\n \t\t + String.fromCharCode(data[dp]);\n \t\ts = s.replace(/\\n/g,\"
\").replace(/ /g,\"&nbsp;\");\n \t\tdocument.getElementById(\"output\").innerHTML = s;*/\n \t},\n };\n\n\tlet ar=prog.split('');\n\tvar st = [], back, error = -1;\n\tfor (ip=0; ip+>+++>++++>+++++++>++++++++>+++++++++>++++++++++>+++++++++++>++++++++++++<<<<<<<<<-]>>>>+.>>>>+..<.<++++++++.>>>+.<<+.<<<<++++.<++.>>>+++++++.>>>.+++.<+++++++.--------.<<<<<+.<+++.---.\";\nlet hello=\"++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.\";\nlet fib=`+\n\n++\n\n+++\n\n++++\n\n+>+>>\n\n>>++++\n\n+++++++\n\n++++++++\n\n+++++++++\n\n++++++++++\n\n++++++>++++\n\n++++++++++++\n\n+++++++++++++\n\n+++<<<<<<[>[>>\n\n>>>>+>+<<<<<<<-\n\n]>>>>>>>[<<<<<<<\n\n+>>>>>>>-]<[>++++\n\n++++++[-<-[>>+>+<<\n\n<-]>>>[<<<+>>>-]+<[\n\n>[-]<[-]]>[<<[>>>+<<\n\n<-]>>[-]]<<]>>>[>>+>+\n\n<<<-]>>>[<<<+>>>-]+<[>\n\n[-]<[-]]>[<<+>>[-]]<<<<\n\n<<<]>>>>>[++++++++++++++\n\n+++++++++++++++++++++++++\n\n+++++++++.[-]]++++++++++<[\n\n->-<]>+++++++++++++++++++++\n\n+++++++++++++++++++++++++++.\n\n[-]<<<<<<<<<<<<[>>>+>+<<<<-]>\n\n>>>[<<<<+>>>>-]<-[>>.>.<<<[-]]\n\n<<[>>+>+<<<-]>>>[<<<+>>>-]<<[<+\n\n>-]>[<+>-]<<<-]`;\n" + ], + "tests": [ + { + "text": "brian(\"bye\") should return a string. ", + "testString": "assert(typeof brain(\"bye\") === 'string', 'brian(\"bye\") should return a string. ');" + }, + { + "text": "brian(\"hello\") should return a string. ", + "testString": "assert(typeof brain(\"hello\") === 'string', 'brian(\"hello\") should return a string. ');" + }, + { + "text": "brian(\"++++++[>++++++++++<-]>+++++.\") should return \"A\". ", + "testString": "assert.equal(brain(\"++++++[>++++++++++<-]>+++++.\"),\"A\", 'brian(\"++++++[>++++++++++<-]>+++++.\") should return \"A\". ');" + }, + { + "text": "brain(\"+bye+\") should return Goodbye, World!\\\\r\\\\n", + "testString": "assert.equal(brain(\"+bye+\"),\"Goodbye, World!\\r\\n\",'brain(\"+bye+\") should return Goodbye, World!\\\\r\\\\n');" + }, + { + "text": "brain(\"+hello+\") should return Hello World!\\n", + "testString": "assert.equal(brain(\"+hello+\"),\"Hello World!\\n\",'brain(\"+hello+\") should return Hello World!\\n');" + }, + { + "text": "brain(\"+fib+\") should return 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89", + "testString": "assert.equal(brain(\"+fib+\"),\"1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89\",'brain(\"+fib+\") should return 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89');" + } + ], + "id": "59e0a8df964e4540d5abe599", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function brain (prog) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Extensible prime generator", + "type": "Waypoint", + "description": [ + "

Write a generator of prime numbers, in order, that will automatically adjust to accommodate the generation of any reasonably high prime.

The generator should be able to : Show the first n prime numbers.Show the prime numbers in a range.Show the number of primes in a range.Show the nth prime number.

The function should have two paramters. The first will recieve n or the range as an array. The second will recieve a boolean, that specifies if the function returns the prime numbers as an array or a single number(the number of primes in the range or the nth prime). According to the parameters the function should return an array." + ], + "solutions": [ + "// noprotect\nfunction primeGenerator(num, showPrimes) {\n let i,\n arr = [];\n\n function isPrime(num) {\n // try primes <= 16\n if (num <= 16) { return (\n num == 2 || num == 3 || num == 5 || num == 7 || num == 11 || num == 13\n ); }\n // cull multiples of 2, 3, 5 or 7\n if (num % 2 == 0 || num % 3 == 0 || num % 5 == 0 || num % 7 == 0)\n { return false; }\n // cull square numbers ending in 1, 3, 7 or 9\n for (let i = 10; i * i <= num; i += 10) {\n if (num % (i + 1) == 0) return false;\n if (num % (i + 3) == 0) return false;\n if (num % (i + 7) == 0) return false;\n if (num % (i + 9) == 0) return false;\n }\n return true;\n }\n\n if (typeof num === 'number') {\n for (i = 0; arr.length < num; i++) if (isPrime(i)) arr.push(i);\n // first x primes\n if (showPrimes) return arr;\n // xth prime\n return arr.pop();\n }\n\n if (Array.isArray(num)) {\n for (i = num[0]; i <= num[1]; i++) if (isPrime(i)) arr.push(i);\n // primes between x .. y\n if (showPrimes) return arr;\n // number of primes between x .. y\n return arr.length;\n }\n}\n" + ], + "tests": [ + { + "text": "primeGenerator is a function.", + "testString": "assert(typeof primeGenerator === 'function', 'primeGenerator is a function.');" + }, + { + "text": "primeGenerator is a function.", + "testString": "assert.deepEqual(primeGenerator(20, true), [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71], 'primeGenerator is a function.');" + }, + { + "text": "primeGenerator is a function.", + "testString": "assert.deepEqual(primeGenerator([100, 150], true), [101, 103, 107, 109, 113, 127, 131, 137, 139, 149], 'primeGenerator is a function.');" + }, + { + "text": "primeGenerator is a function.", + "testString": "assert.equal(primeGenerator([7700, 8000], false), 30, 'primeGenerator is a function.');" + }, + { + "text": "primeGenerator is a function.", + "testString": "assert.equal(primeGenerator(10000, false), 104729, 'primeGenerator is a function.');" + } + ], + "id": "598ee8b91b410510ae82efef", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function primeGenerator (num, showPrimes) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Factorial", + "type": "Waypoint", + "description": [ + "

Write a function to return the factorial of a number.

", + "

Factorial of a number is given by :

", + "n! = n * (n-1) * (n-2) * ..... * 1", + "

", + "For example :", + "3! = 3*2*1 = 6", + "4! = 4*3*2*1 = 24", + "

", + "

Note : ", + "0! = 1 ", + "

" + ], + "solutions": [ + "function factorial(n) {\n let sum = 1;\n while (n > 1) {\n sum *= n;\n n--;\n }\n return sum;\n}\n\n" + ], + "tests": [ + { + "text": "factorial is a function.", + "testString": "assert(typeof factorial === 'function', 'factorial is a function.');" + }, + { + "text": "factorial(2) should return a number.", + "testString": "assert(typeof factorial(2) === 'number', 'factorial(2) should return a number.');" + }, + { + "text": "factorial(3) should return 6.\")", + "testString": "assert.equal(factorial(3),results[0],\"factorial(3) should return 6.\");" + }, + { + "text": "factorial(3) should return 120.\")", + "testString": "assert.equal(factorial(5),results[1],\"factorial(3) should return 120.\");" + }, + { + "text": "factorial(3) should return 3,628,800.\")", + "testString": "assert.equal(factorial(10),results[2],\"factorial(3) should return 3,628,800.\");" + } + ], + "id": "597b2b2a2702b44414742771", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function factorial (n) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const results=[6,120,3628800];" + } + } + }, + { + "title": "Factors of a Mersenne number", + "type": "Waypoint", + "description": [ + "

A Mersenne number is a number in the form of 2P-1.

If P is prime, the Mersenne number may be a Mersenne prime

", + "

(if P is not prime, the Mersenne number is also not prime).

In the search for Mersenne prime numbers it is advantageous to eliminate exponents by finding a small factor before starting a, potentially lengthy, Lucas-Lehmer test.

There are very efficient algorithms for determining if a number divides 2P-1 (or equivalently, if 2P mod (the number) = 1).

", + "

Some languages already have built-in implementations of this exponent-and-mod operation (called modPow or similar).

The following is how to implement this modPow yourself:

For example, let's compute 223 mod 47.

", + "

Convert the exponent 23 to binary, you get 10111. Starting with square = 1, repeatedly square it.

", + "

Remove the top bit of the exponent, and if it's 1 multiply square by the base of the exponentiation (2), then compute square modulo 47.

", + "

Use the result of the modulo from the last step as the initial value of square in the next step:

Remove Optional

", + "

square top bit multiply by 2 mod 47

", + "

------------ ------- ------------- ------

", + "

1*1 = 1 1 0111 1*2 = 2 2

", + "

2*2 = 4 0 111 no 4

", + "

4*4 = 16 1 11 16*2 = 32 32

", + "

32*32 = 1024 1 1 1024*2 = 2048 27

", + "

27*27 = 729 1 729*2 = 1458 1

Since 223 mod 47 = 1, 47 is a factor of 2P-1.

", + "

(To see this, subtract 1 from both sides: 223-1 = 0 mod 47.)

", + "

Since we've shown that 47 is a factor, 223-1 is not prime.

", + "

Further properties of Mersenne numbers allow us to refine the process even more.

", + "

Any factor q of 2P-1 must be of the form 2kP+1, k being a positive integer or zero. Furthermore, q must be 1 or 7 mod 8.

", + "

Finally any potential factor q must be prime.

", + "

As in other trial division algorithms, the algorithm stops when 2kP+1 > sqrt(N).

These primality tests only work on Mersenne numbers where P is prime. For example, M4=15 yields no factors using these techniques, but factors into 3 and 5, neither of which fit 2kP+1.

", + "Task:", + "

Using the above method find a factor of 2929-1 (aka M929)

", + "Related tasks:", + " count in factors", + " prime decomposition", + " factors of an integer", + " Sieve of Eratosthenes", + " primality by trial division", + " trial factoring of a Mersenne number", + " partition an integer X into N primes", + " sequence of primes by Trial Division", + " Computers in 1948: 2¹²⁷-1" + ], + "solutions": [ + "function check_mersenne(p){ \n\tfunction isPrime(value){\n\t for (let i=2; i < value; i++){\n\t\tif (value % i == 0){\n\t\t return false;\n\t\t}\n\t\tif (value % i != 0){\n\t\t return true;\n\t\t }\n\t }\n\t}\n\t\n\tfunction trial_factor(base, exp, mod){\n\t let square, bits;\n\t square = 1;\n\t bits = exp.toString(2).split('');\n\t for (let i=0,ln=bits.length; icheck_mersenne is a function.", + "testString": "assert(typeof check_mersenne === 'function', 'check_mersenne is a function.');" + }, + { + "text": "check_mersenne(3) should return a string.", + "testString": "assert(typeof check_mersenne(3) == 'string', 'check_mersenne(3) should return a string.');" + }, + { + "text": "check_mersenne(3) should return \"M3 = 2^3-1 is prime\".", + "testString": "assert.equal(check_mersenne(3),\"M3 = 2^3-1 is prime\",'check_mersenne(3) should return \"M3 = 2^3-1 is prime\".');" + }, + { + "text": "check_mersenne(23) should return \"M23 = 2^23-1 is composite with factor 47\".", + "testString": "assert.equal(check_mersenne(23),\"M23 = 2^23-1 is composite with factor 47\",'check_mersenne(23) should return \"M23 = 2^23-1 is composite with factor 47\".');" + }, + { + "text": "check_mersenne(929) should return \"M929 = 2^929-1 is composite with factor 13007", + "testString": "assert.equal(check_mersenne(929),\"M929 = 2^929-1 is composite with factor 13007\",'check_mersenne(929) should return \"M929 = 2^929-1 is composite with factor 13007');" + } + ], + "id": "598eea87e5cf4b116c3ff81a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function check_mersenne (p) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Factors of an integer", + "type": "Waypoint", + "description": [ + "

Write a function that returns the factors of a positive integer.

These factors are the positive integers by which the number being factored can be divided to yield a positive integer result.

", + "///" + ], + "solutions": [ + "function factors(num)\n{\n let n_factors = [], i, sqr=Math.floor(Math.sqrt(num));\n\n for (i = 1; i <=sqr ; i += 1)\n if (num % i === 0)\n {\n n_factors.push(i);\n if (num / i !== i)\n n_factors.push(num / i);\n }\n n_factors.sort(function(a, b){return a - b;});\n return n_factors;\n}\n" + ], + "tests": [ + { + "text": "factors is a function.", + "testString": "assert(typeof factors === 'function', 'factors is a function.');" + }, + { + "text": "factors(45) should return [1,3,5,9,15,45].", + "testString": "assert.deepEqual(factors(45), ans[0], 'factors(45) should return [1,3,5,9,15,45].');" + }, + { + "text": "factors(53) should return [1,53].", + "testString": "assert.deepEqual(factors(53), ans[1], 'factors(53) should return [1,53].');" + }, + { + "text": "factors(64) should return [1,2,4,8,16,32,64].", + "testString": "assert.deepEqual(factors(64), ans[2], 'factors(64) should return [1,2,4,8,16,32,64].');" + } + ], + "id": "597f1e7fbc206f0e9ba95dc4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function factors (num) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const ans=[[1,3,5,9,15,45],[1,53],[1,2,4,8,16,32,64]];" + } + } + }, + { + "title": "Farey sequence", + "type": "Waypoint", + "description": [ + "

Write a function that returns the Farey sequence of order n. The function should have one parameter that is n. It should return the sequence as an array. Read the following for more details :

The Farey sequence Fn of order n is the sequence of completely reduced fractions between 0 and 1 which, when in lowest terms, have denominators less than or equal to n, arranged in order of increasing size.

The Farey sequence is sometimes incorrectly called a Farey series.

", + "

Each Farey sequence:

", + "

::* starts with the value 0, denoted by the fraction $ \\frac{0}{1} $

", + "

::* ends with the value 1, denoted by the fraction $ \\frac{1}{1}$.

", + "

The Farey sequences of orders 1 to 5 are:

${\\bf\\it{F}}_1 = \\frac{0}{1}, \\frac{1}{1}$

", + "

", + "

${\\bf\\it{F}}_2 = \\frac{0}{1}, \\frac{1}{2}, \\frac{1}{1}$

", + "

", + "

${\\bf\\it{F}}_3 = \\frac{0}{1}, \\frac{1}{3}, \\frac{1}{2}, \\frac{2}{3}, \\frac{1}{1}$

", + "

", + "

${\\bf\\it{F}}_4 = \\frac{0}{1}, \\frac{1}{4}, \\frac{1}{3}, \\frac{1}{2}, \\frac{2}{3}, \\frac{3}{4}, \\frac{1}{1}$

", + "

", + "

${\\bf\\it{F}}_5 = \\frac{0}{1}, \\frac{1}{5}, \\frac{1}{4}, \\frac{1}{3}, \\frac{2}{5}, \\frac{1}{2}, \\frac{3}{5}, \\frac{2}{3}, \\frac{3}{4}, \\frac{4}{5}, \\frac{1}{1}$

" + ], + "solutions": [ + "function farey(n){\n\tlet farSeq=[];\n\tfor(let den = 1; den <= n; den++){\n\t\tfor(let num = 1; num < den; num++){\n\t\t\tfarSeq.push({\n\t\t\t\tstr:num+\"/\"+den,\n\t\t\t\tval:num/den});\n\t\t}\n\t}\n\tfarSeq.sort(function(a,b){\n\t\treturn a.val-b.val;\n\t});\n\tfarSeq=farSeq.map(function(a){\n\t\treturn a.str;\n\t});\n\treturn farSeq;\n}\n" + ], + "tests": [ + { + "text": "farey is a function.", + "testString": "assert(typeof farey === 'function', 'farey is a function.');" + }, + { + "text": "farey(3) should return an array", + "testString": "assert(Array.isArray(farey(3)), 'farey(3) should return an array');" + }, + { + "text": "farey(3) should return [\"1/3\",\"1/2\",\"2/3\"]", + "testString": "assert.deepEqual(farey(3),[\"1/3\",\"1/2\",\"2/3\"], 'farey(3) should return [\"1/3\",\"1/2\",\"2/3\"]');" + }, + { + "text": "farey(4) should return [\"1/4\",\"1/3\",\"1/2\",\"2/4\",\"2/3\",\"3/4\"]", + "testString": "assert.deepEqual(farey(4),[\"1/4\",\"1/3\",\"1/2\",\"2/4\",\"2/3\",\"3/4\"],'farey(4) should return [\"1/4\",\"1/3\",\"1/2\",\"2/4\",\"2/3\",\"3/4\"]');" + }, + { + "text": "farey(5) should return [\"1/5\",\"1/4\",\"1/3\",\"2/5\",\"1/2\",\"2/4\",\"3/5\",\"2/3\",\"3/4\",\"4/5\"]", + "testString": "assert.deepEqual(farey(5),[\"1/5\",\"1/4\",\"1/3\",\"2/5\",\"1/2\",\"2/4\",\"3/5\",\"2/3\",\"3/4\",\"4/5\"],'farey(5) should return [\"1/5\",\"1/4\",\"1/3\",\"2/5\",\"1/2\",\"2/4\",\"3/5\",\"2/3\",\"3/4\",\"4/5\"]');" + } + ], + "id": "59c3ec9f15068017c96eb8a3", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function farey (n) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Fibonacci n-step number sequences", + "type": "Waypoint", + "description": [ + "

Write a function to generate Fibonacci n-step number sequences and Lucas sequences. The first parameter will be n. The second parameter will be the number of elements to be returned. The third paramter will specify whether to output the Fibonacci sequence or the Lucas sequence. If the parameter is \"f\" then return the Fibonacci sequence and if it is \"l\", then return the Lucas sequence. The sequences must be returned as an array. More details are given below :

These number series are an expansion of the ordinary Fibonacci sequence where:

", + "For $n = 2$ we have the Fibonacci sequence; with initial values $[1, 1]$ and $F_k^2 = F_{k-1}^2 + F_{k-2}^2$", + "For $n = 3$ we have the tribonacci sequence; with initial values $[1, 1, 2]$ and $F_k^3 = F_{k-1}^3 + F_{k-2}^3 + F_{k-3}^3$", + "For $n = 4$ we have the tetranacci sequence; with initial values $[1, 1, 2, 4]$ and $F_k^4 = F_{k-1}^4 + F_{k-2}^4 + F_{k-3}^4 + F_{k-4}^4$...", + "For general $n>2$ we have the Fibonacci $n$-step sequence - $F_k^n$; with initial values of the first $n$ values of the $(n-1)$'th Fibonacci $n$-step sequence $F_k^{n-1}$; and $k$'th value of this $n$'th sequence being $F_k^n = \\sum_{i=1}^{(n)} {F_{k-i}^{(n)}}$", + "

For small values of $n$, Greek numeric prefixes are sometimes used to individually name each series.

{| style=\"text-align: left;\" border=\"4\" cellpadding=\"2\" cellspacing=\"2\"

", + "

|+ Fibonacci $n$-step sequences

", + "

|- style=\"background-color: rgb(255, 204, 255);\"

", + "

! $n$ !! Series name !! Values

", + "

|-

", + "

| 2 || fibonacci || 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 ...

", + "

|-

", + "

| 3 || tribonacci || 1 1 2 4 7 13 24 44 81 149 274 504 927 1705 3136 ...

", + "

|-

", + "

| 4 || tetranacci || 1 1 2 4 8 15 29 56 108 208 401 773 1490 2872 5536 ...

", + "

|-

", + "

| 5 || pentanacci || 1 1 2 4 8 16 31 61 120 236 464 912 1793 3525 6930 ...

", + "

|-

", + "

| 6 || hexanacci || 1 1 2 4 8 16 32 63 125 248 492 976 1936 3840 7617 ...

", + "

|-

", + "

| 7 || heptanacci || 1 1 2 4 8 16 32 64 127 253 504 1004 2000 3984 7936 ...

", + "

|-

", + "

| 8 || octonacci || 1 1 2 4 8 16 32 64 128 255 509 1016 2028 4048 8080 ...

", + "

|-

", + "

| 9 || nonanacci || 1 1 2 4 8 16 32 64 128 256 511 1021 2040 4076 8144 ...

", + "

|-

", + "

| 10 || decanacci || 1 1 2 4 8 16 32 64 128 256 512 1023 2045 4088 8172 ...

", + "

|}

Allied sequences can be generated where the initial values are changed:

", + "

The Lucas series sums the two preceding values like the fibonacci series for $n=2$ but uses $[2, 1]$ as its initial values.

" + ], + "solutions": [ + "function fib_luc(n, len, w) {\n\tfunction nacci(a, n, len) {\n\t\twhile (a.length < len) {\n\t\t let sum = 0;\n\t\t for (let i = Math.max(0, a.length - n); i < a.length; i++)\n\t\t sum += a[i];\n\t\t a.push(sum);\n\t\t}\n\t\treturn a;\n\t}\n\tif(w==\"f\"){\n \treturn nacci(nacci([1,1], n, n), n, len);\n\t}else{\n \treturn nacci(nacci([2,1], n, n), n, len);\n\t}\n}\n" + ], + "tests": [ + { + "text": "fib_luc is a function.", + "testString": "assert(typeof fib_luc === 'function', 'fib_luc is a function.');" + }, + { + "text": "fib_luc(2,10,\"f\") should return [1,1,2,3,5,8,13,21,34,55].", + "testString": "assert.deepEqual(fib_luc(2,10,\"f\"),ans[0],'fib_luc(2,10,\"f\") should return [1,1,2,3,5,8,13,21,34,55].');" + }, + { + "text": "fib_luc(3,15,\"f\") should return [1,1,2,4,7,13,24,44,81,149,274,504,927,1705,3136].", + "testString": "assert.deepEqual(fib_luc(3,15,\"f\"),ans[1],'fib_luc(3,15,\"f\") should return [1,1,2,4,7,13,24,44,81,149,274,504,927,1705,3136].');" + }, + { + "text": "fib_luc(4,15,\"f\") should return [1,1,2,4,8,15,29,56,108,208,401,773,1490,2872,5536].", + "testString": "assert.deepEqual(fib_luc(4,15,\"f\"),ans[2],'fib_luc(4,15,\"f\") should return [1,1,2,4,8,15,29,56,108,208,401,773,1490,2872,5536].');" + }, + { + "text": "fib_luc(2,10,\"l\") should return [ 2, 1, 3, 4, 7, 11, 18, 29, 47, 76].", + "testString": "assert.deepEqual(fib_luc(2,10,\"l\"),ans[3],'fib_luc(2,10,\"l\") should return [ 2, 1, 3, 4, 7, 11, 18, 29, 47, 76].');" + }, + { + "text": "fib_luc(3,15,\"l\") should return [ 2, 1, 3, 6, 10, 19, 35, 64, 118, 217, 399, 734, 1350, 2483, 4567 ].", + "testString": "assert.deepEqual(fib_luc(3,15,\"l\"),ans[4],'fib_luc(3,15,\"l\") should return [ 2, 1, 3, 6, 10, 19, 35, 64, 118, 217, 399, 734, 1350, 2483, 4567 ].');" + }, + { + "text": "fib_luc(4,15,\"l\") should return [ 2, 1, 3, 6, 12, 22, 43, 83, 160, 308, 594, 1145, 2207, 4254, 8200 ].", + "testString": "assert.deepEqual(fib_luc(4,15,\"l\"),ans[5],'fib_luc(4,15,\"l\") should return [ 2, 1, 3, 6, 12, 22, 43, 83, 160, 308, 594, 1145, 2207, 4254, 8200 ].');" + }, + { + "text": "fib_luc(5,15,\"l\") should return [ 2, 1, 3, 6, 12, 24, 46, 91, 179, 352, 692, 1360, 2674, 5257, 10335 ].", + "testString": "assert.deepEqual(fib_luc(5,15,\"l\"),ans[6],'fib_luc(5,15,\"l\") should return [ 2, 1, 3, 6, 12, 24, 46, 91, 179, 352, 692, 1360, 2674, 5257, 10335 ].');" + } + ], + "id": "598eef80ba501f1268170e1e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function fib_luc (n, len, w) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const ans = [[1,1,2,3,5,8,13,21,34,55],\n[1,1,2,4,7,13,24,44,81,149,274,504,927,1705,3136],\n[1,1,2,4,8,15,29,56,108,208,401,773,1490,2872,5536],\n[ 2, 1, 3, 4, 7, 11, 18, 29, 47, 76],\n[ 2, 1, 3, 6, 10, 19, 35, 64, 118, 217, 399, 734, 1350, 2483, 4567 ],\n[ 2, 1, 3, 6, 12, 22, 43, 83, 160, 308, 594, 1145, 2207, 4254, 8200 ],\n[ 2, 1, 3, 6, 12, 24, 46, 91, 179, 352, 692, 1360, 2674, 5257, 10335 ]];" + } + } + }, + { + "title": "Fibonacci sequence", + "type": "Waypoint", + "description": [ + "

Write a function to generate the nth Fibonacci number.

", + "///

The nth Fibonacci number is given by :", + "///

Fn = Fn-1 + Fn-2

", + "///

The first two terms of the series are 0, 1.

", + "///

Hence, the series is : 0, 1, 1, 2, 3, 5, 8, 13...

", + "///" + ], + "solutions": [ + "function fibonacci(n) {\n let a = 0, b = 1, t;\n while (--n > 0) {\n t = a;\n a = b;\n b += t;\n }\n return a;\n}\n" + ], + "tests": [ + { + "text": "fibonacci is a function.", + "testString": "assert(typeof fibonacci === 'function', 'fibonacci is a function.');" + }, + { + "text": "fibonacci(2) should return a number.", + "testString": "assert(typeof fibonacci(2) == 'number', 'fibonacci(2) should return a number.');" + }, + { + "text": "fibonacci(3) should return 1.\")", + "testString": "assert.equal(fibonacci(3),1,\"fibonacci(3) should return 1.\");" + }, + { + "text": "fibonacci(5) should return 3.\")", + "testString": "assert.equal(fibonacci(5),3,\"fibonacci(5) should return 3.\");" + }, + { + "text": "fibonacci(10) should return 34.\")", + "testString": "assert.equal(fibonacci(10),34,\"fibonacci(10) should return 34.\");" + } + ], + "id": "597f24c1dda4e70f53c79c81", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function fibonacci(n) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Fibonacci word", + "type": "Waypoint", + "description": [ + "

Write a function to return the Fibonacci Words upto N. N will be provided as a parameter to the function. The function should return an array of objects. The objects should be of the form : { N: 1, Length: 1, Entropy: 0, Word: '1' }. More details are given below :

The Fibonacci Word may be created in a manner analogous to the Fibonacci Sequence as described here:

Define F_Word1 as 1

", + "

Define F_Word2 as 0

", + "

Form F_Word3 as F_Word2 concatenated with F_Word1 i.e.: 01

", + "

Form F_Wordn as F_Wordn-1 concatenated with F_wordn-2

" + ], + "solutions": [ + "function fibWord(n) {\n function entropy(s) {\n //create an object containing each individual char\n //and the amount of iterations per char \n function prob(s) {\n var h = Object.create(null);\n s.split('').forEach(function(c) {\n h[c] && h[c]++ || (h[c] = 1); \n });\n return h;\n }\n\n s = s.toString(); //just in case \n var e = 0, l = s.length, h = prob(s);\n\n for (var i in h ) {\n var p = h[i]/l;\n e -= p * Math.log(p) / Math.log(2);\n }\n return e;\n }\n var wOne = \"1\", wTwo = \"0\", wNth = [wOne, wTwo], w = \"\", o = [];\n \n for (var i = 0; i < n; i++) {\n if (i === 0 || i === 1) {\n w = wNth[i];\n } else {\n w = wNth[i - 1] + wNth[i - 2];\n wNth.push(w);\n }\n var l = w.length;\n var e = entropy(w);\n \n if (l <= 21) {\n \to.push({\n \tN: i + 1,\n \tLength: l,\n \tEntropy: e,\n \tWord: w\n \t});\n } else {\n \to.push({\n \tN: i + 1,\n \tLength: l,\n \tEntropy: e,\n \tWord: \"...\"\n \t});\n } \n }\n return o;\n}\n" + ], + "tests": [ + { + "text": "fibWord is a function.", + "testString": "assert(typeof fibWord === 'function', 'fibWord is a function.');" + }, + { + "text": "fibWord(5) should return an array.", + "testString": "assert(Array.isArray(fibWord(5)),'fibWord(5) should return an array.');" + }, + { + "text": "fibWord(5) should return '+JSON.stringify(ans)+'.", + "testString": "assert.deepEqual(fibWord(5),ans,'fibWord(5) should return '+JSON.stringify(ans)+'.');" + } + ], + "id": "5992e222d397f00d21122931", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function fibWord (n) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "let ans=[ { N: 1, Length: 1, Entropy: 0, Word: '1' },\n\n { N: 2, Length: 1, Entropy: 0, Word: '0' },\n\n { N: 3, Length: 2, Entropy: 1, Word: '01' },\n\n { N: 4, Length: 3, Entropy: 0.9182958340544896, Word: '010' },\n\n { N: 5, Length: 5, Entropy: 0.9709505944546688, Word: '01001' }];" + } + } + }, + { + "title": "Hailstone sequence", + "type": "Waypoint", + "description": [ + "

The Hailstone sequence of numbers can be generated from a starting positive integer, n by:

", + " If n is 1 then the sequence ends.", + " If n is even then the next n of the sequence = n/2 ", + " If n is odd then the next n of the sequence = (3 * n) + 1

The (unproven) Collatz conjecture is that the hailstone sequence for any starting number always terminates.

", + "

The hailstone sequence is also known as hailstone numbers (because the values are usually subject to multiple descents and ascents like hailstones in a cloud), or as the Collatz sequence.

", + "Task:", + "Create a routine to generate the hailstone sequence for a number.", + "Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with 27, 82, 41, 124 and ending with 8, 4, 2, 1", + "Show the number less than 100,000 which has the longest hailstone sequence together with that sequence's length. (But don't show the actual sequence!)See also:", + " xkcd (humourous)." + ], + "solutions": [ + "// noprotect\nfunction hailstoneSequence () {\n const res = [];\n\n function hailstone(n) {\n const seq = [n];\n while (n > 1) {\n n = n % 2 ? 3 * n + 1 : n / 2;\n seq.push(n);\n }\n return seq;\n }\n\n const h = hailstone(27);\n const hLen = h.length;\n res.push([...h.slice(0, 4), ...h.slice(hLen - 4, hLen)]);\n\n let n = 0;\n let max = 0;\n for (let i = 100000; --i;) {\n const seq = hailstone(i);\n const sLen = seq.length;\n\n if (sLen > max) {\n n = i;\n max = sLen;\n }\n }\n res.push([max, n]);\n\n return res;\n}\n" + ], + "tests": [ + { + "text": "hailstoneSequence is a function.", + "testString": "assert(typeof hailstoneSequence === 'function', 'hailstoneSequence is a function.');" + }, + { + "text": "hailstoneSequence() should return [[27,82,41,124,8,4,2,1], [351, 77031]]", + "testString": "assert.deepEqual(hailstoneSequence(), res, 'hailstoneSequence() should return [[27,82,41,124,8,4,2,1], [351, 77031]]');" + } + ], + "id": "595608ff8bcd7a50bd490181", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "// noprotect", + "function hailstoneSequence () {", + " const res = [];", + " // Good luck!", + "", + " return res;", + "}" + ], + "head": "", + "tail": "const res = [[27, 82, 41, 124, 8, 4, 2, 1], [351, 77031]];" + } + } + }, + { + "title": "Happy numbers", + "type": "Waypoint", + "description": [ + "

A happy number is defined by the following process:

", + "

Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers, while those that do not end in 1 are unhappy numbers.

", + "

Implement a function that returns true if the number is happy, or false if not.

" + ], + "solutions": [ + "function happy (number) {\n let m;\n let digit;\n const cycle = [];\n\n while (number !== 1 && cycle[number] !== true) {\n cycle[number] = true;\n m = 0;\n while (number > 0) {\n digit = number % 10;\n m += Math.pow(digit, 2);\n number = (number - digit) / 10;\n }\n number = m;\n }\n return (number === 1);\n}\n" + ], + "tests": [ + { + "text": "happy is a function.", + "testString": "assert(typeof happy === 'function', 'happy is a function.');" + }, + { + "text": "happy(1) should return a boolean.", + "testString": "assert(typeof happy(1) === 'boolean', 'happy(1) should return a boolean.');" + }, + { + "text": "happy(1) should return true.", + "testString": "assert(happy(1), 'happy(1) should return true.');" + }, + { + "text": "happy(2) should return false.", + "testString": "assert(!happy(2), 'happy(2) should return false.');" + }, + { + "text": "happy(7) should return true.", + "testString": "assert(happy(7), 'happy(7) should return true.');" + }, + { + "text": "happy(10) should return true.", + "testString": "assert(happy(10), 'happy(10) should return true.');" + }, + { + "text": "happy(13) should return true.", + "testString": "assert(happy(13), 'happy(13) should return true.');" + }, + { + "text": "happy(19) should return true.", + "testString": "assert(happy(19), 'happy(19) should return true.');" + }, + { + "text": "happy(23) should return true.", + "testString": "assert(happy(23), 'happy(23) should return true.');" + }, + { + "text": "happy(28) should return true.", + "testString": "assert(happy(28), 'happy(28) should return true.');" + }, + { + "text": "happy(31) should return true.", + "testString": "assert(happy(31), 'happy(31) should return true.');" + }, + { + "text": "happy(32) should return true:.", + "testString": "assert(happy(32), 'happy(32) should return true:.');" + }, + { + "text": "happy(33) should return false.", + "testString": "assert(!happy(33), 'happy(33) should return false.');" + } + ], + "id": "594810f028c0303b75339ad1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function happy (number) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "Harshad or Niven series", + "type": "Waypoint", + "description": [ + "

The Harshad or Niven numbers are positive integers ≥ 1 that are divisible by the sum of their digits.

For example, 42 is a Harshad number as 42 is divisible by (4 + 2) without remainder.

", + "Assume that the series is defined as the numbers in increasing order.", + "Task:", + "

Implement a function to generate successive members of the Harshad sequence.

Use it to list the first twenty members of the sequence and list the first Harshad number greater than 1000.

" + ], + "solutions": [ + "function isHarshadOrNiven() {\n const res = {\n firstTwenty: [],\n firstOver1000: undefined\n };\n\n function isHarshad(n) {\n let s = 0;\n const nStr = n.toString();\n for (let i = 0; i < nStr.length; ++i) {\n s += parseInt(nStr.charAt(i), 10);\n }\n return n % s === 0;\n }\n\n let count = 0;\n const harshads = [];\n\n for (let n = 1; count < 20; ++n) {\n if (isHarshad(n)) {\n count++;\n harshads.push(n);\n }\n }\n\n res.firstTwenty = harshads;\n\n let h = 1000;\n while (!isHarshad(++h));\n res.firstOver1000 = h;\n\n return res;\n}\n" + ], + "tests": [ + { + "text": "isHarshadOrNiven is a function.", + "testString": "assert(typeof isHarshadOrNiven === 'function', 'isHarshadOrNiven is a function.');" + }, + { + "text": "isHarshadOrNiven() should return {\"firstTwenty\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42],\"firstOver1000\": 1002}", + "testString": "assert.deepEqual(isHarshadOrNiven(), res, 'isHarshadOrNiven() should return {\"firstTwenty\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42],\"firstOver1000\": 1002}');" + } + ], + "id": "595668ca4cfe1af2fb9818d4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function isHarshadOrNiven () {", + " const res = {", + " firstTwenty: [],", + " firstOver1000: undefined", + " };", + " // Change after this line", + "", + " return res;", + "}" + ], + "head": "", + "tail": "const res = {\n firstTwenty: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30, 36, 40, 42],\n firstOver1000: 1002\n};" + } + } + }, + { + "title": "Hash from two arrays", + "type": "Waypoint", + "description": [ + "Task:", + "

Using two Arrays of equal length, create a Hash object where the elements from one array (the keys) are linked to the elements of the other (the values)

", + "Related task:", + " Associative arrays/Creation" + ], + "solutions": [ + "function arrToObj (keys, vals) {\n return keys.reduce((map, key, index) => {\n map[key] = vals[index];\n return map;\n }, {});\n}" + ], + "tests": [ + { + "text": "arrToObj is a function.", + "testString": "assert(typeof arrToObj === 'function', 'arrToObj is a function.');" + }, + { + "text": "arrToObj([1, 2, 3, 4, 5], [\"a\", \"b\", \"c\", \"d\", \"e\"]) should return { 1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\" }", + "testString": "assert.deepEqual(arrToObj(...testCases[0]), res[0], 'arrToObj([1, 2, 3, 4, 5], [\"a\", \"b\", \"c\", \"d\", \"e\"]) should return { 1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: \"e\" }');" + }, + { + "text": "arrToObj([1, 2, 3, 4, 5], [\"a\", \"b\", \"c\", \"d\"]) should return { 1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: undefined }", + "testString": "assert.deepEqual(arrToObj(...testCases[1]), res[1], 'arrToObj([1, 2, 3, 4, 5], [\"a\", \"b\", \"c\", \"d\"]) should return { 1: \"a\", 2: \"b\", 3: \"c\", 4: \"d\", 5: undefined }');" + }, + { + "text": "arrToObj([1, 2, 3], [\"a\", \"b\", \"c\", \"d\", \"e\"]) should return { 1: \"a\", 2: \"b\", 3: \"c\" }", + "testString": "assert.deepEqual(arrToObj(...testCases[2]), res[2], 'arrToObj([1, 2, 3], [\"a\", \"b\", \"c\", \"d\", \"e\"]) should return { 1: \"a\", 2: \"b\", 3: \"c\" }');" + }, + { + "text": "arrToObj([\"a\", \"b\", \"c\", \"d\", \"e\"], [1, 2, 3, 4, 5]) should return { \"a\": 1, \"b\": 2, \"c\": 3 , \"d\": 4, \"e\": 5 }", + "testString": "assert.deepEqual(arrToObj(...testCases[3]), res[3], 'arrToObj([\"a\", \"b\", \"c\", \"d\", \"e\"], [1, 2, 3, 4, 5]) should return { \"a\": 1, \"b\": 2, \"c\": 3 , \"d\": 4, \"e\": 5 }');" + }, + { + "text": "arrToObj([\"a\", \"b\", \"c\", \"d\", \"e\"], [1, 2, 3, 4]) should return { \"a\": 1, \"b\": 2, \"c\": 3 , \"d\": 4, \"e\": undefined }", + "testString": "assert.deepEqual(arrToObj(...testCases[4]), res[4], 'arrToObj([\"a\", \"b\", \"c\", \"d\", \"e\"], [1, 2, 3, 4]) should return { \"a\": 1, \"b\": 2, \"c\": 3 , \"d\": 4, \"e\": undefined }');" + }, + { + "text": "arrToObj([\"a\", \"b\", \"c\"], [1, 2, 3, 4, 5]) should return { \"a\": 1, \"b\": 2, \"c\": 3 }", + "testString": "assert.deepEqual(arrToObj(...testCases[5]), res[5], 'arrToObj([\"a\", \"b\", \"c\"], [1, 2, 3, 4, 5]) should return { \"a\": 1, \"b\": 2, \"c\": 3 }');" + } + ], + "id": "595671d4d2cdc305f0d5b36f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function arrToObj (keys, vals) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const testCases = [\n [[1, 2, 3, 4, 5], ['a', 'b', 'c', 'd', 'e']],\n [[1, 2, 3, 4, 5], ['a', 'b', 'c', 'd']],\n [[1, 2, 3], ['a', 'b', 'c', 'd', 'e']],\n [['a', 'b', 'c', 'd', 'e'], [1, 2, 3, 4, 5]],\n [['a', 'b', 'c', 'd', 'e'], [1, 2, 3, 4]],\n [['a', 'b', 'c'], [1, 2, 3, 4, 5]]\n];\n\nconst res = [\n { 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e' },\n { 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: undefined },\n { 1: 'a', 2: 'b', 3: 'c' },\n { a: 1, b: 2, c: 3, d: 4, e: 5 },\n { a: 1, b: 2, c: 3, d: 4, e: undefined },\n { a: 1, b: 2, c: 3 }\n];" + } + } + }, + { + "title": "Hash join", + "type": "Waypoint", + "description": [ + "

An inner join is an operation that combines two data tables into one table, based on matching column values. The simplest way of implementing this operation is the nested loop join algorithm, but a more scalable alternative is the hash join algorithm.

", + "

Implement the \"hash join\" algorithm, and demonstrate that it passes the test-case listed below.

You should represent the tables as data structures that feel natural in your programming language.

", + "

The \"hash join\" algorithm consists of two steps:

", + "Hash phase: Create a multimap from one of the two tables, mapping from each join column value to all the rows that contain it.", + " The multimap must support hash-based lookup which scales better than a simple linear search, because that's the whole point of this algorithm.", + " Ideally we should create the multimap for the smaller table, thus minimizing its creation time and memory size.", + "Join phase: Scan the other table, and find matching rows by looking in the multimap created before.", + "

In pseudo-code, the algorithm could be expressed as follows:

", + "
",
+        "let A = the first input table (or ideally, the larger one)",
+        "let B = the second input table (or ideally, the smaller one)",
+        "let jA = the join column ID of table A",
+        "let jB = the join column ID of table B",
+        "let MB = a multimap for mapping from single values to multiple rows of table B (starts out empty)",
+        "let C = the output table (starts out empty)",
+        "for each row b in table B:",
+        "  place b in multimap MB under key b(jB)",
+        "for each row a in table A:",
+        "  for each row b in multimap MB under key a(jA):",
+        "    let c = the concatenation of row a and row b",
+        "    place row c in table C

", + "
", + "Test-case", + "

Input

", + "", + "", + "", + "
", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "
A =", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "
Age Name", + "
27 Jonah", + "
18 Alan", + "
28 Glory", + "
18 Popeye", + "
28 Alan", + "
", + "
", + " B =", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "
Character Nemesis", + "
Jonah Whales", + "
Jonah Spiders", + "
Alan Ghosts", + "
Alan Zombies", + "
Glory Buffy", + "
", + "
jA =", + " Name (i.e. column 1)", + " jB =", + " Character (i.e. column 0)", + "
", + "
", + "
", + "

Output

", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "
A.Age A.Name B.Character B.Nemesis", + "
27 Jonah Jonah Whales", + "
27 Jonah Jonah Spiders", + "
18 Alan Alan Ghosts", + "
18 Alan Alan Zombies", + "
28 Glory Glory Buffy", + "
28 Alan Alan Ghosts", + "
28 Alan Alan Zombies", + "
", + "

The order of the rows in the output table is not significant.

", + "

If you're using numerically indexed arrays to represent table rows (rather than referring to columns by name), you could represent the output rows in the form [[27, \"Jonah\"], [\"Jonah\", \"Whales\"]].


" + ], + "solutions": [ + "function hashJoin (hash1, hash2) {\n const hJoin = (tblA, tblB, strJoin) => {\n const [jA, jB] = strJoin.split('=');\n const M = tblB.reduce((a, x) => {\n const id = x[jB];\n return (\n a[id] ? a[id].push(x) : (a[id] = [x]),\n a\n );\n }, {});\n\n return tblA.reduce((a, x) => {\n const match = M[x[jA]];\n return match ? (\n a.concat(match.map(row => dictConcat(x, row)))\n ) : a;\n }, []);\n };\n\n const dictConcat = (dctA, dctB) => {\n const ok = Object.keys;\n return ok(dctB).reduce(\n (a, k) => (a[`B_${k}`] = dctB[k]) && a,\n ok(dctA).reduce(\n (a, k) => (a[`A_${k}`] = dctA[k]) && a, {}\n )\n );\n };\n\n return hJoin(hash1, hash2, 'name=character');\n}\n\n" + ], + "tests": [ + { + "text": "hashJoin is a function.", + "testString": "assert(typeof hashJoin === 'function', 'hashJoin is a function.');" + }, + { + "text": "hashJoin([{ age: 27, name: \"Jonah\" }, { age: 18, name: \"Alan\" }, { age: 28, name: \"Glory\" }, { age: 18, name: \"Popeye\" }, { age: 28, name: \"Alan\" }], [{ character: \"Jonah\", nemesis: \"Whales\" }, { character: \"Jonah\", nemesis: \"Spiders\" }, { character: \"Alan\", nemesis: \"Ghosts\" }, { character:\"Alan\", nemesis: \"Zombies\" }, { character: \"Glory\", nemesis: \"Buffy\" }, { character: \"Bob\", nemesis: \"foo\" }]) should return [{\"A_age\": 27,\"A_name\": \"Jonah\", \"B_character\": \"Jonah\", \"B_nemesis\": \"Whales\"}, {\"A_age\": 27,\"A_name\": \"Jonah\", \"B_character\": \"Jonah\", \"B_nemesis\": \"Spiders\"}, {\"A_age\": 18,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Ghosts\"}, {\"A_age\": 18,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Zombies\"}, {\"A_age\": 28,\"A_name\": \"Glory\", \"B_character\": \"Glory\", \"B_nemesis\": \"Buffy\"}, {\"A_age\": 28,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Ghosts\"}, {\"A_age\": 28,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Zombies\"}]", + "testString": "assert.deepEqual(hashJoin(hash1, hash2), res, 'hashJoin([{ age: 27, name: \"Jonah\" }, { age: 18, name: \"Alan\" }, { age: 28, name: \"Glory\" }, { age: 18, name: \"Popeye\" }, { age: 28, name: \"Alan\" }], [{ character: \"Jonah\", nemesis: \"Whales\" }, { character: \"Jonah\", nemesis: \"Spiders\" }, { character: \"Alan\", nemesis: \"Ghosts\" }, { character:\"Alan\", nemesis: \"Zombies\" }, { character: \"Glory\", nemesis: \"Buffy\" }, { character: \"Bob\", nemesis: \"foo\" }]) should return [{\"A_age\": 27,\"A_name\": \"Jonah\", \"B_character\": \"Jonah\", \"B_nemesis\": \"Whales\"}, {\"A_age\": 27,\"A_name\": \"Jonah\", \"B_character\": \"Jonah\", \"B_nemesis\": \"Spiders\"}, {\"A_age\": 18,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Ghosts\"}, {\"A_age\": 18,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Zombies\"}, {\"A_age\": 28,\"A_name\": \"Glory\", \"B_character\": \"Glory\", \"B_nemesis\": \"Buffy\"}, {\"A_age\": 28,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Ghosts\"}, {\"A_age\": 28,\"A_name\": \"Alan\", \"B_character\": \"Alan\", \"B_nemesis\": \"Zombies\"}]');" + } + ], + "id": "5956795bc9e2c415eb244de1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function hashJoin (hash1, hash2) {", + " // Good luck!", + " return [];", + "}" + ], + "head": "", + "tail": "const hash1 = [\n { age: 27, name: 'Jonah' },\n { age: 18, name: 'Alan' },\n { age: 28, name: 'Glory' },\n { age: 18, name: 'Popeye' },\n { age: 28, name: 'Alan' }\n];\n\nconst hash2 = [\n { character: 'Jonah', nemesis: 'Whales' },\n { character: 'Jonah', nemesis: 'Spiders' },\n { character: 'Alan', nemesis: 'Ghosts' },\n { character: 'Alan', nemesis: 'Zombies' },\n { character: 'Glory', nemesis: 'Buffy' },\n { character: 'Bob', nemesis: 'foo' }\n];\n\nconst res = [\n { A_age: 27, A_name: 'Jonah', B_character: 'Jonah', B_nemesis: 'Whales' },\n { A_age: 27, A_name: 'Jonah', B_character: 'Jonah', B_nemesis: 'Spiders' },\n { A_age: 18, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Ghosts' },\n { A_age: 18, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Zombies' },\n { A_age: 28, A_name: 'Glory', B_character: 'Glory', B_nemesis: 'Buffy' },\n { A_age: 28, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Ghosts' },\n { A_age: 28, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Zombies' }\n];\n\nconst bench1 = [{ name: 'u2v7v', num: 1 }, { name: 'n53c8', num: 10 }, { name: 'oysce', num: 9 }, { name: '0mto2s', num: 1 }, { name: 'vkh5id', num: 4 }, { name: '5od0cf', num: 8 }, { name: 'uuulue', num: 10 }, { name: '3rgsbi', num: 9 }, { name: 'kccv35r', num: 4 }, { name: '80un74', num: 9 }, { name: 'h4pp3', num: 6 }, { name: '51bit', num: 7 }, { name: 'j9ndf', num: 8 }, { name: 'vf3u1', num: 10 }, { name: 'g0bw0om', num: 10 }, { name: 'j031x', num: 7 }, { name: 'ij3asc', num: 9 }, { name: 'byv83y', num: 8 }, { name: 'bjzp4k', num: 4 }, { name: 'f3kbnm', num: 10 }];\nconst bench2 = [{ friend: 'o8b', num: 8 }, { friend: 'ye', num: 2 }, { friend: '32i', num: 5 }, { friend: 'uz', num: 3 }, { friend: 'a5k', num: 4 }, { friend: 'uad', num: 7 }, { friend: '3w5', num: 10 }, { friend: 'vw', num: 10 }, { friend: 'ah', num: 4 }, { friend: 'qv', num: 7 }, { friend: 'ozv', num: 2 }, { friend: '9ri', num: 10 }, { friend: '7nu', num: 4 }, { friend: 'w3', num: 9 }, { friend: 'tgp', num: 8 }, { friend: 'ibs', num: 1 }, { friend: 'ss7', num: 6 }, { friend: 'g44', num: 9 }, { friend: 'tab', num: 9 }, { friend: 'zem', num: 10 }];" + } + } + }, + { + "title": "Heronian triangles", + "type": "Waypoint", + "description": [ + "

Hero's formula for the area of a triangle given the length of its three sides a, b, and c is given by:

$$A = \\sqrt{s(s-a)(s-b)(s-c)},$$

where s is half the perimeter of the triangle; that is,

$$s=\\frac{a+b+c}{2}.$$

", + "

Heronian triangles are triangles whose sides and area are all integers.

", + "

An example is the triangle with sides 3, 4, 5 whose area is 6 (and whose perimeter is 12).

", + "

Note that any triangle whose sides are all an integer multiple of 3, 4, 5; such as 6, 8, 10, will also be a Heronian triangle.

Define a Primitive Heronian triangle as a Heronian triangle where the greatest common divisor

", + "

of all three sides is 1 (unity).

This will exclude, for example, triangle 6, 8, 10.

", + "Task:", + "

Implement a function based on Hero's formula that returns the first nth ordered triangles in an array of arrays.

" + ], + "solutions": [ + "// noprotect\nfunction heronianTriangle (n) {\n const list = [];\n const result = [];\n\n let j = 0;\n for (let c = 1; c <= 200; c++) {\n for (let b = 1; b <= c; b++) {\n for (let a = 1; a <= b; a++) {\n if (gcd(gcd(a, b), c) === 1 && isHeron(heronArea(a, b, c))) {\n list[j++] = new Array(a, b, c, heronArea(a, b, c));\n }\n }\n }\n }\n\n sort(list);\n\n for (let i = 0; i < n; i++) {\n result[i] = [list[i][0], list[i][1], list[i][2]];\n }\n\n return result;\n\n function heronArea(a, b, c) {\n const s = (a + b + c) / 2;\n return Math.sqrt(s * (s - a) * (s - b) * (s - c));\n }\n\n function isHeron(h) { return h % 1 === 0 && h > 0; }\n\n function gcd(a, b) {\n let leftover = 1;\n let dividend = a > b ? a : b;\n let divisor = a > b ? b : a;\n while (leftover !== 0) {\n leftover = dividend % divisor;\n if (leftover > 0) {\n dividend = divisor;\n divisor = leftover;\n }\n }\n return divisor;\n }\n\n function sort(arg) {\n let swapped = true;\n let temp = [];\n while (swapped) {\n swapped = false;\n for (let i = 1; i < arg.length; i++) {\n if (arg[i][4] < arg[i - 1][4] || arg[i][4] === arg[i - 1][4] && arg[i][3] < arg[i - 1][3]) {\n temp = arg[i];\n arg[i] = arg[i - 1];\n arg[i - 1] = temp;\n swapped = true;\n }\n }\n }\n }\n}\n" + ], + "tests": [ + { + "text": "heronianTriangle is a function.", + "testString": "assert(typeof heronianTriangle === 'function', 'heronianTriangle is a function.');" + }, + { + "text": "heronianTriangle() should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17]]", + "testString": "assert.deepEqual(heronianTriangle(testCases[0]), res[0], 'heronianTriangle() should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17]]');" + }, + { + "text": "heronianTriangle() should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15]],", + "testString": "assert.deepEqual(heronianTriangle(testCases[1]), res[1], 'heronianTriangle() should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15]],');" + }, + { + "text": "heronianTriangle() should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53]],", + "testString": "assert.deepEqual(heronianTriangle(testCases[2]), res[2], 'heronianTriangle() should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53]],');" + }, + { + "text": "heronianTriangle() should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53], [19, 20, 37],[16, 17, 17], [17, 17, 30], [16, 25, 39], [13, 20, 21]]", + "testString": "assert.deepEqual(heronianTriangle(testCases[3]), res[3], 'heronianTriangle() should return [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53], [19, 20, 37],[16, 17, 17], [17, 17, 30], [16, 25, 39], [13, 20, 21]]');" + } + ], + "id": "595b98f8b5a2245e243aa831", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "// noprotect", + "function heronianTriangle (n) {", + " // Good luck!", + "", + " return [];", + "}" + ], + "head": "", + "tail": "const testCases = [10, 15, 20, 25];\n\nconst res = [\n [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17]],\n [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15]],\n [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53]],\n [[3, 4, 5], [5, 5, 6], [5, 5, 8], [4, 13, 15], [5, 12, 13], [9, 10, 17], [3, 25, 26], [7, 15, 20], [10, 13, 13], [8, 15, 17], [13, 13, 24], [6, 25, 29], [11, 13, 20], [5, 29, 30], [13, 14, 15], [10, 17, 21], [7, 24, 25], [8, 29, 35], [12, 17, 25], [4, 51, 53], [19, 20, 37], [16, 17, 17], [17, 17, 30], [16, 25, 39], [13, 20, 21]]\n];" + } + } + }, + { + "title": "Hofstadter Figure-Figure sequences", + "type": "Waypoint", + "description": [ + "

These two sequences of positive integers are defined as:

", + "

$$R(1)=1\\ ;\\ S(1)=2 \\\\R(n)=R(n-1)+S(n-1), \\quad n>1.$$

", + "

The sequence $S(n)$ is further defined as the sequence of positive integers not present in $R(n)$.

Sequence $R$ starts:

", + "

1, 3, 7, 12, 18, ...

", + "

Sequence $S$ starts:

", + "

2, 4, 5, 6, 8, ...

", + "Task:", + "Create two functions named ffr and ffs that when given n return R(n) or S(n) respectively.(Note that R(1) = 1 and S(1) = 2 to avoid off-by-one errors).", + "No maximum value for n should be assumed.", + "Sloane's A005228 and A030124.", + "Wolfram MathWorld", + "Wikipedia: Hofstadter Figure-Figure sequences." + ], + "solutions": [ + "// noprotect\nconst R = [null, 1];\nconst S = [null, 2];\n\nfunction extendSequences (n) {\n let current = Math.max(R[R.length - 1], S[S.length - 1]);\n let i;\n while (R.length <= n || S.length <= n) {\n i = Math.min(R.length, S.length) - 1;\n current += 1;\n if (current === R[i] + S[i]) {\n R.push(current);\n } else {\n S.push(current);\n }\n }\n}\n\nfunction ffr (n) {\n extendSequences(n);\n return R[n];\n}\n\nfunction ffs (n) {\n extendSequences(n);\n return S[n];\n}\n" + ], + "tests": [ + { + "text": "ffr is a function.", + "testString": "assert(typeof ffr === 'function', 'ffr is a function.');" + }, + { + "text": "ffs is a function.", + "testString": "assert(typeof ffs === 'function', 'ffs is a function.');" + }, + { + "text": "ffr should return integer.", + "testString": "assert(Number.isInteger(ffr(1)), 'ffr should return integer.');" + }, + { + "text": "ffs should return integer.", + "testString": "assert(Number.isInteger(ffs(1)), 'ffs should return integer.');" + }, + { + "text": "ffr() should return 69", + "testString": "assert.equal(ffr(ffrParamRes[0][0]), ffrParamRes[0][1], 'ffr() should return 69');" + }, + { + "text": "ffr() should return 1509", + "testString": "assert.equal(ffr(ffrParamRes[1][0]), ffrParamRes[1][1], 'ffr() should return 1509');" + }, + { + "text": "ffr() should return 5764", + "testString": "assert.equal(ffr(ffrParamRes[2][0]), ffrParamRes[2][1], 'ffr() should return 5764');" + }, + { + "text": "ffr() should return 526334", + "testString": "assert.equal(ffr(ffrParamRes[3][0]), ffrParamRes[3][1], 'ffr() should return 526334');" + }, + { + "text": "ffs() should return 14", + "testString": "assert.equal(ffs(ffsParamRes[0][0]), ffsParamRes[0][1], 'ffs() should return 14');" + }, + { + "text": "ffs() should return 59", + "testString": "assert.equal(ffs(ffsParamRes[1][0]), ffsParamRes[1][1], 'ffs() should return 59');" + }, + { + "text": "ffs() should return 112", + "testString": "assert.equal(ffs(ffsParamRes[2][0]), ffsParamRes[2][1], 'ffs() should return 112');" + }, + { + "text": "ffs() should return 1041", + "testString": "assert.equal(ffs(ffsParamRes[3][0]), ffsParamRes[3][1], 'ffs() should return 1041');" + } + ], + "id": "59622f89e4e137560018a40e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "// noprotect", + "function ffr(n) {", + " return n;", + "}", + "", + "function ffs(n) {", + " return n;", + "}" + ], + "head": "", + "tail": "const ffrParamRes = [[10, 69], [50, 1509], [100, 5764], [1000, 526334]];\nconst ffsParamRes = [[10, 14], [50, 59], [100, 112], [1000, 1041]];\n" + } + } + }, + { + "title": "Hofstadter Q sequence", + "type": "Waypoint", + "description": [ + "

The Hofstadter Q sequence is defined as:

", + "

$Q(1)=Q(2)=1, \\\\ Q(n)=Q\\big(n-Q(n-1)\\big)+Q\\big(n-Q(n-2)), \\quad n>2.$

", + "

It is defined like the Fibonacci sequence, but whereas the next term in the Fibonacci sequence is the sum of the previous two terms, in the Q sequence the previous two terms tell you how far to go back in the Q sequence to find the two numbers to sum to make the next term of the sequence.

", + "Task:", + "Implement the Hofstadter Q Sequence equation into JavaScript" + ], + "solutions": [ + "function hofstadterQ (n) {\n const memo = [1, 1, 1];\n const Q = function (i) {\n let result = memo[i];\n if (typeof result !== 'number') {\n result = Q(i - Q(i - 1)) + Q(i - Q(i - 2));\n memo[i] = result;\n }\n return result;\n };\n return Q(n);\n}\n" + ], + "tests": [ + { + "text": "hofstadterQ is a function.", + "testString": "assert(typeof hofstadterQ === 'function', 'hofstadterQ is a function.');" + }, + { + "text": "hofstadterQ() should return integer", + "testString": "assert(Number.isInteger(hofstadterQ(1000)), 'hofstadterQ() should return integer');" + }, + { + "text": "hofstadterQ(1000) should return 502", + "testString": "assert.equal(hofstadterQ(testCase[0]), res[0], 'hofstadterQ(1000) should return 502');" + }, + { + "text": "hofstadterQ(1500) should return 755", + "testString": "assert.equal(hofstadterQ(testCase[1]), res[1], 'hofstadterQ(1500) should return 755');" + }, + { + "text": "hofstadterQ(2000) should return 1005", + "testString": "assert.equal(hofstadterQ(testCase[2]), res[2], 'hofstadterQ(2000) should return 1005');" + }, + { + "text": "hofstadterQ(2500) should return 1261", + "testString": "assert.equal(hofstadterQ(testCase[3]), res[3], 'hofstadterQ(2500) should return 1261');" + } + ], + "id": "59637c4d89f6786115efd814", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function hofstadterQ (n) {", + " // Good luck!", + " return n;", + "}" + ], + "head": "", + "tail": "const testCase = [1000, 1500, 2000, 2500];\nconst res = [502, 755, 1005, 1261];" + } + } + }, + { + "title": "Sailors, coconuts and a monkey problem", + "type": "Waypoint", + "description": [ + " ", + "

", + " Five sailors are shipwrecked on an island and", + " collect a large pile of coconuts during the day.", + "

", + "

That night the first sailor wakes up and decides", + " to take his first share early so tries to divide the pile of coconuts equally", + " into five piles but finds that there is one coconut left over, so he tosses it", + " to a monkey and then hides \"his\" one of the five equally sized piles of", + " coconuts and pushes the other four piles together to form a single visible pile", + " of coconuts again and goes to bed.", + "

", + "

", + " To cut a long story short, each of the sailors in", + " turn gets up once during the night and performs the same actions of dividing", + " the coconut pile into five, finding that one coconut is left over and giving", + " that single remainder coconut to the monkey.", + "

", + "

", + " In the morning (after the surreptitious and", + " separate action of each of the five sailors during the night), the remaining", + " coconuts are divided into five equal piles for each of the sailors, whereupon", + " it is found that the pile of coconuts divides equally amongst the sailors with", + " no remainder. (Nothing for the monkey in the morning.)", + "

", + " ", + " The task:", + " ", + " ", + " Create a function that returns the", + " the minimum possible size", + " of the initial pile of coconuts collected during the day for N", + " sailors.", + " ", + " ", + " Note:", + " ", + " ", + " Of course the tale is told in a", + " world where the collection of any amount of coconuts in a day and multiple", + " divisions of the pile, etc can occur in time fitting the story line, so as", + " not to affect the mathematics.", + " ", + " ", + " ", + " C.f:", + " ", + " ", + " Monkeys and Coconuts - Numberphile (Video) Analytical solution.", + " ", + " ", + " A002021 Pile of coconuts problem The On-Line", + " Encyclopedia of Integer Sequences. (Although some of its references may use", + " the alternate form of the tale).", + " ", + " ", + " " + ], + "solutions": [ + "// noprotect\nfunction splitCoconuts(intSailors) {\n let intNuts = intSailors;\n let result = splitCoconutsHelper(intNuts, intSailors);\n while (!result) {\n intNuts += 1;\n result = splitCoconutsHelper(intNuts, intSailors);\n }\n\n return intNuts;\n}\n\nfunction splitCoconutsHelper(intNuts, intSailors, intDepth) {\n const nDepth = intDepth !== undefined ? intDepth : intSailors;\n const portion = Math.floor(intNuts / intSailors);\n const remain = intNuts % intSailors;\n\n if (portion <= 0 || remain !== (nDepth ? 1 : 0)) {\n return null;\n }\n\n if (nDepth) {\n return splitCoconutsHelper(\n intNuts - portion - remain, intSailors, nDepth - 1\n );\n }\n\n return intNuts;\n}\n" + ], + "tests": [ + { + "text": "splitCoconuts is a function.", + "testString": "assert(typeof splitCoconuts === 'function', 'splitCoconuts is a function.');" + }, + { + "text": "splitCoconuts(5) should return 3121.", + "testString": "assert(splitCoconuts(5) === 3121, 'splitCoconuts(5) should return 3121.');" + }, + { + "text": "splitCoconuts(6) should return 233275.", + "testString": "assert(splitCoconuts(6) === 233275, 'splitCoconuts(6) should return 233275.');" + }, + { + "text": "splitCoconuts(7) should return 823537.", + "testString": "assert(splitCoconuts(7) === 823537, 'splitCoconuts(7) should return 823537.');" + } + ], + "id": "59da22823d04c95919d46269", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "// noprotect", + "function splitCoconuts(intSailors) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "" + } + } + }, + { + "title": "SEDOLs", + "type": "Waypoint", + "null": [], + "description": [ + " ", + " ", + " Task:", + " ", + "

", + " For each number list of 6-digit ", + " SEDOLs,", + " calculate and append the checksum digit.", + "

", + " ", + "

", + " That is, given the input string on the left, your function should return the", + " corresponding string on the right:", + "

", + " ", + "
",
+        "     710889 => 7108899",
+        "     B0YBKJ => B0YBKJ7",
+        "     406566 => 4065663",
+        "     B0YBLH => B0YBLH2",
+        "     228276 => 2282765",
+        "     B0YBKL => B0YBKL9",
+        "     557910 => 5579107",
+        "     B0YBKR => B0YBKR5",
+        "     585284 => 5852842",
+        "     B0YBKT => B0YBKT7",
+        "     B00030 => B000300",
+        "    
", + " ", + "

", + " Check also that each input is correctly formed, especially", + " with respect to valid characters allowed in a SEDOL string. Your function", + " should return null on invalid input.", + "

" + ], + "solutions": [ + "function sedol(input) {\n const checkDigit = sedolCheckDigit(input);\n if (checkDigit !== null) {\n return input + checkDigit;\n }\n return null;\n}\n\nconst weight = [1, 3, 1, 7, 3, 9, 1];\nfunction sedolCheckDigit(char6) {\n if (char6.search(/^[0-9BCDFGHJKLMNPQRSTVWXYZ]{6}$/) === -1) {\n return null;\n }\n\n let sum = 0;\n for (let i = 0; i < char6.length; i++) {\n sum += weight[i] * parseInt(char6.charAt(i), 36);\n }\n const check = (10 - (sum % 10)) % 10;\n return check.toString();\n}\n" + ], + "tests": [ + { + "text": "sedol is a function.", + "testString": "assert(typeof sedol === 'function', 'sedol is a function.');" + }, + { + "text": "sedol('a') should return null.\")", + "testString": "assert(sedol('a') === null, \"sedol('a') should return null.\");" + }, + { + "text": "sedol('710889') should return '7108899'.\")", + "testString": "assert(sedol('710889') === '7108899', \"sedol('710889') should return '7108899'.\");" + }, + { + "text": "sedol('BOATER') should return null.\")", + "testString": "assert(sedol('BOATER') === null, \"sedol('BOATER') should return null.\");" + }, + { + "text": "sedol('228276') should return '2282765'.\")", + "testString": "assert(sedol('228276') === '2282765', \"sedol('228276') should return '2282765'.\");" + }, + { + "text": "Should return the correct answer when pases a random string from a list. ", + "testString": "assert(sedol(inputVal) === expVal, randMsg);" + } + ], + "id": "59d9c6bc214c613ba73ff012", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function sedol (input) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const input = [\n '710889', 'B0YBKJ', '406566', 'B0YBLH', '228276',\n 'B0YBKL', '557910', 'B0YBKR', '585284', 'B0YBKT',\n 'BOATER', '12345', '123456', '1234567', 'ABBAAC',\n '767642', 'B33FAC', 'H3FH3F', 'C0M3D1', 'GOOGL3',\n 'APPPL3'\n];\n\nconst expected = [\n '7108899', 'B0YBKJ7', '4065663', 'B0YBLH2', '2282765',\n 'B0YBKL9', '5579107', 'B0YBKR5', '5852842', 'B0YBKT7',\n null, null, '1234563', null, null, '7676426',\n null, 'H3FH3F6', 'C0M3D17', null, null\n];\n\nconst inputLen = input.length;\nconst randIndex = Math.floor(Math.random(new Date().getTime()) * inputLen);\nconst inputVal = input[randIndex];\nconst expVal = expected[randIndex];\nconst randMsg = `message: sedol('${inputVal}') should return '${expVal}'.`;" + } + } + }, + { + "title": "S-Expressions", + "type": "Waypoint", + "description": [ + "

", + "S-Expressions are one convenient way to parse and store data.", + "

", + "Task:", + "

", + " Write a simple reader/parser for S-Expressions that handles quoted and unquoted strings, integers and floats.", + "

", + "

", + "The function should read a single but nested S-Expression from a string and", + "return it as a (nested) array.", + "

", + "

", + " Newlines and other whitespace may be ignored unless contained within a quoted string.", + "

", + "

()” inside quoted strings are not interpreted, but treated as part of the string.", + "

", + "

", + "Handling escaped quotes inside a string is optional; thus “(foo\"bar)” maybe treated as a string “foo\"bar”, or as an error.", + "

", + "

", + "For this, the reader need not recognize “\\” for escaping, but should, in addition, recognize numbers if the language has appropriate datatypes.", + "

", + "

", + "Note that with the exception of “()\"” (“\\” if escaping is supported) and whitespace there are no special characters. Anything else is allowed without quotes.", + "

", + "

The reader should be able to read the following input

", + "

", + "

",
+        "    ((data \"quoted data\" 123 4.5)",
+        "    (data (!@# (4.5) \"(more\" \"data)\")))",
+        "
", + "

", + "

", + "and turn it into a native datastructure. (see the", + "Pike, ", + "Python and", + "Ruby implementations", + "for examples of native data structures.)", + "

" + ], + "solutions": [ + "function parseSexpr(str) {\n const t = str.match(/\\s*(\"[^\"]*\"|\\(|\\)|\"|[^\\s()\"]+)/g);\n for (var o, c = 0, i = t.length - 1; i >= 0; i--) {\n var n,\n ti = t[i].trim();\n if (ti == '\"') return;\n else if (ti == '(') t[i] = '[', c += 1;\n else if (ti == ')') t[i] = ']', c -= 1;\n else if ((n = +ti) == ti) t[i] = n;\n else t[i] = `'${ti.replace('\\'', '\\\\\\'')}'`;\n if (i > 0 && ti != ']' && t[i - 1].trim() != '(') t.splice(i, 0, ',');\n if (!c) if (!o) o = true; else return;\n }\n return c ? undefined : eval(t.join(''));\n}\n" + ], + "tests": [ + { + "text": "parseSexpr is a function.", + "testString": "assert(typeof parseSexpr === 'function', 'parseSexpr is a function.');" + }, + { + "text": "parseSexpr('(data1 data2 data3)') should return ['data1', 'data2', 'data3']\")", + "testString": "assert.deepEqual(parseSexpr(simpleSExpr), simpleSolution, \"parseSexpr('(data1 data2 data3)') should return ['data1', 'data2', 'data3']\");" + }, + { + "text": "parseSexpr('(data1 data2 data3)') should return an array with 3 elements\")", + "testString": "assert.deepEqual(parseSexpr(basicSExpr), basicSolution, \"parseSexpr('(data1 data2 data3)') should return an array with 3 elements\");" + } + ], + "id": "59667989bf71cf555dd5d2ff", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function parseSexpr(str) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const simpleSExpr = '(data1 data2 data3)';\nconst simpleSolution = ['data1', 'data2', 'data3'];\n\nconst basicSExpr = '((data \"quoted data\" 123 4.5) (data (!@# (4.5) \"(more\" \"data)\")))';\nconst basicSolution = [[\"data\",\"\\\"quoted data\\\"\",123,4.5],[\"data\",[\"!@#\",[4.5],\"\\\"(more\\\"\",\"\\\"data)\\\"\"]]];" + } + } + }, + { + "title": "Taxicab numbers", + "type": "Waypoint", + "description": [ + "A   taxicab number", + "  (the definition that is being used here)   is a positive integer that can be expressed as the sum of two positive cubes in more than one way.", + "The first taxicab number is   1729,   which is:", + "13   +   123       and", + "93   +   103.", + "Taxicab numbers are also known as:", + " *   taxi numbers", + " *   taxi-cab numbers", + " *   taxi cab numbers", + " *   Hardy-Ramanujan numbers", + "Task:", + "Write a function that returns the lowest N taxicab numbers.", + "For each of the taxicab numbers, show the number as well as it's constituent cubes.", + "See also:", + "[http://oeis.org/A001235 A001235 taxicab numbers] on The On-Line Encyclopedia of Integer Sequences.", + " Hardy-Ramanujan Number on MathWorld.", + " taxicab number on MathWorld.", + " taxicab number on Wikipedia." + ], + "solutions": [ + "function taxicabNumbers(nNumbers) {\n const cubeN = [];\n const s3s = {};\n\n const e = 100;\n for (let n = 1; n < e; n += 1) {\n cubeN[n] = n * n * n;\n }\n\n for (let a = 1; a < e - 1; a += 1) {\n const a3 = cubeN[a];\n for (let b = a; b < e; b += 1) {\n const b3 = cubeN[b];\n const s3 = a3 + b3;\n\n let abs = s3s[s3];\n if (!abs) {\n s3s[s3] = abs = [];\n }\n abs.push([a, b]);\n }\n }\n\n let i = 0;\n const res = [];\n Object.keys(s3s).forEach(s3 => {\n const abs = s3s[s3];\n if (abs.length >= 2) { // No two cube pairs found\n i += 1;\n if (i <= nNumbers) {\n res.push(s3);\n }\n }\n });\n return res.map(item => parseInt(item, 10));\n}\n" + ], + "tests": [ + { + "text": "taxicabNumbers is a function.", + "testString": "assert(typeof taxicabNumbers === 'function', 'taxicabNumbers is a function.');" + }, + { + "text": "taxicabNumbers should return an array.", + "testString": "assert(typeof taxicabNumbers(2) === 'object', 'taxicabNumbers should return an array.');" + }, + { + "text": "taxicabNumbers should return an array of numbers.", + "testString": "assert(typeof taxicabNumbers(100)[0] === 'number', 'taxicabNumbers should return an array of numbers.');" + }, + { + "text": "taxicabNumbers(4) must return [1729, 4104, 13832, 20683].", + "testString": "assert.deepEqual(taxicabNumbers(4), res4, 'taxicabNumbers(4) must return [1729, 4104, 13832, 20683].');" + }, + { + "text": "taxicabNumbers(25) should return [1729, 4104, 13832, 20683, 32832, 39312, 40033, 46683, 64232, 65728, 110656, 110808, 134379, 149389, 165464, 171288, 195841, 216027, 216125, 262656, 314496, 320264, 327763, 373464, 402597]", + "testString": "assert.deepEqual(taxicabNumbers(25), res25, 'taxicabNumbers(25) should return [1729, 4104, 13832, 20683, 32832, 39312, 40033, 46683, 64232, 65728, 110656, 110808, 134379, 149389, 165464, 171288, 195841, 216027, 216125, 262656, 314496, 320264, 327763, 373464, 402597]');" + }, + { + "text": "taxicabNumbers(39) resulting numbers from 20 - 29 should be [314496,320264,327763,373464,402597,439101,443889,513000,513856].", + "testString": "assert.deepEqual(taxicabNumbers(39).slice(20, 29), res39From20To29, 'taxicabNumbers(39) resulting numbers from 20 - 29 should be [314496,320264,327763,373464,402597,439101,443889,513000,513856].');" + } + ], + "id": "594ecc0d9a8cf816e3340187", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function taxicabNumbers (n) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const res4 = [1729, 4104, 13832, 20683];\nconst res25 = [\n 1729, 4104, 13832, 20683, 32832, 39312, 40033, 46683, 64232, 65728, 110656,\n 110808, 134379, 149389, 165464, 171288, 195841, 216027, 216125, 262656, 314496, 320264, 327763,\n 373464, 402597\n];\n\nconst res39From20To29 = [314496, 320264, 327763, 373464, 402597, 439101, 443889, 513000, 513856];" + } + } + }, + { + "title": "Tokenize a string with escaping", + "type": "Waypoint", + "description": [ + "

", + "Write a function or program that can split a string at each non-escaped occurrence of a separator character.", + "

", + "

", + "It should accept three input parameters:", + "

", + " The string", + " The separator character", + " The escape character", + "

It should output a list of strings.

", + "

Rules for splitting:

", + " The fields that were separated by the separators, become the elements of the output list.", + " Empty fields should be preserved, even at the start and end.", + "

Rules for escaping:

", + " \"Escaped\" means preceded by an occurrence of the escape character that is not already escaped itself.", + " When the escape character precedes a character that has no special meaning, it still counts as an escape (but does not do anything special).", + " Each occurrences of the escape character that was used to escape something, should not become part of the output.", + "

Demonstrate that your function satisfies the following test-case:", + " Given string

one^|uno||three^^^^|four^^^|^cuatro|
and using", + "
|
as a separator and
^
as escape character, your", + " function should output the following array:", + "

", + "
",
+        "  ['one|uno', '', 'three^^', 'four^|quatro', '']",
+        "  
" + ], + "solutions": [ + "// tokenize :: String -> Character -> Character -> [String]\nfunction tokenize(str, charDelim, charEsc) {\n const dctParse = str.split('')\n .reduce((a, x) => {\n const blnEsc = a.esc;\n const blnBreak = !blnEsc && x === charDelim;\n const blnEscChar = !blnEsc && x === charEsc;\n\n return {\n esc: blnEscChar,\n token: blnBreak ? '' : (\n a.token + (blnEscChar ? '' : x)\n ),\n list: a.list.concat(blnBreak ? a.token : [])\n };\n }, {\n esc: false,\n token: '',\n list: []\n });\n\n return dctParse.list.concat(\n dctParse.token\n );\n}\n" + ], + "tests": [ + { + "text": "tokenize is a function.", + "testString": "assert(typeof tokenize === 'function', 'tokenize is a function.');" + }, + { + "text": "tokenize should return an array.", + "testString": "assert(typeof tokenize('a', 'b', 'c') === 'object', 'tokenize should return an array.');" + }, + { + "text": "tokenize('one^|uno||three^^^^|four^^^|^cuatro|', '|', '^') should return ['one|uno', '', 'three^^', 'four^|cuatro', '']\")", + "testString": "assert.deepEqual(tokenize(testStr1, '|', '^'), res1, \"tokenize('one^|uno||three^^^^|four^^^|^cuatro|', '|', '^') should return ['one|uno', '', 'three^^', 'four^|cuatro', '']\");" + }, + { + "text": "hi', '&', '@') should return ['a&bcd', 'ef', '', '@hi']\");", + "testString": "assert.deepEqual(tokenize(testStr2, '&', '@'), res2, \"tokenize('a@&bcd&ef&&" + } + ], + "id": "594faaab4e2a8626833e9c3d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function tokenize(str, esc, sep) {", + " return true;", + "}" + ], + "head": "", + "tail": "const testStr1 = 'one^|uno||three^^^^|four^^^|^cuatro|';\nconst res1 = ['one|uno', '', 'three^^', 'four^|cuatro', ''];\n\n// TODO add more tests\nconst testStr2 = 'a@&bcd&ef&&@@hi';\nconst res2 = ['a&bcd', 'ef', '', '@hi'];" + } + } + }, + { + "title": "Topological sort", + "type": "Waypoint", + "description": [ + "

", + "Given a mapping between items, and items they depend on, a ", + "topological sort orders ", + "items so that no item precedes an item it depends upon.", + "

", + "

", + "The compiling of a library in the ", + "VHDL language", + "has the constraint that a library must be compiled after any library it depends on.", + "

", + "Task:", + "

", + "Write a function that will return a valid compile order of VHDL libraries from their dependencies.", + "

", + " Assume library names are single words. ", + " Items mentioned as only dependents have no dependents of their own, but their order of compiling must be given.", + " Any self dependencies should be ignored. ", + " Any un-orderable dependencies should be ignored.", + "

Use the following data as an example:

", + "
",
+        "LIBRARY          LIBRARY DEPENDENCIES",
+        "=======          ====================",
+        "des_system_lib   std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee",
+        "dw01             ieee dw01 dware gtech",
+        "dw02             ieee dw02 dware",
+        "dw03             std synopsys dware dw03 dw02 dw01 ieee gtech",
+        "dw04             dw04 ieee dw01 dware gtech",
+        "dw05             dw05 ieee dware",
+        "dw06             dw06 ieee dware",
+        "dw07             ieee dware",
+        "dware            ieee dware",
+        "gtech            ieee gtech",
+        "ramlib           std ieee",
+        "std_cell_lib     ieee std_cell_lib",
+        "synopsys",
+        "
", + "

", + "Note: the above data would be un-orderable if, for example, dw04 is added to the list of dependencies of dw01.", + "

", + "C.f.:", + " ", + " Topological sort/Extracted top item.", + " ", + "

There are two popular algorithms for topological sorting:

", + "

", + " Kahn's 1962 topological sort, and depth-first search:", + " topological sort", + "

", + "

", + " Jason Sachs:", + " ", + " \"Ten little algorithms, part 4: topological sort\"", + " .", + "

" + ], + "solutions": [ + "function topologicalSort(libs) {\n // A map of the input data, with the keys as the packages, and the values as\n // and array of packages on which it depends.\n const D = libs\n .split('\\n')\n .map(e => e.split(' ').filter(ep => ep !== ''))\n .reduce((p, c) =>\n p.set(c[0], c.filter((e, i) => (i > 0 && e !== c[0] ? e : null))), new Map());\n [].concat(...D.values()).forEach(e => {\n D.set(e, D.get(e) || []);\n });\n\n // The above map rotated so that it represents a DAG of the form\n // Map {\n // A => [ A, B, C],\n // B => [C],\n // C => []\n // }\n // where each key represents a node, and the array contains the edges.\n const G = [...D.keys()].reduce((p, c) =>\n p.set(\n c,\n [...D.keys()].filter(e => D.get(e).includes(c))),\n new Map()\n );\n\n // An array of leaf nodes; nodes with 0 in degrees.\n const Q = [...D.keys()].filter(e => D.get(e).length === 0);\n\n // The result array.\n const S = [];\n while (Q.length) {\n const u = Q.pop();\n S.push(u);\n G.get(u).forEach(v => {\n D.set(v, D.get(v).filter(e => e !== u));\n if (D.get(v).length === 0) {\n Q.push(v);\n }\n });\n }\n\n return S;\n}\n" + ], + "tests": [ + { + "text": "topologicalSort is a function.", + "testString": "assert(typeof topologicalSort === 'function', 'topologicalSort is a function.');" + }, + { + "text": "topologicalSort must return correct library order..", + "testString": "assert.deepEqual(topologicalSort(libsSimple), ['bbb', 'aaa'], 'topologicalSort must return correct library order..');" + }, + { + "text": "topologicalSort must return correct library order..", + "testString": "assert.deepEqual(topologicalSort(libsVHDL), solutionVHDL, 'topologicalSort must return correct library order..');" + }, + { + "text": "topologicalSort must return correct library order..", + "testString": "assert.deepEqual(topologicalSort(libsCustom), solutionCustom, 'topologicalSort must return correct library order..');" + }, + { + "text": "topologicalSort must ignore unorderable dependencies..", + "testString": "assert.deepEqual(topologicalSort(libsUnorderable), solutionUnorderable, 'topologicalSort must ignore unorderable dependencies..');" + } + ], + "id": "594fa2746886f41f7d8bf225", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function topologicalSort(libs) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const libsSimple =\n `aaa bbb\n bbb`;\n\nconst libsVHDL =\n `des_system_lib std synopsys std_cell_lib des_system_lib dw02 dw01 ramlib ieee\n dw01 ieee dw01 dware gtech\n dw02 ieee dw02 dware\n dw03 std synopsys dware dw03 dw02 dw01 ieee gtech\n dw04 dw04 ieee dw01 dware gtech\n dw05 dw05 ieee dware\n dw06 dw06 ieee dware\n dw07 ieee dware\n dware ieee dware\n gtech ieee gtech\n ramlib std ieee\n std_cell_lib ieee std_cell_lib\n synopsys`;\n\nconst solutionVHDL = [\n 'ieee', 'std_cell_lib', 'gtech', 'dware', 'dw07', 'dw06',\n 'dw05', 'dw02', 'dw01', 'dw04', 'std', 'ramlib', 'synopsys',\n 'dw03', 'des_system_lib'\n];\n\nconst libsCustom =\n `a b c d\n b c d\n d c\n c base\n base`;\nconst solutionCustom = ['base', 'c', 'd', 'b', 'a'];\n\nconst libsUnorderable =\n `TestLib Base MainLib\n MainLib TestLib\n Base`;\n\nconst solutionUnorderable = ['Base'];" + } + } + }, + { + "title": "Top rank per group", + "type": "Waypoint", + "description": [ + "Task:", + "

Find the top N ranked data in each group, where N is provided as a parameter. Name of the rank and the group are also provided as parameter.

", + "Given the following data:", + "
",
+        "[",
+        "  { name: 'Tyler Bennett', id: 'E10297', salary: 32000, dept: 'D101' },",
+        "  { name: 'John Rappl', id: 'E21437', salary: 47000, dept: 'D050' },",
+        "  { name: 'George Woltman', id: 'E00127', salary: 53500, dept: 'D101' },",
+        "  { name: 'Adam Smith', id: 'E63535', salary: 18000, dept: 'D202' },",
+        "  { name: 'Claire Buckman', id: 'E39876', salary: 27800, dept: 'D202' },",
+        "  { name: 'David McClellan', id: 'E04242', salary: 41500, dept: 'D101' },",
+        "  { name: 'Rich Holcomb', id: 'E01234', salary: 49500, dept: 'D202' },",
+        "  { name: 'Nathan Adams', id: 'E41298', salary: 21900, dept: 'D050' },",
+        "  { name: 'Richard Potter', id: 'E43128', salary: 15900, dept: 'D101' },",
+        "  { name: 'David Motsinger', id: 'E27002', salary: 19250, dept: 'D202' },",
+        "  { name: 'Tim Sampair', id: 'E03033', salary: 27000, dept: 'D101' },",
+        "  { name: 'Kim Arlich', id: 'E10001', salary: 57000, dept: 'D190' },",
+        "  { name: 'Timothy Grove', id: 'E16398', salary: 29900, dept: 'D190' }",
+        "];",
+        "
", + "one could rank top 10 employees in each department by calling", + "topRankPerGroup(10, data, 'dept', 'salary')", + "Given the following data:", + "
",
+        "[",
+        "  { name: 'Friday 13th', genre: 'horror', rating: 9.9 },",
+        "  { name: \"Nightmare on Elm's Street\", genre: 'horror', rating: 5.7 },",
+        "  { name: 'Titanic', genre: 'drama', rating: 7.3 },",
+        "  { name: 'Maze Runner', genre: 'scifi', rating: 7.1 },",
+        "  { name: 'Blade runner', genre: 'scifi', rating: 8.9 }",
+        "];",
+        "
", + "one could rank the top-rated movie in each genre by calling", + "topRankPerGroup(1, data, 'genre', 'rating')" + ], + "solutions": [ + "\nconst collectDept = function (arrOfObj, groupName) {\n const collect = arrOfObj.reduce((rtnObj, obj) => {\n if (rtnObj[obj[groupName]] === undefined) {\n rtnObj[obj[groupName]] = [];\n }\n rtnObj[obj[groupName]].push(obj);\n return rtnObj;\n }, {} // initial value to reduce\n );\n\n return Object.keys(collect).sort().map(key => collect[key]);\n};\n\nconst sortRank = function (arrOfRankArrs, rankName) {\n return arrOfRankArrs.map(item => item.sort((a, b) => {\n if (a[rankName] > b[rankName]) { return -1; }\n if (a[rankName] < b[rankName]) { return 1; }\n return 0;\n }));\n};\n\nfunction topRankPerGroup(n, data, groupName, rankName) {\n if (n < 0) { return; }\n return sortRank(collectDept(data, groupName),\n rankName).map(list => list.slice(0, n));\n}\n" + ], + "tests": [ + { + "text": "topRankPerGroup is a function.", + "testString": "assert(typeof topRankPerGroup === 'function', 'topRankPerGroup is a function.');" + }, + { + "text": "topRankPerGroup returns undefined on negative n values.", + "testString": "assert(typeof topRankPerGroup(-1, []) === 'undefined', 'topRankPerGroup returns undefined on negative n values.');" + }, + { + "text": "First department must be D050", + "testString": "assert.equal(res1[0][0].dept, 'D050', 'First department must be D050');" + }, + { + "text": "First department must be D050", + "testString": "assert.equal(res1[0][1].salary, 21900, 'First department must be D050');" + }, + { + "text": "The last department must be D202", + "testString": "assert.equal(res1[3][3].dept, 'D202', 'The last department must be D202');" + }, + { + "text": "topRankPerGroup(1, ...) must return only top ranking result per group.", + "testString": "assert.equal(res2[2].length, 1, 'topRankPerGroup(1, ...) must return only top ranking result per group.');" + }, + { + "text": "topRankPerGroup(1, ...) must return only top ranking result per group.", + "testString": "assert.equal(res3[2][1].name, 'Maze Runner', 'topRankPerGroup(1, ...) must return only top ranking result per group.');" + } + ], + "id": "595011cba5a81735713873bd", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function topRankPerGroup(n, data, groupName, rankName) {", + " // Good luck!", + " return true;", + "}" + ], + "head": "", + "tail": "const testData1 = [\n { name: 'Tyler Bennett', id: 'E10297', salary: 32000, dept: 'D101' },\n { name: 'John Rappl', id: 'E21437', salary: 47000, dept: 'D050' },\n { name: 'George Woltman', id: 'E00127', salary: 53500, dept: 'D101' },\n { name: 'Adam Smith', id: 'E63535', salary: 18000, dept: 'D202' },\n { name: 'Claire Buckman', id: 'E39876', salary: 27800, dept: 'D202' },\n { name: 'David McClellan', id: 'E04242', salary: 41500, dept: 'D101' },\n { name: 'Rich Holcomb', id: 'E01234', salary: 49500, dept: 'D202' },\n { name: 'Nathan Adams', id: 'E41298', salary: 21900, dept: 'D050' },\n { name: 'Richard Potter', id: 'E43128', salary: 15900, dept: 'D101' },\n { name: 'David Motsinger', id: 'E27002', salary: 19250, dept: 'D202' },\n { name: 'Tim Sampair', id: 'E03033', salary: 27000, dept: 'D101' },\n { name: 'Kim Arlich', id: 'E10001', salary: 57000, dept: 'D190' },\n { name: 'Timothy Grove', id: 'E16398', salary: 29900, dept: 'D190' }\n];\n\nconst res1 = topRankPerGroup(10, testData1, 'dept', 'salary');\n\nconst testData2 = [\n { name: 'Friday 13th', genre: 'horror', rating: 9.9 },\n { name: \"Nightmare on Elm's Street\", genre: 'horror', rating: 5.7 },\n { name: 'Titanic', genre: 'drama', rating: 7.3 },\n { name: 'Maze Runner', genre: 'scifi', rating: 7.1 },\n { name: 'Blade runner', genre: 'scifi', rating: 8.9 }\n];\n\nconst res2 = topRankPerGroup(1, testData2, 'genre', 'rating');\nconst res3 = topRankPerGroup(2, testData2, 'genre', 'rating');\n\n//console.log(JSON.stringify(topRankPerGroup(10, testData1)));" + } + } + }, + { + "title": "Towers of Hanoi", + "type": "Waypoint", + "description": [ + " Task:", + "

Solve the Towers of Hanoi problem.

", + "

", + "Your solution should accept the number of discs as the first parameters, and", + "three string used to identify each of the three stacks of discs, for example", + "towerOfHanoi(4, 'A', 'B', 'C'). The function should return an", + "array of arrays containing the list of moves, source -> destination. For", + "example, the array [['A', 'C'], ['B', 'A']] indicates that the", + "1st move was to move a disc from stack A to C, and the 2nd move was to move a", + "disc from stack B to A.", + "

" + ], + "solutions": [ + "function towerOfHanoi(n, a, b, c) {\n const res = [];\n towerOfHanoiHelper(n, a, c, b, res);\n return res;\n}\n\nfunction towerOfHanoiHelper(n, a, b, c, res) {\n if (n > 0) {\n towerOfHanoiHelper(n - 1, a, c, b, res);\n res.push([a, c]);\n towerOfHanoiHelper(n - 1, b, a, c, res);\n }\n}\n" + ], + "tests": [ + { + "text": "towerOfHanoi is a function.", + "testString": "assert(typeof towerOfHanoi === 'function', 'towerOfHanoi is a function.');" + }, + { + "text": "towerOfHanoi(3, ...) should return 7 moves.", + "testString": "assert(res3.length === 7, 'towerOfHanoi(3, ...) should return 7 moves.');" + }, + { + "text": "towerOfHanoi(3, 'A', 'B', 'C') should return [['A','B'],['A','C'],['B','C'],['A','B'],['C','A'],['C','B'],['A','B']].\")", + "testString": "assert.deepEqual(towerOfHanoi(3, 'A', 'B', 'C'), res3Moves, \"towerOfHanoi(3, 'A', 'B', 'C') should return [['A','B'],['A','C'],['B','C'],['A','B'],['C','A'],['C','B'],['A','B']].\");" + }, + { + "text": "towerOfHanoi(5, \"X\", \"Y\", \"Z\") 10th move should be Y -> X.", + "testString": "assert.deepEqual(res5[9], ['Y', 'X'], 'towerOfHanoi(5, \"X\", \"Y\", \"Z\") 10th move should be Y -> X.');" + }, + { + "text": "towerOfHanoi(7, 'A', 'B', 'C') first ten moves are [['A','B'],['A','C'],['B','C'],['A','B'],['C','A'],['C','B'],['A','B'],['A','C'],['B','C'],['B','A']].\")", + "testString": "assert.deepEqual(towerOfHanoi(7, 'A', 'B', 'C').slice(0, 10), res7First10Moves, \"towerOfHanoi(7, 'A', 'B', 'C') first ten moves are [['A','B'],['A','C'],['B','C'],['A','B'],['C','A'],['C','B'],['A','B'],['A','C'],['B','C'],['B','A']].\");" + } + ], + "id": "5951ed8945deab770972ae56", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function towerOfHanoi (n, a, b, c) {", + " // Good luck!", + " return [[]];", + "}" + ], + "head": "", + "tail": "const res3 = towerOfHanoi(3, 'A', 'B', 'C');\nconst res3Moves = [['A', 'B'], ['A', 'C'], ['B', 'C'], ['A', 'B'], ['C', 'A'], ['C', 'B'], ['A', 'B']];\nconst res5 = towerOfHanoi(5, 'X', 'Y', 'Z');\nconst res7First10Moves = [['A', 'B'], ['A', 'C'], ['B', 'C'], ['A', 'B'], ['C', 'A'], ['C', 'B'], ['A', 'B'], ['A', 'C'], ['B', 'C'], ['B', 'A']];" + } + } + }, + { + "title": "Vector cross product", + "type": "Waypoint", + "description": [ + "A vector is defined as having three dimensions as being represented by an ordered collection of three numbers:   (X, Y, Z).", + "

", + "Task:", + " ", + " Write a function that takes two vectors (arrays) as input and computes their cross product.", + " ", + "Your function should return null on", + "invalid inputs (ie vectors of different lengths).", + "

" + ], + "solutions": [ + "function crossProduct(a, b) {\n if (!a || !b) {\n return null;\n }\n\n // Check lengths\n if (a.length !== 3 || b.length !== 3) {\n return null;\n }\n\n return [\n (a[1] * b[2]) - (a[2] * b[1]),\n (a[2] * b[0]) - (a[0] * b[2]),\n (a[0] * b[1]) - (a[1] * b[0])\n ];\n}\n" + ], + "tests": [ + { + "text": "dotProduct must be a function", + "testString": "assert.equal(typeof crossProduct, 'function', 'dotProduct must be a function');" + }, + { + "text": "dotProduct() must return null", + "testString": "assert.equal(crossProduct(), null, 'dotProduct() must return null');" + }, + { + "text": "crossProduct([1, 2, 3], [4, 5, 6]) must return [-3, 6, -3].", + "testString": "assert.deepEqual(res12, exp12, 'crossProduct([1, 2, 3], [4, 5, 6]) must return [-3, 6, -3].');" + } + ], + "id": "594810f028c0303b75339ad2", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function crossProduct() {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const tv1 = [1, 2, 3];\nconst tv2 = [4, 5, 6];\nconst res12 = crossProduct(tv1, tv2);\nconst exp12 = [-3, 6, -3];" + } + } + }, + { + "title": "Vector dot product", + "type": "Waypoint", + "description": [ + "

", + "A vector is defined as having three dimensions as being represented by an ordered collection of three numbers:   (X, Y, Z).", + "

", + "

", + "Task:", + " ", + " Write a function that takes any numbers of vectors (arrays) as input and computes their dot product.", + " ", + "Your function should return null on", + "invalid inputs (ie vectors of different lengths).", + "

" + ], + "solutions": [ + "function dotProduct(...vectors) {\n if (!vectors || !vectors.length) {\n return null;\n }\n if (!vectors[0] || !vectors[0].length) {\n return null;\n }\n const vectorLen = vectors[0].length;\n const numVectors = vectors.length;\n\n // If all vectors not same length, return null\n for (let i = 0; i < numVectors; i++) {\n if (vectors[i].length !== vectorLen) {\n return null; // return undefined\n }\n }\n\n let prod = 0;\n let sum = 0;\n let j = vectorLen;\n let i = numVectors;\n // Sum terms\n while (j--) {\n i = numVectors;\n prod = 1;\n\n while (i--) {\n prod *= vectors[i][j];\n }\n sum += prod;\n }\n return sum;\n}\n" + ], + "tests": [ + { + "text": "dotProduct must be a function", + "testString": "assert.equal(typeof dotProduct, 'function', 'dotProduct must be a function');" + }, + { + "text": "dotProduct() must return null", + "testString": "assert.equal(dotProduct(), null, 'dotProduct() must return null');" + }, + { + "text": "dotProduct([[1], [1]]) must return 1.", + "testString": "assert.equal(dotProduct([1], [1]), 1, 'dotProduct([[1], [1]]) must return 1.');" + }, + { + "text": "dotProduct([[1], [1, 2]]) must return null.", + "testString": "assert.equal(dotProduct([1], [1, 2]), null, 'dotProduct([[1], [1, 2]]) must return null.');" + }, + { + "text": "dotProduct([[1, 3, -5], [4, -2, -1]]) must return 3.", + "testString": "assert.equal(dotProduct(...vectorsWp), 3, 'dotProduct([[1, 3, -5], [4, -2, -1]]) must return 3.');" + }, + { + "text": "Should return 156000. ", + "testString": "assert.equal(dotProduct(...vectors5x5), 156000, 'Should return 156000. ');" + } + ], + "id": "594810f028c0303b75339ad3", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function dotProduct() {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "const vectors5x5 = [ [ 0, 1, 2, 3, 4 ], [ 0, 2, 4, 6, 8 ], [ 0, 3, 6, 9, 12 ], [ 0, 4, 8, 12, 16 ], [ 0, 5, 10, 15, 20 ] ];\nconst vectorsWp = [[1, 3, -5], [4, -2, -1]];" + } + } + }, + { + "title": "Word wrap", + "type": "Waypoint", + "description": [ + "

", + "Even today, with proportional fonts and complex layouts, there are still", + "cases where you need to wrap text at a specified", + "column. The basic task is to wrap a paragraph of text in a simple way.", + "Example text:", + "

", + "
",
+        "Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX algorithm.",
+        "If your language provides this, you get easy extra credit,",
+        "but you ''must reference documentation'' indicating that the algorithm",
+        "is something better than a simple minimimum length algorithm.",
+        "
", + "

", + "Task:", + " ", + " Write a function that can wrap this text to any number of characters.", + " ", + "As an example, the text wrapped to 80 characters should look like the following:", + "

", + "
",
+        "Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX",
+        "algorithm. If your language provides this, you get easy extra credit, but you",
+        "must reference documentation indicating that the algorithm is something better",
+        "than a simple minimimum length algorithm.",
+        "
" + ], + "solutions": [ + "function wrap (text, limit) {\n const noNewlines = text.replace('\\n', '');\n if (noNewlines.length > limit) {\n // find the last space within limit\n const edge = noNewlines.slice(0, limit).lastIndexOf(' ');\n if (edge > 0) {\n const line = noNewlines.slice(0, edge);\n const remainder = noNewlines.slice(edge + 1);\n return line + '\\n' + wrap(remainder, limit);\n }\n }\n return text;\n}\n" + ], + "tests": [ + { + "text": "wrap must be a function.", + "testString": "assert.equal(typeof wrap, 'function', 'wrap must be a function.');" + }, + { + "text": "wrap must return a string.", + "testString": "assert.equal(typeof wrap('abc', 10), 'string', 'wrap must return a string.');" + }, + { + "text": "wrap(80) must return 4 lines.", + "testString": "assert(wrapped80.split('\\n').length === 4, 'wrap(80) must return 4 lines.');" + }, + { + "text": "wrap(80) should break at the correct point. ", + "testString": "assert.equal(wrapped80.split('\\n')[0], 'wrap(80) should break at the correct point. ');" + }, + { + "text": "wrap(42) must return 7 lines.", + "testString": "assert(wrapped42.split('\\n').length === 7, 'wrap(42) must return 7 lines.');" + }, + { + "text": "wrap(42) should break at the correct point. ", + "testString": "assert.equal(wrapped42.split('\\n')[0], 'wrap(42) should break at the correct point. ');" + } + ], + "id": "594810f028c0303b75339ad4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function wrap (text, limit) {", + " return text;", + "}" + ], + "head": "", + "tail": "const text =\n`Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX algorithm.\nIf your language provides this, you get easy extra credit,\nbut you ''must reference documentation'' indicating that the algorithm\nis something better than a simple minimimum length algorithm.`;\n\nconst wrapped80 = wrap(text, 80);\nconst wrapped42 = wrap(text, 42);\n\nconst firstRow80 =\n 'Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX';\n\nconst firstRow42 = 'Wrap text using a more sophisticated';" + } + } + }, + { + "title": "Y combinator", + "type": "Waypoint", + "description": [ + "

", + "In strict ", + "functional programming and", + "the lambda calculus, ", + "functions (lambda expressions) don't have state and are only allowed to refer to arguments of enclosing functions. ", + "This rules out the usual definition of a recursive function wherein a function is associated with the state of a variable and this variable's state is used in the body of the function.", + "

", + "

", + "The Y combinator is itself a stateless function that,", + "when applied to another stateless function, returns a recursive version of the function. The Y combinator is", + "the simplest of the class of such functions, called ", + "fixed-point combinators.", + "

", + "Task:", + " ", + " Define the stateless Y combinator function and use it to compute", + " factorial.", + " ", + "factorial(N) function is already given to you.", + "See also Jim Weirich: Adventures in Functional Programming." + ], + "solutions": [ + "var Y = f => (x => x(x))(y => f(x => y(y)(x)));\n" + ], + "tests": [ + { + "text": "Y must return a function", + "testString": "assert.equal(typeof Y(f => n => n), 'function', 'Y must return a function');" + }, + { + "text": "factorial(1) must return 1.", + "testString": "assert.equal(factorial(1), 1, 'factorial(1) must return 1.');" + }, + { + "text": "factorial(2) must return 2.", + "testString": "assert.equal(factorial(2), 2, 'factorial(2) must return 2.');" + }, + { + "text": "factorial(3) must return 6.", + "testString": "assert.equal(factorial(3), 6, 'factorial(3) must return 6.');" + }, + { + "text": "factorial(4) must return 24.", + "testString": "assert.equal(factorial(4), 24, 'factorial(4) must return 24.');" + }, + { + "text": "factorial(10) must return 3628800.", + "testString": "assert.equal(factorial(10), 3628800, 'factorial(10) must return 3628800.');" + } + ], + "id": "594810f028c0303b75339ad5", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function Y(f) {", + " return function() {", + " // Good luck!", + " };", + "}", + "", + "var factorial = Y(function(f) {", + " return function (n) {", + " return n > 1 ? n * f(n - 1) : 1;", + " };", + "});" + ], + "head": "", + "tail": "var factorial = Y(f => n => (n > 1 ? n * f(n - 1) : 1));" + } + } + }, + { + "title": "Zeckendorf number representation", + "type": "Waypoint", + "description": [ + "

", + "Just as numbers can be represented in a", + "positional notation as sums of multiples of the powers of ten (decimal)", + "or two (binary); all the positive integers can be represented as the sum", + "of one or zero times the distinct members of the Fibonacci series.", + "

", + "

", + "Recall that the first six distinct Fibonacci", + "numbers are: 1, 2, 3, 5, 8, 13. The decimal number eleven can", + "be written as 0*13 + 1*8 + 0*5 + 1*3 + 0*2 + 0*1 or", + "010100 in positional notation where the columns represent", + "multiplication by a particular member of the sequence. Leading zeroes are", + "dropped so that 11 decimal becomes 10100.", + "

", + "

", + "10100 is not the only way to make 11 from the Fibonacci numbers however", + "0*13 + 1*8 + 0*5 + 0*3 + 1*2 + 1*1 or 010011 would also", + "represent decimal 11. For a true Zeckendorf number there is the added", + "restriction that ''no two consecutive Fibonacci numbers can be used''", + "which leads to the former unique solution.", + "

", + "

", + " Task:", + " Write a function that generates and returns an array of first N Zeckendorf numbers in order.", + "

" + ], + "solutions": [ + "// zeckendorf :: Int -> String\nfunction zeckendorf(n) {\n const f = (m, x) => (m < x ? [m, 0] : [m - x, 1]);\n return (n === 0 ? ([0]) :\n mapAccumL(f, n, reverse(\n tail(fibUntil(n))\n ))[1]).join('');\n}\n\n// fibUntil :: Int -> [Int]\nlet fibUntil = n => {\n const xs = [];\n until(\n ([a]) => a > n,\n ([a, b]) => (xs.push(a), [b, a + b]), [1, 1]\n );\n return xs;\n};\n\nlet mapAccumL = (f, acc, xs) => (\n xs.reduce((a, x) => {\n const pair = f(a[0], x);\n\n return [pair[0], a[1].concat(pair[1])];\n }, [acc, []])\n);\n\nlet until = (p, f, x) => {\n let v = x;\n while (!p(v)) v = f(v);\n return v;\n};\n\nconst tail = xs => (\n xs.length ? xs.slice(1) : undefined\n);\n\nconst reverse = xs => xs.slice(0).reverse();\n" + ], + "tests": [ + { + "text": "zeckendorf must be function", + "testString": "assert.equal(typeof zeckendorf, 'function', 'zeckendorf must be function');" + }, + { + "text": "Passing a random number from a list to zeckendorf returns the correct zeckendorf number. ", + "testString": "assert.deepEqual(answer, solution20, 'Passing a random number from a list to zeckendorf returns the correct zeckendorf number. ');" + } + ], + "id": "594810f028c0303b75339ad6", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function zeckendorf(n) {", + " // good luck!", + "}" + ], + "head": "", + "tail": "const range = (m, n) => (\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i)\n);\n\nconst solution20 = [\n '1', '10', '100', '101', '1000', '1001', '1010', '10000', '10001',\n '10010', '10100', '10101', '100000', '100001', '100010', '100100', '100101',\n '101000', '101001', '101010'\n];\n\nconst answer = range(1, 20).map(zeckendorf);" + } + } + }, + { + "title": "Zhang-Suen thinning algorithm", + "type": "Waypoint", + "description": [ + "This is an algorithm used to thin a black and white i.e. one bit per pixel images.", + "For example, with an input image of:", + "
",
+        " #################                   #############",
+        " ##################               ################",
+        " ###################            ##################",
+        " ########     #######          ###################",
+        "   ######     #######         #######       ######",
+        "   ######     #######        #######",
+        "   #################         #######",
+        "   ################          #######",
+        "   #################         #######",
+        "   ######     #######        #######",
+        "   ######     #######        #######",
+        "   ######     #######         #######       ######",
+        " ########     #######          ###################",
+        " ########     ####### ######    ################## ######",
+        " ########     ####### ######      ################ ######",
+        " ########     ####### ######         ############# ######",
+        "                                                           
", + "It produces the thinned output:", + "
",
+        "                                                           ",
+        "    # ##########                       #######",
+        "     ##        #                   ####       #",
+        "     #          #                 ##",
+        "     #          #                #",
+        "     #          #                #",
+        "     #          #                #",
+        "     ############               #",
+        "     #          #               #",
+        "     #          #                #",
+        "     #          #                #",
+        "     #          #                #",
+        "     #                            ##",
+        "     #                             ############",
+        "                       ###                          ###",
+        "                                                           ",
+        "                                                           
", + "

Algorithm

", + "Assume black pixels are one and white pixels zero, and that the input image is a rectangular N by M array of ones and zeroes.", + "The algorithm operates on all black pixels P1 that can have eight neighbours. The neighbours are, in order, arranged as:", + "", + " ", + " ", + " ", + "
P9P2P3
P8P1P4
P7P6P5
", + "Obviously the boundary pixels of the image cannot have the full eight neighbours.", + " ", + " Define $A(P1)$ = the number of transitions from white to black, (0 -> 1) in the sequence P2,P3,P4,P5,P6,P7,P8,P9,P2. (Note the extra P2 at the end - it is circular).", + " ", + " ", + " Define $B(P1)$ = the number of black pixel neighbours of P1. ( = sum(P2 .. P9) )", + " ", + "

Step 1:

", + "All pixels are tested and pixels satisfying all the following conditions (simultaneously) are just noted at this stage.", + " (0) The pixel is black and has eight neighbours", + " (1) $2 <= B(P1) <= 6$", + " (2) $A(P1) = 1$", + " (3) At least one of P2 and P4 and P6 is white", + " (4) At least one of P4 and P6 and P8 is white", + "After iterating over the image and collecting all the pixels satisfying all step 1 conditions, all these condition satisfying pixels are set to white.", + "

Step 2:

", + "All pixels are again tested and pixels satisfying all the following conditions are just noted at this stage.", + " (0) The pixel is black and has eight neighbours", + " (1) $2 <= B(P1) <= 6$", + " (2) $A(P1) = 1$", + " (3) At least one of P2 and P4 and '''P8''' is white", + " (4) At least one of '''P2''' and P6 and P8 is white", + "After iterating over the image and collecting all the pixels satisfying all step 2 conditions, all these condition satisfying pixels are again set to white.", + "Iteration:", + "If any pixels were set in this round of either step 1 or step 2 then all steps are repeated until no image pixels are so changed.", + "

", + "Task:", + "Write a routine to perform Zhang-Suen thinning on an image matrix of ones and zeroes.", + "

" + ], + "solutions": [ + "function Point(x, y) {\n this.x = x;\n this.y = y;\n}\n\nconst ZhangSuen = (function () {\n function ZhangSuen() {\n }\n\n ZhangSuen.nbrs = [[0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1]];\n\n ZhangSuen.nbrGroups = [[[0, 2, 4], [2, 4, 6]], [[0, 2, 6], [0, 4, 6]]];\n\n ZhangSuen.toWhite = [];\n\n ZhangSuen.main = function (image) {\n ZhangSuen.grid = new Array(image);\n for (let r = 0; r < image.length; r++) {\n ZhangSuen.grid[r] = image[r].split('');\n }\n ZhangSuen.thinImage();\n return ZhangSuen.getResult();\n };\n\n ZhangSuen.thinImage = function () {\n let firstStep = false;\n let hasChanged;\n do {\n hasChanged = false;\n firstStep = !firstStep;\n for (let r = 1; r < ZhangSuen.grid.length - 1; r++) {\n for (let c = 1; c < ZhangSuen.grid[0].length - 1; c++) {\n if (ZhangSuen.grid[r][c] !== '#') {\n continue;\n }\n const nn = ZhangSuen.numNeighbors(r, c);\n if (nn < 2 || nn > 6) {\n continue;\n }\n if (ZhangSuen.numTransitions(r, c) !== 1) {\n continue;\n }\n if (!ZhangSuen.atLeastOneIsWhite(r, c, firstStep ? 0 : 1)) {\n continue;\n }\n ZhangSuen.toWhite.push(new Point(c, r));\n hasChanged = true;\n }\n }\n for (let i = 0; i < ZhangSuen.toWhite.length; i++) {\n const p = ZhangSuen.toWhite[i];\n ZhangSuen.grid[p.y][p.x] = ' ';\n }\n ZhangSuen.toWhite = [];\n } while ((firstStep || hasChanged));\n };\n\n ZhangSuen.numNeighbors = function (r, c) {\n let count = 0;\n for (let i = 0; i < ZhangSuen.nbrs.length - 1; i++) {\n if (ZhangSuen.grid[r + ZhangSuen.nbrs[i][1]][c + ZhangSuen.nbrs[i][0]] === '#') {\n count++;\n }\n }\n return count;\n };\n\n ZhangSuen.numTransitions = function (r, c) {\n let count = 0;\n for (let i = 0; i < ZhangSuen.nbrs.length - 1; i++) {\n if (ZhangSuen.grid[r + ZhangSuen.nbrs[i][1]][c + ZhangSuen.nbrs[i][0]] === ' ') {\n if (ZhangSuen.grid[r + ZhangSuen.nbrs[i + 1][1]][c + ZhangSuen.nbrs[i + 1][0]] === '#') {\n count++;\n }\n }\n }\n return count;\n };\n\n ZhangSuen.atLeastOneIsWhite = function (r, c, step) {\n let count = 0;\n const group = ZhangSuen.nbrGroups[step];\n for (let i = 0; i < 2; i++) {\n for (let j = 0; j < group[i].length; j++) {\n const nbr = ZhangSuen.nbrs[group[i][j]];\n if (ZhangSuen.grid[r + nbr[1]][c + nbr[0]] === ' ') {\n count++;\n break;\n }\n }\n }\n return count > 1;\n };\n\n ZhangSuen.getResult = function () {\n const result = [];\n for (let i = 0; i < ZhangSuen.grid.length; i++) {\n const row = ZhangSuen.grid[i].join('');\n result.push(row);\n }\n return result;\n };\n return ZhangSuen;\n}());\n\nfunction thinImage(image) {\n return ZhangSuen.main(image);\n}\n" + ], + "tests": [ + { + "text": "thinImage must be a function", + "testString": "assert.equal(typeof thinImage, 'function', 'thinImage must be a function');" + }, + { + "text": "thinImage must return an array of strings", + "testString": "assert.equal(typeof result, 'object', 'thinImage must return an array of strings');" + }, + { + "text": "thinImage must return an array of strings", + "testString": "assert.equal(typeof result[0], 'string', 'thinImage must return an array of strings');" + }, + { + "text": "thinImage must return an array of strings", + "testString": "assert.deepEqual(result, expected, 'thinImage must return an array of strings');" + } + ], + "id": "594810f028c0303b75339ad7", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "const testImage = [", + " ' ',", + " ' ################# ############# ',", + " ' ################## ################ ',", + " ' ################### ################## ',", + " ' ######## ####### ################### ',", + " ' ###### ####### ####### ###### ',", + " ' ###### ####### ####### ',", + " ' ################# ####### ',", + " ' ################ ####### ',", + " ' ################# ####### ',", + " ' ###### ####### ####### ',", + " ' ###### ####### ####### ',", + " ' ###### ####### ####### ###### ',", + " ' ######## ####### ################### ',", + " ' ######## ####### ###### ################## ###### ',", + " ' ######## ####### ###### ################ ###### ',", + " ' ######## ####### ###### ############# ###### ',", + " ' '];", + "", + "function thinImage(image) {", + " // Good luck!", + "}" + ], + "head": "", + "tail": "\nconst imageForTests = [\n ' ',\n ' ################# ############# ',\n ' ################## ################ ',\n ' ################### ################## ',\n ' ######## ####### ################### ',\n ' ###### ####### ####### ###### ',\n ' ###### ####### ####### ',\n ' ################# ####### ',\n ' ################ ####### ',\n ' ################# ####### ',\n ' ###### ####### ####### ',\n ' ###### ####### ####### ',\n ' ###### ####### ####### ###### ',\n ' ######## ####### ################### ',\n ' ######## ####### ###### ################## ###### ',\n ' ######## ####### ###### ################ ###### ',\n ' ######## ####### ###### ############# ###### ',\n ' '];\nconst expected = [\n ' ',\n ' ',\n ' # ########## ####### ',\n ' ## # #### # ',\n ' # # ## ',\n ' # # # ',\n ' # # # ',\n ' # # # ',\n ' ############ # ',\n ' # # # ',\n ' # # # ',\n ' # # # ',\n ' # # # ',\n ' # ## ',\n ' # ############ ',\n ' ### ### ',\n ' ',\n ' '\n];\nconst result = thinImage(imageForTests);" + } + } + }, + { + "title": "Zig-zag matrix", + "type": "Waypoint", + "description": [ + "A   ''zig-zag''   array is a square arrangement of the first  ", + "$N^2$   integers,   where the", + "numbers increase sequentially as you zig-zag along the array's  ", + "anti-diagonals.", + "For example, given   '''5''',   produce this array:", + "
",
+        " 0  1  5  6 14",
+        " 2  4  7 13 15",
+        " 3  8 12 16 21",
+        " 9 11 17 20 22",
+        "10 18 19 23 24",
+        "
", + "Write a function that takes the size of the zig-zag matrix, and returns the", + "corresponding matrix as two-dimensional array." + ], + "solutions": [ + "function ZigZagMatrix(n) {\n const mtx = [];\n for (let i = 0; i < n; i++) {\n mtx[i] = [];\n }\n\n let i = 1;\n let j = 1;\n for (let e = 0; e < n * n; e++) {\n mtx[i - 1][j - 1] = e;\n if ((i + j) % 2 === 0) {\n // Even stripes\n if (j < n) j++;\n else i += 2;\n if (i > 1) i--;\n } else {\n // Odd stripes\n if (i < n) i++;\n else j += 2;\n if (j > 1) j--;\n }\n }\n return mtx;\n}\n" + ], + "tests": [ + { + "text": "ZigZagMatrix must be a function", + "testString": "assert.equal(typeof ZigZagMatrix, 'function', 'ZigZagMatrix must be a function');" + }, + { + "text": "ZigZagMatrix should return array", + "testString": "assert.equal(typeof ZigZagMatrix(1), 'object', 'ZigZagMatrix should return array');" + }, + { + "text": "ZigZagMatrix should return an array of nestes arrays", + "testString": "assert.equal(typeof ZigZagMatrix(1)[0], 'object', 'ZigZagMatrix should return an array of nestes arrays');" + }, + { + "text": "ZigZagMatrix(1) should return [[0]]", + "testString": "assert.deepEqual(ZigZagMatrix(1), zm1, 'ZigZagMatrix(1) should return [[0]]');" + }, + { + "text": "ZigZagMatrix(2) should return [[0, 1], [2, 3]]", + "testString": "assert.deepEqual(ZigZagMatrix(2), zm2, 'ZigZagMatrix(2) should return [[0, 1], [2, 3]]');" + }, + { + "text": "ZigZagMatrix(5) must return specified matrix", + "testString": "assert.deepEqual(ZigZagMatrix(5), zm5, 'ZigZagMatrix(5) must return specified matrix');" + } + ], + "id": "594810f028c0303b75339ad8", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "files": { + "indexjs": { + "key": "indexjs", + "ext": "js", + "name": "index", + "contents": [ + "function ZigZagMatrix(n) {", + " // Good luck!", + " return [[], []];", + "}" + ], + "head": "", + "tail": "const zm1 = [[0]];\nconst zm2 = [[0, 1], [2, 3]];\nconst zm5 = [\n [0, 1, 5, 6, 14],\n [2, 4, 7, 13, 15],\n [3, 8, 12, 16, 21],\n [9, 11, 17, 20, 22],\n [10, 18, 19, 23, 24]\n];" + } + } + } + ], + "fileName": "08-coding-interview-questions-and-take-home-assignments/rosetta-code-problems.json", + "superBlock": "coding-interview-questions-and-take-home-assignments", + "superOrder": 8 +} \ No newline at end of file diff --git a/packages/learn/seed/challenges/08-coding-interview-prep/take-home-projects.json b/packages/learn/seed/challenges/08-coding-interview-prep/take-home-projects.json new file mode 100644 index 0000000000..6a89d1db1c --- /dev/null +++ b/packages/learn/seed/challenges/08-coding-interview-prep/take-home-projects.json @@ -0,0 +1,876 @@ +{ + "name": "Take Home Projects", + "order": 4, + "time": "", + "helpRoom": "HelpFrontEnd", + "challenges": [ + { + "id": "bd7158d8c442eddfaeb5bd10", + "title": "Show the Local Weather", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/bELRjV.", + "Rule #1: Don't look at the example project's code. Figure it out for yourself.", + "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can see the weather in my current location.", + "User Story: I can see a different icon or background image (e.g. snowy mountain, hot desert) depending on the weather.", + "User Story: I can push a button to toggle between Fahrenheit and Celsius.", + "Note: Many internet browsers now require an HTTP Secure (https://) connection to obtain a user's locale via HTML5 Geolocation. For this reason, we recommend using HTML5 Geolocation to get user location and then use the freeCodeCamp Weather API https://fcc-weather-api.glitch.me which uses an HTTP Secure connection for the weather. Also, be sure to connect to CodePen.io via https://.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "type": "zipline", + "challengeType": 3, + "isRequired": false, + "translations": { + "es": { + "title": "Muestra el clima local", + "description": [ + "Objetivo: Crea una aplicación con CodePen.io cuya funcionalidad sea similar a la de esta: https://codepen.io/freeCodeCamp/full/bELRjV.", + "Satisface las siguientes historias de usuario. Usa cualquier librería o APIs que necesites.", + "Historia de usuario: Pedo obtener información acerca del clima en mi localización actual.", + "Historia de usuario: Puedo ver un icono diferente o una imagen de fondo diferente (e.g. montaña con nieve, desierto caliente) dependiendo del clima.", + "Historia de usuario: Puedo pulsar un botón para cambiar la unidad de temperatura de grados Fahrenheit a Celsius y viceversa.", + "Recomendamos utilizar Open Weather API. Al utilizarlo tendrás que crear una llave API gratuita. Normalmente debes evitar exponer llaves de API en CodePen, pero por el momento no hemos encontrado un API de clima que no requiera llave.", + "Recuerda utilizar Leer-Buscar-Preguntar si te sientes atascado.", + "Cuando hayas terminado, pulsa el botón de \"I've completed this challenge\" e incluye un enlace a tu CodePen.", + "Puedes obtener retroalimentación sobre tu proyecto por parte de otros campistas, compartiendolo en nuestra Sala de chat para revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + }, + "ru": { + "title": "Покажите местную погоду", + "description": [ + "Задание: Создайте CodePen.io который успешно копирует вот этот: https://codepen.io/freeCodeCamp/full/bELRjV.", + "Правило #1: Не подсматривайте код приведенного на CodePen примера. Напишите его самостоятельно.", + "Правило #2: Можете использовать любые библиотеки или API, которые потребуются.", + "Правило #3: Воссоздайте функционал приведенного примера и не стесняйтесь добавить что-нибудь от себя.", + "Реализуйте следующие пользовательские истории, сделайте также бонусные по желанию:", + "Пользовательская история: В качестве пользователя, я могу узнать погоду с учетом моего текущего местоположения.", + "Бонусная пользовательская история: В качестве пользователя, я могу в зависимости от погоды видеть различные температурные значки.", + "Бонусная пользовательская история: В качестве пользователя, я могу в зависимости от погоды видеть различные фоновые изображения (снежные горы, знойная пустыня).", + "Бонусная пользовательская история: В качестве пользователя, я могу нажать на кнопку чтобы переключится между градусами по Цельсию или по Фаренгейту.", + "Если что-то не получается, воспользуйтесь Read-Search-Ask.", + "Когда выполните задание кликните кнопку \"I've completed this challenge\" и добавьте ссылку на ваш CodePen. Если вы программировали с кем-то в паре, также добавьте имя вашего напарника.", + "Если вы хотите получить немедленную оценку вашего проекта, нажмите эту кнопку и добавьте ссылку на ваш CodePen. В противном случае мы проверим его перед тем как вы приступите к проектам для некоммерческих организаций.

Click here then add your link to your tweet's text" + ] + } + } + }, + { + "id": "bd7158d8c442eddfaeb5bd19", + "title": "Build a Wikipedia Viewer", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/wGqEga/.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can search Wikipedia entries in a search box and see the resulting Wikipedia entries.", + "User Story: I can click a button to see a random Wikipedia entry.", + "Hint #1: Here's a URL you can use to get a random Wikipedia article: https://en.wikipedia.org/wiki/Special:Random.", + "Hint #2: Here's an entry on using Wikipedia's API: https://www.mediawiki.org/wiki/API:Main_page.", + "Hint #3: Use this link to experiment with Wikipedia's API.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "type": "zipline", + "challengeType": 3, + "isRequired": false, + "translations": { + "es": { + "title": "Crea un buscador de Wikipedia", + "description": [ + "Objetivo: Crea una aplicación con CodePen.io cuya funcionalidad sea similar a la de esta: https://codepen.io/freeCodeCamp/full/wGqEga/.", + "Satisface las siguientes historias de usuario. Usa cualquier librería o APIs que necesites. Dale tu estilo personal.", + "Historia de usuario: Pedo obtener información acerca del clima en mi localización actual.", + "Historia de usuario: Puedo ver un icono diferente o una imagen de fondo diferente (e.g. montaña con nieve, desierto caliente) dependiendo del clima.", + "Historia de usuario: Puedo pulsar un botón para cambiar la unidad de temperatura de grados Fahrenheit a Celsius y viceversa.", + "Historia de usuario: Puedo buscar entradas en Wikipedia en un cuadro de búsqueda y ver las entradas de Wikipedia resultantes.", + "Historia de usuario:Puedo pulsar un botón para ver un artículo aleatorio de Wikipedia.", + "Pista 1: Aquí está una URL donde puedes ver una entrada aleatoria de Wikipedia: https://en.wikipedia.org/wiki/Special:Random<.", + "Pista 2: Este es un artículo muy útil relativo al uso del API de Wikipedia: https://www.mediawiki.org/wiki/API:Main_page.", + "Pista 3: Usa este enlace para experimentar con el API de Wikipedia.", + "Recuerda utilizar Leer-Buscar-Preguntar si te sientes atascado.", + "Cuando hayas terminado, pulsa el botón de \"I've completed this challenge\" e incluye un enlace a tu CodePen.", + "Puedes obtener retroalimentación sobre tu proyecto por parte de otros campistas, compartiendolo en nuestra Sala de chat para revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "bd7158d8c442eddfaeb5bd1f", + "title": "Use the Twitch JSON API", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/Myvqmo/.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can see whether freeCodeCamp is currently streaming on Twitch.tv.", + "User Story: I can click the status output and be sent directly to the freeCodeCamp's Twitch.tv channel.", + "User Story: if a Twitch user is currently streaming, I can see additional details about what they are streaming.", + "Hint: See an example call to Twitch.tv's JSONP API at http://forum.freecodecamp.org/t/use-the-twitchtv-json-api/19541.", + "Hint: The relevant documentation about this API call is here: https://dev.twitch.tv/docs/v5/reference/streams/#get-stream-by-user.", + "Hint: Here's an array of the Twitch.tv usernames of people who regularly stream: [\"ESL_SC2\", \"OgamingSC2\", \"cretetion\", \"freecodecamp\", \"storbeck\", \"habathcx\", \"RobotCaleb\", \"noobs2ninjas\"]", + "UPDATE: Due to a change in conditions on API usage explained here Twitch.tv now requires an API key, but we've built a workaround. Use https://wind-bow.glitch.me/twitch-api instead of twitch's API base URL (i.e. https://api.twitch.tv/kraken ) and you'll still be able to get account information, without needing to sign up for an API key.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "type": "zipline", + "challengeType": 3, + "isRequired": false, + "translations": { + "es": { + "title": "Usa el API JSON de Twitch", + "description": [ + "Objetivo: Crea una aplicación con CodePen.io cuya funcionalidad sea similar a la de esta: https://codepen.io/freeCodeCamp/full/Myvqmo/.", + "Satisface las siguientes historias de usuario. Usa cualquier librería o APIs que necesites. Dale tu estilo personal.", + "Historia de usuario: Puedo verificar si freeCodeCamp está transmitiendo actualmente en Twitch.tv", + "Historia de usuario: Puedo pulsar el estatus y ser enviado directamente al canal de freeCodeCamp en Twitch.tv.", + "Historia de usuario: Si un usuario Twitch está transmitiendo actualmente, puedo ver detalles adicionales acerca del contenido que están transmitiendo.", + "Pista: Obseva una llamada de ejemplo al API JSONP de Twitch.tv en http://forum.freecodecamp.org/t/use-the-twitchtv-json-api/19541.", + "Pista: La documentación relevante sobre esta llamada al API está aquí: https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel.", + "Pista: Aquí está un vector de usuarios en Twitch.tv que regularmente transmiten sobre programación: [\"ESL_SC2\", \"OgamingSC2\", \"cretetion\", \"freecodecamp\", \"storbeck\", \"habathcx\", \"RobotCaleb\", \"noobs2ninjas\"]", + "Recuerda utilizar Leer-Buscar-Preguntar si te sientes atascado.", + "Cuando hayas terminado, pulsa el botón de \"I've completed this challenge\" e incluye un enlace a tu CodePen.", + "Puedes obtener retroalimentación sobre tu proyecto por parte de otros campistas, compartiendolo en nuestra Sala de chat para revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + }, + "ru": { + "title": "Используйте Twitch JSON API", + "description": [ + "Задание: Создайте CodePen.io который успешно копирует вот этот: https://codepen.io/freeCodeCamp/full/Myvqmo/.", + "Правило #1: Не подсматривайте код приведенного на CodePen примера. Напишите его самостоятельно.", + "Правило #2: Можете использовать любые библиотеки или API, которые потребуются.", + "Правило #3: Воссоздайте функционал приведенного примера и не стесняйтесь добавить что-нибудь от себя.", + "Реализуйте следующие пользовательские истории, сделайте также бонусные по желанию:", + "Пользовательская история: В качестве пользователя, я могу увидеть идет ли в данный момент на Twitch.tv трансляция freeCodeCamp.", + "Пользовательская история: В качестве пользователя, я могу, кликнув на описание трансляции, перейти на канал freeCodeCamp.", + "Пользовательская история: В качестве пользователя, я могу видеть дополнительную информацию о текущей трансляции freeCodeCamp.", + "Бонусная пользовательская история: В качестве пользователя, я могу произвести поиск среди перечисленных каналов.", + "Подсказка: Пример запроса к Twitch.tv JSON API: https://api.twitch.tv/kraken/streams/freecodecamp.", + "Подсказка: Документацию об этом запросе можно найти по ссылке: https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel.", + "Подсказка: В этом массиве приведены имена пользователей, которые регулярно пишут код онлайн: [\"ESL_SC2\", \"OgamingSC2\", \"cretetion\", \"freecodecamp\", \"storbeck\", \"habathcx\", \"RobotCaleb\", \"noobs2ninjas\"]", + "Если что-то не получается, воспользуйтесь Read-Search-Ask.", + "Когда выполните задание кликните кнопку \"I've completed this challenge\" и добавьте ссылку на ваш CodePen. Если вы программировали с кем-то в паре, также добавьте имя вашего напарника.", + "Если вы хотите получить немедленную оценку вашего проекта, нажмите эту кнопку и добавьте ссылку на ваш CodePen. В противном случае мы проверим его перед тем как вы приступите к проектам для некоммерческих организаций.

Click here then add your link to your tweet's text" + ] + } + } + }, + { + "id": "bd7158d8c443edefaeb5bdee", + "title": "Build an Image Search Abstraction Layer", + "description": [ + "Objective: Build a full stack JavaScript app that allows you to search for images like this: https://cryptic-ridge-9197.herokuapp.com/api/imagesearch/lolcats%20funny?offset=10 and browse recent search queries like this: https://cryptic-ridge-9197.herokuapp.com/api/latest/imagesearch/. Then deploy it to Glitch.", + "Note that for each project, you should create a new GitHub repository and a new Glitch project. If you can't remember how to do this, revisit https://freecodecamp.org/challenges/get-set-for-our-api-development-projects.", + "Here are the specific user stories you should implement for this project:", + "User Story: I can get the image URLs, alt text and page urls for a set of images relating to a given search string.", + "User Story: I can paginate through the responses by adding a ?offset=2 parameter to the URL.", + "User Story: I can get a list of the most recently submitted search strings.", + "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Glitch.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "isRequired": true, + "releasedOn": "January 1, 2016", + "type": "basejump", + "challengeType": 4, + "translations": { + "es": { + "title": "Capa de abstracción para buscar imágenes", + "description": [ + "Objetivo: Desarolla una aplicación de Pila Completa en JavaScript que te permite buscar imágenes como esta: https://cryptic-ridge-9197.herokuapp.com/api/imagesearch/lolcats%20funny?offset=10 y examinar las búsquedas recientes como esta: https://cryptic-ridge-9197.herokuapp.com/api/latest/imagesearch/. Después, despliegala en Glitch.", + "Ten en cuenta que para cada proyecto, deberías crear un nuevo repositorio en GitHub y un nuevo proyecto en Glitch. Si no recuerdas como hacer esto, vuelve a visitar https://freecodecamp.org//challenges/get-set-for-our-api-development-projects.", + "Aquí están las historias de usuario específicas que debes implementar para este proyecto:", + "Historia de Usuario: Puedo obtener la URL de una imagen, texto alternativo y URLs de las páginas de un conjunto de imágenes que se relacionen con una cadena de texto dada.", + "Historia de Usuario: Puedo examinar página a página las respuestas añadiendo un parámetro del estilo ?offset=2 al URL.", + "Historia de Usuario: Puedo obtener una lista de las cadenas búscadas que se enviaron más recientemente.", + "Una vez que hayas terminado de implementar estas historias de usuarios, pulsa el botón \"I've completed this challenge\" e introduce los URLs de tu repositorio en GitHub y de tu aplicación en vivo en Glitch.", + "Puedes obtener retroalimentación sobre tu proyecto por parte de otros campistas, compartiendolo en nuestra Sala de chat para revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "bd7158d8c442eedfaeb5bd1c", + "title": "Build a Tic Tac Toe Game", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/KzXQgy/.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can play a game of Tic Tac Toe with the computer.", + "User Story: My game will reset as soon as it's over so I can play again.", + "User Story: I can choose whether I want to play as X or O.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "type": "zipline", + "challengeType": 3, + "isRequired": false, + "translations": { + "es": { + "title": "Crea un juego de Tic Tac Toe", + "description": [ + "Objetivo: Construye una aplicación en CodePen.io cuya funcionalidad sea similar a la de esta: https://codepen.io/freeCodeCamp/full/KzXQgy/.", + "Satisface las siguientes historias de usuario. Usa cualquier librería o APIs que necesites. Dale tu estilo personal.", + "Historia de usuario: Puedo jugar un juego de Tic Tac Toe contra el computador.", + "Historia de usuario: Mi juego se reiniciará tan pronto como termine para poder jugar de nuevo.", + "Historia de usuario: Puedo elegir si quiero jugar como X o como O.", + "Recuerda utilizar Leer-Buscar-Preguntar si te sientes atascado.", + "Cuando hayas terminado, pulsa el botón de \"I've completed this challenge\" e incluye un enlace a tu CodePen.", + "Puedes obtener retroalimentación sobre tu proyecto por parte de otros campistas, compartiéndolo en nuestra Sala de chat para revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "bd7158d8c442eddfaeb5bd1c", + "title": "Build a Simon Game", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/obYBjE.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I am presented with a random series of button presses.", + "User Story: Each time I input a series of button presses correctly, I see the same series of button presses but with an additional step.", + "User Story: I hear a sound that corresponds to each button both when the series of button presses plays, and when I personally press a button.", + "User Story: If I press the wrong button, I am notified that I have done so, and that series of button presses starts again to remind me of the pattern so I can try again.", + "User Story: I can see how many steps are in the current series of button presses.", + "User Story: If I want to restart, I can hit a button to do so, and the game will return to a single step.", + "User Story: I can play in strict mode where if I get a button press wrong, it notifies me that I have done so, and the game restarts at a new random series of button presses.", + "User Story: I can win the game by getting a series of 20 steps correct. I am notified of my victory, then the game starts over.", + "Hint: Here are mp3s you can use for each button: https://s3.amazonaws.com/freecodecamp/simonSound1.mp3, https://s3.amazonaws.com/freecodecamp/simonSound2.mp3, https://s3.amazonaws.com/freecodecamp/simonSound3.mp3, https://s3.amazonaws.com/freecodecamp/simonSound4.mp3.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "type": "zipline", + "challengeType": 3, + "isRequired": false, + "translations": { + "es": { + "title": "Construye un juego de Simon", + "description": [ + "Objetivo: Construye una aplicación en CodePen.io cuya funcionalidad sea similar a la de esta: https://codepen.io/Em-Ant/full/QbRyqq/.", + "Satisface las siguientes historias de usuario. Usa cualquier librería o APIs que necesites. Dale tu estilo personal.", + "Historia de usuario: Se me presenta una serie aleatoria de pulsaciones a botones.", + "Historia de usuario: Cada vez que presiono una secuencia de pulsaciones correctamente, veo que vuelve a ejecutarse la misma serie de pulsaciones con un paso adicional.", + "Historia de usuario: Escucho un sonido que corresponde a cada botón cuando se ejecuta una secuencia de pulsaciones, así como cuando yo presiono un botón.", + "Historia de usuario: Si presiono el botón equivocado, se me notifica sobre mi error, y se ejecuta de nuevo la serie correcta de pulsaciones para recordarme cuál es la secuencia correcta, tras lo cual puedo intentar de nuevo.", + "Historia de usuario: Puedo ver cuántos pasos hay en la serie de pulsaciones actual.", + "Historia de usuario: Si deseo reiniciar, puedo pulsar un botón para hacerlo, y el juego comenzará desde una secuencia con un solo paso.", + "Historia de usuario: Puedo jugar en modo estricto donde si presiono el botón equivocado, se me notifica de mi error, y el juego vuelve a comenzar con una nueva serie aleatoria de colores.", + "Historia de usuario: Puedo ganar el juego si completo 20 pasos correctos. Se me notifica sobre mi victoria, tras lo cual el juego se reinicia.", + "Pista: Aquí hay algunos mp3s que puedes utilizar para tus botones: https://s3.amazonaws.com/freecodecamp/simonSound1.mp3, https://s3.amazonaws.com/freecodecamp/simonSound2.mp3, https://s3.amazonaws.com/freecodecamp/simonSound3.mp3, https://s3.amazonaws.com/freecodecamp/simonSound4.mp3.", + "Recuerda utilizar Leer-Buscar-Preguntar si te sientes atascado.", + "Cuando hayas terminado, pulsa el botón de \"I've completed this challenge\" e incluye un enlace a tu CodePen.", + "Puedes obtener retroalimentación sobre tu proyecto por parte de otros campistas, compartiéndolo en nuestra Sala de chat para revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "bd7156d8c242eddfaeb5bd13", + "title": "Build a Camper Leaderboard", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/eZGMjp/.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can see a table of the freeCodeCamp campers who've earned the most brownie points in the past 30 days.", + "User Story: I can see how many brownie points they've earned in the past 30 days, and how many they've earned total.", + "User Story: I can toggle between sorting the list by how many brownie points they've earned in the past 30 days and by how many brownie points they've earned total.", + "Hint: To get the top 100 campers for the last 30 days: https://fcctop100.herokuapp.com/api/fccusers/top/recent.", + "Hint: To get the top 100 campers of all time: https://fcctop100.herokuapp.com/api/fccusers/top/alltime.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "releasedOn": "January 1, 2016", + "challengeSeed": [], + "tests": [], + "type": "zipline", + "isRequired": false, + "challengeType": 3, + "translations": { + "es": { + "title": "Crea un marcador para los campistas", + "description": [ + "Objetivo: Construye una aplicación en CodePen.io que funcione de forma similar al siguiente ejemplo: https://codepen.io/freeCodeCamp/full/eZGMjp/.", + "Satisface las siguientes historias de usuario. Usa cualquier librería o API que sea necesaria. ¡Ponle un toque personal!.", + "Historia de usuario: Puedo ver un tablero con los campistas de freeCodeCamp que han ganado más puntos de brownie en los últimos 30 días.", + "Historia de usuario: Puedo ver cuántos puntos de brownie han ganado en los últimos 30 días, y cuántos han ganado en total.", + "Historia de usuario: Puedo elegir entre dos formas de organizar la lista: 1) En base a cuántos puntos de brownie se han ganado en los últimos 30 días. 2) En base al número de puntos de brownie que han ganado en total.", + "Pista: Para obtener los 100 mejores campistas para los últimos 30 días: https://fcctop100.herokuapp.com/api/fccusers/top/recent.", + "Pista: Para obtener los 100 mejores campistas de toda la historia: http://fcctop100.herokuapp.com/api/fccusers/top/alltime.", + "Recuerda utilizar Read-Search-Ask si te sientes atascado.", + "Cuando termines, haz clic en el botón de \"I've completed this challenge\" e incluye el vínculo de tu proyecto en CodePen. ", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + }, + "ru": { + "title": "Создайте таблицу Кемперов-Лидеров", + "description": [ + "Задание: Создайте приложение CodePen.io, функционал которого схож с этим: https://codepen.io/freeCodeCamp/full/eZGMjp/.", + "Приложение должно удовлетворять нижеприведённым пользовательским историям. Используйте любые библиотеки или API, которые потребуются. Придайте ему свой личный стиль.", + "Пользовательская история: Я могу видеть таблицу кемперов freeCodeCamp, которые получили наибольшее количество очков за последние 30 дней.", + "Пользовательская история: Я могу видеть сколько очков они получили за последние 30 дней, и сколько они получили их всего.", + "Пользовательская история: Я могу отсортировать список по количеству очков, которые они получили за последние 30 дней, и по общему количеству полученных очков.", + "Подсказка: Ссылка на топ 100 кемперов за последние 30 дней в формате JSON: https://fcctop100.herokuapp.com/api/fccusers/top/recent.", + "Подсказка: Ссылка на топ 100 кемперов за все время в формате JSON: http://fcctop100.herokuapp.com/api/fccusers/top/alltime.", + "Если что-то не получается, не забывайте пользоваться методом Читай-Ищи-Спрашивай.", + "Когда закончите, нажмите кнопку \"I've completed this challenge\" и укажите ссылку на вашу работу на CodePen.", + "Вы можете получить отзыв о вашем проекте от коллег, поделившись ссылкой на него в нашем чате для рассмотрения кода. Также вы можете поделиться ею через Twitter и на странице freeCodeCamp вашего города на Facebook." + ] + } + } + }, + { + "id": "bd7155d8c242eddfaeb5bd13", + "title": "Build a Recipe Box", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/dNVazZ/.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can create recipes that have names and ingredients.", + "User Story: I can see an index view where the names of all the recipes are visible.", + "User Story: I can click into any of those recipes to view it.", + "User Story: I can edit these recipes.", + "User Story: I can delete these recipes.", + "User Story: All new recipes I add are saved in my browser's local storage. If I refresh the page, these recipes will still be there.", + "Hint: You should prefix your local storage keys on CodePen, i.e. _username_recipes", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "releasedOn": "January 1, 2016", + "challengeSeed": [], + "tests": [], + "type": "zipline", + "isRequired": false, + "challengeType": 3, + "translations": { + "ru": { + "title": "Создайте хранилище рецептов", + "description": [ + "Задание: Создайте приложение CodePen.io, функционал которого схож с этим: https://codepen.io/freeCodeCamp/full/dNVazZ/.", + "Правило #1: Не подсматривайте код приложения-примера. Напишите его самостоятельно.", + "Правило #2: Приложение должно удовлетворять нижеприведённым пользовательским историям. Используйте любые библиотеки или API, которые потребуются. Придайте ему свой личный стиль.", + "Правило #3: Для создания этого проекта вы должны использовать Sass и React.", + "Пользовательская история: Я могу создавать рецепты, содержащие название и ингредиенты.", + "Пользовательская история: Я могу просмотреть корневой вид, на котором видны все рецепты.", + "Пользовательская история: Я могу нажать на имя каждого из рецептов для просмотра содержимого.", + "Пользовательская история: Я могу отредактировать эти рецепты.", + "Пользовательская история: Я могу удалить эти рецепты.", + "Пользовательская история: Все новые рецепты, которые я добавил, сохранены в локальном хранилище моего браузера. Если я обновлю страницу, эти рецепты будут всё ещё там.", + "Если что-то не получается, не забывайте пользоваться методом Читай-Ищи-Спрашивай.", + "Когда закончите, нажмите кнопку \"I've completed this challenge\" и укажите ссылку на вашу работу на CodePen.", + "Вы можете получить отзыв о вашем проекте от коллег, поделившись ссылкой на него в нашем чате для рассмотрения кода. Также вы можете поделиться ею через Twitter и на странице Free Code Camp вашего города на Facebook." + ] + }, + "es": { + "title": "Crea una caja de recetas", + "description": [ + "Objetivo: Construye una aplicación en CodePen.io que funcione de forma similar al siguiente ejemplo: https://codepen.io/freeCodeCamp/full/dNVazZ/.", + "Regla #1: No veas el código del proyecto de ejemplo. Encuentra la forma de hacerlo por tu cuenta.", + "Regla #2: Satisface las siguientes historias de usuario. Usa cualquier librería o API que sea necesaria. ¡Ponle un toque personal!.", + "Rule #3: Debes utilizar ambos Sass y React para construir este proyecto.", + "Historia de usuario: Puedo crear recetas a las que les puedo poner un nombre y los ingredientes necesarios.", + "Historia de usuario: Puedo ver un índice que contenga los nombres de todas las recetas.", + "Historia de usuario: Puedo pulsar cualquiera de las recetas para verla.", + "Historia de usuario: Puedo editar las recetas.", + "Historia de usuario: Puedo eliminar las recetas.", + "Historia de usuario: Las recetas que voy agregando deben guardarse en el almacenamiento local de mi navegador. Las recetas deben seguir allí si refresco la página.", + "Recuerda utilizar Read-Search-Ask si te sientes atascado.", + "Cuando termines, haz clic en el botón de \"I've completed this challenge\" e incluye el vínculo de tu proyecto en CodePen. ", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "bd7154d8c242eddfaeb5bd13", + "title": "Build the Game of Life", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/BpwMZv/.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: When I first arrive at the game, it will randomly generate a board and start playing.", + "User Story: I can start and stop the board.", + "User Story: I can set up the board.", + "User Story: I can clear the board.", + "User Story: When I press start, the game will play out.", + "User Story: Each time the board changes, I can see how many generations have gone by.", + "Hint: Here's an explanation of Conway's Game of Life from John Conway himself: https://www.youtube.com/watch?v=E8kUJL04ELA", + "Hint: Here's an overview of Conway's Game of Life with rules for your reference: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "releasedOn": "January 1, 2016", + "challengeSeed": [], + "tests": [], + "type": "zipline", + "isRequired": false, + "challengeType": 3, + "translations": { + "ru": { + "title": "Создайте игру \"Жизнь\"", + "description": [ + "Задание: Создайте приложение CodePen.io, функционал которого схож с этим: https://codepen.io/freeCodeCamp/full/BpwMZv/.", + "Правило #1: Не подсматривайте код приложения-примера. Напишите его самостоятельно.", + "Правило #2: Приложение должно удовлетворять нижеприведённым пользовательским историям. Используйте любые библиотеки или API, которые потребуются. Придайте ему свой личный стиль.", + "Правило #3: Для создания этого проекта вы должны использовать Sass и React.", + "Пользовательская история: Когда я впервые запускаю игру, она генерирует доску случайным образом и начинает игру.", + "Пользовательская история: Я могу запустить и остановить игру.", + "Пользовательская история: Я могу настроить доску.", + "Пользовательская история: Я могу очистить доску.", + "Пользовательская история: Когда я нажимаю начать, игра начинает воспроизведение.", + "Пользовательская история: Каждый раз, когда доска меняется, я могу видеть сколько поколений прошло.", + "Подсказка: Вот объяснение игры \"Жизнь\" от её создателя Джона Конвея: https://www.youtube.com/watch?v=E8kUJL04ELA", + "Подсказка: Вот обзор правил игры \"Жизнь\" для вашего сведения: https://ru.wikipedia.org/wiki/Жизнь_(игра)", + "Если что-то не получается, не забывайте пользоваться методом Читай-Ищи-Спрашивай.", + "Когда закончите, нажмите кнопку \"I've completed this challenge\" и укажите ссылку на вашу работу на CodePen.", + "Вы можете получить отзыв о вашем проекте от коллег, поделившись ссылкой на него в нашем чате для рассмотрения кода. Также вы можете поделиться ею через Twitter и на странице Free Code Camp вашего города на Facebook." + ] + }, + "es": { + "title": "Crea un Juego de la vida", + "description": [ + "Objetivo: Construye una aplicación en CodePen.io que funcione de forma similar al siguiente ejemplo: https://codepen.io/freeCodeCamp/full/BpwMZv/.", + "Regla #1: No veas el código del proyecto de ejemplo. Encuentra la forma de hacerlo por tu cuenta.", + "Regla #2: Satisface las siguientes historias de usuario. Usa cualquier librería o API que sea necesaria. ¡Ponle un toque personal!.", + "Rule #3: Debes utilizar ambos Sass y React para construir este proyecto.", + "Historia de usuario: La aplicación debe generar aleatoriamente un tablero y comenzar a jugar cuando entro al juego por primera vez.", + "Historia de usuario: Puedo iniciar y detener el tablero.", + "Historia de usuario: Puedo preparar el tablero.", + "Historia de usuario: Puedo limpiar el tablero.", + "Historia de usuario: El juego inicia cuando presiono un botón de inicio.", + "Historia de usuario: Puedo ver cuántas generaciones han pasado cada vez que el tablero cambia.", + "Pista: Puedes encontrar una explicación del Juego de la vida de Conway de parte del mismísimo John Conway aquí: https://www.youtube.com/watch?v=E8kUJL04ELA", + "Pista: Puedes referirte al siguiente enlace para obtener información general acerca del Juego de la vida de Conway incluyendo las reglas del juego: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life", + "Recuerda utilizar Read-Search-Ask si te sientes atascado.", + "Cuando termines, haz clic en el botón de \"I've completed this challenge\" e incluye el vínculo de tu proyecto en CodePen. ", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "bd7153d8c242eddfaeb5bd13", + "title": "Build a Roguelike Dungeon Crawler Game", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/apLXEJ/.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I have health, a level, and a weapon. I can pick up a better weapon. I can pick up health items.", + "User Story: All the items and enemies on the map are arranged at random.", + "User Story: I can move throughout a map, discovering items.", + "User Story: I can move anywhere within the map's boundaries, but I can't move through an enemy until I've beaten it.", + "User Story: Much of the map is hidden. When I take a step, all spaces that are within a certain number of spaces from me are revealed.", + "User Story: When I beat an enemy, the enemy goes away and I get XP, which eventually increases my level.", + "User Story: When I fight an enemy, we take turns damaging each other until one of us loses. I do damage based off of my level and my weapon. The enemy does damage based off of its level. Damage is somewhat random within a range.", + "User Story: When I find and beat the boss, I win.", + "User Story: The game should be challenging, but theoretically winnable.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "releasedOn": "January 1, 2016", + "challengeSeed": [], + "tests": [], + "type": "zipline", + "isRequired": false, + "challengeType": 3, + "translations": { + "es": { + "title": "Crea un juego de dragones al estilo Rogue", + "description": [ + "Objetivo: Construye una aplicación en CodePen.io que funcione de forma similar al siguiente ejemplo: https://codepen.io/freeCodeCamp/full/apLXEJ/.", + "Satisface las siguientes historias de usuario. Usa cualquier librería o API que sea necesaria. ¡Ponle un toque personal!.", + "Historia de usuario: Tengo energía, nivel de habilidad y un arma. Puedo recoger un arma mejor. Puedo recoger ítems que recuperan mi energía.", + "Historia de usuario: Todos los ítems y los enemigos en el mapa están colocados aleatoriamente.", + "Historia de usuario: Puedo moverme a lo largo de un mapa y descubrir ítems.", + "Historia de usuario: Puedo moverme hacia cualquier parte dentro de los límites del mapa, pero no puedo moverme sobre un enemigo hasta que lo haya vencido.", + "Historia de usuario: Gran parte del mapa está escondido. Cuando doy un paso, todos los espacios que están a cierto número de espacios de distancia de mi son revelados.", + "Historia de usuario: Cuando venzo un enemigo, este desaparece y yo gano puntos de experiencia (XP), lo que eventualmente me permite aumentar de nivel.", + "Historia de usuario: Cuando peleo con un enemigo, tomamos turnos haciéndonos daño hasta que uno de los dos pierde. El daño que hago está basado en mi nivel de experiencia y en el arma que estoy utilizando. El enemigo hace daño basado en su nivel. El daño es aleatorio dentro de cierto márgen.", + "Historia de usuario: Gano el juego cuando encuentre y venza al jefe.", + "Historia de usuario: El juego debe representar un reto, pero ganar debe ser teóricamente posible.", + "Recuerda utilizar Read-Search-Ask si te sientes atascado.", + "Cuando termines, haz clic en el botón de \"I've completed this challenge\" e incluye el vínculo de tu proyecto en CodePen. ", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + }, + "ru": { + "title": "Создайте Roguelike-подобную игру Подземелье", + "description": [ + "Задание: Создайте приложение CodePen.io, функционал которого схож с этим: https://codepen.io/freeCodeCamp/full/apLXEJ/.", + "Приложение должно удовлетворять нижеприведённым пользовательским историям. Используйте любые библиотеки или API, которые потребуются. Придайте ему свой личный стиль.", + "Пользовательская история: У меня есть жизни, уровень и оружие. Я могу подобрать оружие получше. Я могу подобрать очки здоровья.", + "Пользовательская история: Все предметы и враги располагаются на карте случайным образом.", + "Пользовательская история: Я могу передвигаться по карте, обнаруживая новые предметы.", + "Пользовательская история: Я могу двигаться куда угодно в рамках карты, но не могу продвинуться дальше врага, пока он не будет побежден.", + "Пользовательская история: Большая часть карты скрыта. Когда я делаю шаг, все клетки в определенном количестве клеток от меня становятся видимы.", + "Пользовательская история: Когда я побеждаю врага, враг исчезает, а я получаю очки опыта (XP), что увеличивает мой уровень.", + "Пользовательская история: Когда я веду бой с врагом, мы поочередно наносим друг-другу повреждения, до тех пор пока кто-нибудь не победит. Я наношу повреждения, которые зависят от моего уровня и моего оружия. Враг наносит повреждения, которые зависят от его уровня. Значение повреждений распределено случайным образом в некотором диапазоне.", + "Пользовательская история: Когад я нахожу и побеждаю босса, я выигрываю игру.", + "Пользовательская история: Игра должна быть интересной и достаточно сложной, но теоретически проходимой.", + "Если что-то не получается, не забывайте пользоваться методом Читай-Ищи-Спрашивай.", + "Когда закончите, нажмите кнопку \"I've completed this challenge\" и укажите ссылку на вашу работу на CodePen.", + "Вы можете получить отзыв о вашем проекте от коллег, поделившись ссылкой на него в нашем чате для рассмотрения кода. Также вы можете поделиться ею через Twitter и на странице freeCodeCamp вашего города на Facebook." + ] + } + } + }, + { + "id": "bd7150d8c442eddfafb5bd1c", + "title": "P2P Video Chat Application", + "description": [ + "Objective: Build a Glitch app that is functionally similar to this: https://grove-voice.glitch.me.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: Upon arriving, the browser will prompt me to access my camera and microphone. ", + "User Story: After I give it permission, I am prompted to type in a room name.", + "User Story: Once I type in the room name, a room will be created if no room of that name existed before. ", + "User Story: A friend of mine can subsequently go to the same website, type in the same room I entered, and join the same room, then enter into a video chat with me. ", + "User Story: If I type in a room name, and there are already two people in that room, I get a notification that the room is full. ", + "User Story: Anyone can create or join any room. And there can be any number of rooms, but all of them must have unique names. ", + "User Story: I can choose to not permit the site to access my microphone and webcam. If I choose not to do this, if some other driver problem occurs, I see an error message saying these are required. ", + "User Story: When I choose to cancel the room name input step, or if I type in no name, or just spaces, it should again ask me again to type in a valid room name. ", + "User Story: If one of the two people in the room get disconnected, they can reconnect to the same room and continue chatting.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your Glitch App.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "type": "zipline", + "challengeType": 3, + "isRequired": false, + "releasedOn": "January 1, 2016" + }, + { + "id": "bd7198d8c242eddfaeb5bd13", + "title": "Show National Contiguity with a Force Directed Graph", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/xVopBo.", + "Fulfill the following user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can see a Force-directed Graph that shows which countries share borders.", + "User Story: I can see each country's flag on its node.", + "Hint: Here's a dataset you can use to build this: https://raw.githubusercontent.com/DealPete/forceDirected/master/countries.json", + "Hint: You can create a spritesheet of national flags at https://www.flag-sprites.com.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "isRequired": false, + "releasedOn": "January 1, 2016", + "type": "zipline", + "challengeType": 3, + "translations": { + "es": { + "title": "Muestra asociaciones utilizando un gráfico de fuerzas dirigidas", + "description": [ + "Objetivo: Construye una aplicación en CodePen.io que funcione de forma similar al siguiente ejemplo: https://codepen.io/freeCodeCamp/full/KVNNXY.", + "Regla #1: No veas el código del proyecto de ejemplo. Encuentra la forma de hacerlo por tu cuenta.", + "Regla #2: Satisface las siguientes historias de usuario. Usa cualquier librería o API que sea necesaria. ¡Ponle un toque personal!.", + "Regla #3: Debes utilizar D3.js para construir este proyecto.", + "Historia de usuario: Puedo ver un gráfico de fuerza dirigida que muestra qué campistas están publicando enlaces en Camper News hacia qué dominios.", + "Historia de usuario: Puedo ver el icono de cada campista en su nodo respectivo.", + "Historia de usuario: Puedo ver la relación entre los campistas y los dominios que publican.", + "Historia de usuario: Puedo conocer aproximadamente cuántas veces los campistas han enlazado un dominio en particular a partir del tamaño del nodo respectivo.", + "Historia de usuario: Puedo conocer aproximadamente cuántas veces un campista específico ha publicado un enlace a partir del tamaño de su nodo.", + "Pista: La siguiente es la ruta del API de noticias de Camper News: http://www.freecodecamp.org/news/hot.", + "Recuerda utilizar Read-Search-Ask si te sientes atascado.", + "Cuando termines, haz clic en el botón de \"I've completed this challenge\" e incluye el vínculo de tu proyecto en CodePen. ", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "bd7108d8c242eddfaeb5bd13", + "title": "Map Data Across the Globe", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/mVEJag.", + "Fulfill the following user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can see where all Meteorites landed on a world map.", + "User Story: I can tell the relative size of the meteorite, just by looking at the way it's represented on the map.", + "User Story: I can mouse over the meteorite's data point for additional data.", + "Hint: Here's a dataset you can use to build this: https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/meteorite-strike-data.json", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "isRequired": false, + "releasedOn": "January 1, 2016", + "type": "zipline", + "challengeType": 3, + "translations": { + "es": { + "title": "Mapea datos a lo largo del Globo", + "description": [ + "Objetivo: Construye una aplicación en CodePen.io que funcione de forma similar al siguiente ejemplo: https://codepen.io/freeCodeCamp/full/mVEJag.", + "Regla #1: No veas el código del proyecto de ejemplo. Encuentra la forma de hacerlo por tu cuenta.", + "Regla #2: Satisface las siguientes historias de usuario. Usa cualquier librería o API que sea necesaria. ¡Ponle un toque personal!.", + "Regla #3: Debes utilizar D3.js para construir este proyecto.", + "Historia de usuario: Puedo ver a dónde cayeron todos los meteoritos en un mapa mundi.", + "Historia de usuario: Puedo distinguir el tamaño relativo de cada meteorito simplemente viendo la forma en que está representado en el mapa.", + "Historia de usuario: Puedo mover el ratón sobre el dato de cada meteorito para obtener información adicional.", + "Pista: Puedes utilizar el siguiente conjunto de datos para construir tu proyecto: https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/meteorite-strike-data.json", + "Recuerda utilizar Read-Search-Ask si te sientes atascado.", + "Cuando termines, haz clic en el botón de \"I've completed this challenge\" e incluye el vínculo de tu proyecto en CodePen. ", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "bd7158d8c443eddfaeb5bd0f", + "title": "Manage a Book Trading Club", + "description": [ + "Objective: Build a Glitch app that is functionally similar to this: https://chrome-delivery.glitch.me.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can view all books posted by every user.", + "User Story: I can add a new book.", + "User Story: I can update my settings to store my full name, city, and state.", + "User Story: I can propose a trade and wait for the other user to accept the trade.", + "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "type": "basejump", + "challengeType": 4, + "translations": { + "es": { + "description": [ + "Objetivo: Construye una aplicación de pila completa (full stack) en JavaScript que funcione de forma similar al siguiente proyecto: http://bookjump.herokuapp.com/ y despliégalo en Heroku.", + "Ten en cuenta que para cada proyecto, debes crear un nuevo repositorio en GitHub y un nuevo proyecto en Heroku. Si no recuerdas cómo hacerlo, visita de nuevo https://freecodecamp.org/challenges/get-set-for-our-dynamic-web-application-projects.", + "Estas son las Historias de usuario que debes satisfacer para este Basejump:", + "Historia de usuario: Puedo ver todos los libros agregados por cada usuario.", + "Historia de usuario: Puedo agregar un nuevo libro.", + "Historia de usuario: Puedo actualizar mi configuración para que almacene mi nombre completo, ciudad y Estado.", + "Historia de usuario: Puedo proponer un intercambio y esperar a que algún otro usuario acepte el trato.", + "Una vez hayas terminado de implementar estas historias de usuario, pulsa el botón de \"I've completed this challenge\" e incluye las URLs de tu repositorio GitHub y de tu aplicación corriendo en Heroku.", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ], + "title": "Administra un club de intercambio de libros" + } + } + }, + { + "id": "bd7158d8c443eddfaeb5bdee", + "title": "Build a Pinterest Clone", + "description": [ + "Objective: Build a Glitch app that is functionally similar to this: https://wild-song.glitch.me.", + "Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: As an unauthenticated user, I can login with GitHub.", + "User Story: As an authenticated user, I can link to images.", + "User Story: As an authenticated user, I can delete images that I've linked to.", + "User Story: As an authenticated user, I can see a Pinterest-style wall of all the images I've linked to.", + "User Story: As an unauthenticated user, I can browse other users' walls of images.", + "User Story: As an authenticated user, if I upload an image that is broken, it will be replaced by a placeholder image. (can use jQuery broken image detection)", + "Hint: Masonry.js is a library that allows for Pinterest-style image grids.", + "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "type": "basejump", + "challengeType": 4, + "translations": { + "es": { + "description": [ + "Objetivo: Construye una aplicación de pila completa (full stack) en JavaScript que funcione de forma similar al siguiente proyecto: https://midnight-dust.glitch.me/ y despliégalo en Heroku.", + "Ten en cuenta que para cada proyecto, debes crear un nuevo repositorio en GitHub y un nuevo proyecto en Heroku. Si no recuerdas cómo hacerlo, visita de nuevo https://freecodecamp.org/challenges/get-set-for-our-dynamic-web-application-projects.", + "Estas son las Historias de usuario que debes satisfacer para este Basejump:", + "Historia de usuario: Como usuario autenticado, puedo acceder a mi cuenta con Twitter.", + "Historia de usuario: Como usuario autenticado, puedo agregar enlaces a imágenes.", + "Historia de usuario: Como usuario autenticado, puedo elimiar imágenes que he agregado.", + "Historia de usuario: Como usuario autenticado, puedo ver un muro al estilo de Pinterest con todas las imágenes para las que he agregado un enlace.", + "Historia de usuario: Como usuario no autenticado, puedo navegar los muros de imágenes de otros usuarios.", + "Historia de usuario: Como usuario autenticado, si agrego una imagen corrupta, será reemplazada por una imagen predeterminada. (Puedes utilizar la detección de imágenes corruptas de jQuery)", + "Pista: Masonry.js es una librería que permite crear cuadrículas de imágenes al estilo de Pinterest.", + "Una vez hayas terminado de implementar estas historias de usuario, pulsa el botón de \"I've completed this challenge\" e incluye las URLs de tu repositorio GitHub y de tu aplicación corriendo en Heroku.", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ], + "title": "Crea un clon de Pinterest" + } + } + }, + { + "id": "bd7158d8c443eddfaeb5bdff", + "title": "Build a Nightlife Coordination App", + "description": [ + "Objective: Build a full stack JavaScript app that is functionally similar to this: http://whatsgoinontonight.herokuapp.com/ and deploy it to Heroku.", + "Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit https://freecodecamp.com/challenges/get-set-for-our-dynamic-web-application-projects.", + "Here are the specific user stories you should implement for this project:", + "User Story: As an unauthenticated user, I can view all bars in my area.", + "User Story: As an authenticated user, I can add myself to a bar to indicate I am going there tonight.", + "User Story: As an authenticated user, I can remove myself from a bar if I no longer want to go there.", + "User Story: As an unauthenticated user, when I login I should not have to search again.", + "Hint: Try using the Yelp API to find venues in the cities your users search for. If you use Yelp's API, be sure to mention so in your app.", + "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [ + "Gei7QfPmcMw" + ], + "tests": [], + "type": "basejump", + "challengeType": 4, + "isRequired": true, + "translations": { + "es": { + "description": [ + "Objetivo: Construye una aplicación de pila completa (full stack) en JavaScript que funcione de forma similar al siguiente proyecto: http://whatsgoinontonight.herokuapp.com/ y despliégala en Heroku.", + "Ten en cuenta que para cada proyecto, debes crear un nuevo repositorio en GitHub y un nuevo proyecto en Heroku. Si no recuerdas cómo hacerlo, visita de nuevo https://freecodecamp.com/challenges/get-set-for-our-dynamic-web-application-projects.", + "Estas son las Historias de usuario que debes satisfacer para este Basejump:", + "Historia de usuario: Como un usuario no autenticado, puedo ver todos los bares en mi área.", + "Historia de usuario: Como un usuario autenticado, puedo agregarme a mí mismo a un bar para indicar que voy a estar allí esta noche.", + "Historia de usuario: Como un usuario autenticado, puedo removerme de un bar si ya no pienso ir allí.", + "Historia de usuario: Como un usuario no autenticado, cuando accedo a mi cuenta no debo tener la necesidad de buscar de nuevo.", + "Pista: Prueba utilizar el API de Yelp para encontrar lugares en las ciudades donde tus usuarios buscan. Si utilizas el API de Yelp, asegúrate de mencionarlo en tu aplicación.", + "Una vez hayas terminado de implementar estas historias de usuario, pulsa el botón de \"I've completed this challenge\" e incluye las URLs de tu repositorio GitHub y de tu aplicación corriendo en Heroku.", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "bd7158d8c443eddfaeb5bd0e", + "title": "Chart the Stock Market", + "description": [ + "Objective: Build a full stack JavaScript app that is functionally similar to this: http://watchstocks.herokuapp.com/ and deploy it to Heroku.", + "Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit https://freecodecamp.com/challenges/get-set-for-our-dynamic-web-application-projects.", + "Here are the specific user stories you should implement for this project:", + "User Story: I can view a graph displaying the recent trend lines for each added stock.", + "User Story: I can add new stocks by their symbol name.", + "User Story: I can remove stocks.", + "User Story: I can see changes in real-time when any other user adds or removes a stock. For this you will need to use Web Sockets.", + "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [ + "CENs50cnRgM" + ], + "tests": [], + "type": "basejump", + "challengeType": 4, + "isRequired": true, + "translations": { + "es": { + "description": [ + "Objetivo: Construye una aplicación de pila completa (full stack) en JavaScript que funcione de forma similar al siguiente proyecto: http://watchstocks.herokuapp.com/ y despliégalo en Heroku.", + "Ten en cuenta que para cada proyecto, debes crear un nuevo repositorio en GitHub y un nuevo proyecto en Heroku. Si no recuerdas cómo hacerlo, visita de nuevo https://freecodecamp.com/challenges/get-set-for-our-dynamic-web-application-projects.", + "Estas son las Historias de usuario que debes satisfacer para este Basejump:", + "Historia de usuario: Como usuario, puedo ver un gráfico que me muestre las líneas de tendencia recientes para cada acción agregada.", + "Historia de usuario: Como usuario, puedo agregar nuevas acciones por su símbolo.", + "Historia de usuario: Como usuario, puedo remover acciones.", + "Historia de usuario: Como usuario, puedo ver cambios en tiempo real cuando algún otro usuario agrega o remueve una acción. Puedes usar Web Sockets para hacer esto.", + "Una vez hayas terminado de implementar estas historias de usuario, pulsa el botón de \"I've completed this challenge\" e incluye las URLs de tu repositorio GitHub y de tu aplicación corriendo en Heroku.", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "bd7158d8c443eddfaeb5bdef", + "title": "Build a Voting App", + "description": [ + "Objective: Build a full stack JavaScript app that is functionally similar to this: https://fcc-voting-arthow4n.herokuapp.com/ and deploy it to Heroku.", + "Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit https://freecodecamp.com/challenges/get-set-for-our-dynamic-web-application-projects.", + "Here are the specific user stories you should implement for this project:", + "User Story: As an authenticated user, I can keep my polls and come back later to access them.", + "User Story: As an authenticated user, I can share my polls with my friends.", + "User Story: As an authenticated user, I can see the aggregate results of my polls.", + "User Story: As an authenticated user, I can delete polls that I decide I don't want anymore.", + "User Story: As an authenticated user, I can create a poll with any number of possible items.", + "User Story: As an unauthenticated or authenticated user, I can see and vote on everyone's polls.", + "User Story: As an unauthenticated or authenticated user, I can see the results of polls in chart form. (This could be implemented using Chart.js or Google Charts.)", + "User Story: As an authenticated user, if I don't like the options on a poll, I can create a new option.", + "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [ + "JBKnbY_fdg4" + ], + "tests": [], + "type": "basejump", + "challengeType": 4, + "isRequired": true, + "translations": { + "es": { + "description": [ + "Objetivo: Construye una aplicación de pila completa (full stack) en JavaScript que funcione de forma similar al siguiente proyecto: https://fcc-voting-arthow4n.herokuapp.com/ y despliégala en Heroku.", + "Ten en cuenta que para cada proyecto, debes crear un nuevo repositorio en GitHub y un nuevo proyecto en Heroku. Si no recuerdas cómo hacerlo, visita de nuevo https://freecodecamp.com/challenges/get-set-for-our-dynamic-web-application-projects.", + "Estas son las Historias de usuario que debes satisfacer para este proyecto:", + "Historia de usuario: Como un usuario autenticado, puedo guardar mis votaciones y acceder a ellas posteriormente.", + "Historia de usuario: Como un usuario autenticado, puedo compartir mis votaciones con mis amigos.", + "Historia de usuario: Como un usuario autenticado, puedo ver los resultados agregados de mis votaciones.", + "Historia de usuario: Como un usuario autenticado, puedo eliminar votaciones que ya no quiero tener guardadas.", + "Historia de usuario: Como un usuario autenticado, puedo crear una votación con cualquier número de opciones.", + "Historia de usuario: Como un usuario autenticado o no autenticado, puedo ver y votar en las votaciones de otros.", + "Historia de usuario: Como un usuario autenticado o no autenticado, puedo ver los resultados de las votaciones por medio de un gráfico. (Esto podría implementarse utilizando Chart.js o Google Charts.)", + "Historia de usuario: Como un usuario autenticado, si no me gustan las opciones en una votación, puedo crear una nueva opción.", + "Una vez hayas terminado de implementar estas historias de usuario, pulsa el botón de \"I've completed this challenge\" e incluye las URLs de tu repositorio GitHub y de tu aplicación corriendo en Heroku.", + "Puedes obtener retroalimentación acerca de tu proyecto de parte de tus compañeros campistas compartiéndolo en nuestro Cuarto de revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)." + ] + } + } + }, + { + "id": "5a4b7fcdb66f799f199e11db", + "title": "Build a Pong Game", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/satyamdev/full/pdMmBp.", + "Rule #1: Don't look at the example project's code. Figure it out for yourself.", + "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can control a paddle.", + "User Story: The computer can control the other paddle.", + "User Story: The computer's paddle is unbeatable. It should never miss the ball.", + "User Story: The game keeps track of the player and computer's score.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "type": "zipline", + "challengeType": 3, + "isRequired": false + }, + { + "id": "5a5d02bd919fcf9ca8cf46cb", + "title": "Build a Light-Bright App", + "description": [ + "Objective: Build a CodePen.io app that is functionally similar to this: https://codepen.io/freeCodeCamp/full/eyLYXE.", + "Rule #1: Don't look at the example project's code. Figure it out for yourself.", + "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", + "User Story: I can click or drag the mouse cursor to color the circles.", + "User Story: I can double-click on a colored circle to remove the color.", + "User Story: I can click on a colored circle to change its color.", + "User Story: I should get a circle of different color on each click.", + "User Story: I can click on the 'Reset' button to remove the recent color.", + "User Story: I can click on the 'Reset All' button to remove all the colors from the circles.", + "Remember to use Read-Search-Ask if you get stuck.", + "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.", + "You can get feedback on your project by sharing it with your friends on Facebook." + ], + "challengeSeed": [], + "tests": [], + "type": "zipline", + "challengeType": 3, + "isRequired": false + } + ], + "fileName": "08-coding-interview-questions-and-take-home-assignments/take-home-interview-projects.json", + "superBlock": "coding-interview-questions-and-take-home-assignments", + "superOrder": 8 +} \ No newline at end of file diff --git a/packages/learn/seed/project-euler-guide.md b/packages/learn/seed/project-euler-guide.md new file mode 100644 index 0000000000..c1e6d67065 --- /dev/null +++ b/packages/learn/seed/project-euler-guide.md @@ -0,0 +1,249 @@ +# A guide to improve Project Euler's problems + +Thank you for contributing to freeCodeCamp, your help is definitely needed here! + +freeCodeCamp is having a great breakthrough ahead, one of it is to prepare +campers for interview questions, and Project Euler is one of them. + +And to let campers having fun with this challenges during Christmas, we are +going to have a lot of help here to improve the challenges of Project Euler +problems (so people won't cheating by returning the value right away, since +Project Euler's problems only assert one answer.) + +**Table of Contents** + +* [What is Project Euler](#what-is-project-euler) +* [How to improve the problems](#how-to-improve-the-problems) + +## What is Project Euler + +[Project Euler](https://projecteuler.net/) is a series of challenging +mathematical/computer programming problems that will require more than just +mathematical insights to solve. Although mathematics will help you arrive at +elegant and efficient methods, the use of a computer and programming skills will +be required to solve most problems. + +The motivation for starting Project Euler, and its continuation, is to provide a +platform for the inquiring mind to delve into unfamiliar areas and learn new +concepts in a fun and recreational context. + +## How to improve the problems + +The Project Euler problems seed can be found at +`seed/challenges/08-coding-interview-questions-and-take-home-assignments/project-euler-problems.json` + +Here's what it will look like (this is before the improvements, take problem 23 +as the example) + +```javascript +{ + "_id": "5900f3831000cf542c50fe96", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 23: Non-abundant sums", + "tests": [ + "assert.strictEqual(euler23(), 4179871, 'message: euler23() should return 4179871.');" + ], + "solutions": [], + "translations": {}, + "challengeSeed": [ + "function euler23() {", + " // Good luck!", + " return true;", + "}", + "", + "euler23();" + ], + "description": [ + "A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.", + "A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.", + "", + "As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.", + "Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers." + ] +}, +``` + +and here's after some improvements + +```javascript +{ + "_id": "5900f3831000cf542c50fe96", + "challengeType": 5, + "type": "bonfire", + "title": "Problem 23: Non-abundant sums", + "tests": [ + "assert(sumOfNonAbundantNumbers(10000) === 3731004, 'message: sumOfNonAbundantNumbers(10000) should return 3731004.');", + "assert(sumOfNonAbundantNumbers(15000) === 4039939, 'message: sumOfNonAbundantNumbers(15000) should return 4039939.');", + "assert(sumOfNonAbundantNumbers(20000) === 4159710, 'message: sumOfNonAbundantNumbers(20000) should return 4159710.');", + "assert(sumOfNonAbundantNumbers(28123) === 4179871, 'message: sumOfNonAbundantNumbers(28123) should return 4179871.');" + ], + "solutions": [], + "translations": {}, + "challengeSeed": [ + "function sumOfNonAbundantNumbers(n) {", + " // Good luck!", + " return n;", + "}", + "", + "sumOfNonAbundantNumbers(28123);" + ], + "description": [ + "A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.", + "A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.", + "", + "As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.", + "Find the sum of all positive integers <= n which cannot be written as the sum of two abundant numbers." + ] +}, +``` + +Don't be confused now, here's what to do to improve the problems: + +(We expect you already have forked freeCodeCamp's repository) + +### Step 1: Create new branch at your git origin (e.g: `feature/problem_euler23`) + +Always create the branch with the base refer to the newest freeCodeCamp's +staging branch, here's how to do that: + +1. Do fetch staging branch from freeCodeCamp's repository `$ git fetch upstream + staging` +2. Checkout to the staging branch `$ git checkout upstream/staging` +3. Create branch from upstream/staging `$ git checkout -b ` + +### Step 2: Change the name of the function to more readable + +For example, from `euler23()` into `sumOfNonAbundantNumbers()` We took the name +from the problem name :D + +### Step 3: Solve the problem by yourself + +Try to solve the problem by yourself but if you get stucked, + +Here's what to do: you can go to [mathblog](http://www.mathblog.dk/) or +[dreamshire](https://blog.dreamshire.com) to find other people's solution +written in other languages (usually C and C#) Learn from their solution and port +it to JavaScript :) ( Always have the perspective of learning, don't just copy +paste other people's code ) + +So from the example here's my solution (We didn't include it in the JSON because +up till now, we couldn't find a way to fit it in, when we transformed it into +array of strings it spits out error when running `$ npm run test-challenges` it +will be awesome if you can find how to fits that right in) + +```javascript +function sumOfNonAbundantNumbers() { + const getFactors = number => { + let factors = []; + + let possibleFactor = 1; + let sqrt = Math.sqrt(number); + + while (possibleFactor <= sqrt) { + if (number % possibleFactor == 0) { + factors[factors.length] = possibleFactor; + + let otherPossibleFactor = number / possibleFactor; + if (otherPossibleFactor > possibleFactor) + factors[factors.length] = otherPossibleFactor; + } + possibleFactor++; + } + + return factors; + }; + + const getAbundantNumbers = upperLimit => { + let abundantNumbers = []; + for (let i = 12; i <= upperLimit; i++) { + let factors = getFactors(i); + let factorSum = 0; + for (let factor, j = 0; (factor = factors[j]); j++) + if (i != factor) factorSum += factor; + + if (factorSum > i) { + abundantNumbers.push(i); + } + } + return abundantNumbers; + }; + + var abundantNumbers = getAbundantNumbers(28123); + + var sum = 0; + + for (var testNum = 1; testNum <= 28123; testNum++) { + var sumOfAbundant = false; + for ( + var i = 0, j = abundantNumbers.length - 1, abundantNumber1; + (abundantNumber1 = abundantNumbers[i]); + i++ + ) { + if (abundantNumber1 > testNum) { + break; + } + + var abundantNumber2 = abundantNumbers[j]; + while (j > 0 && abundantNumber1 + abundantNumber2 > testNum) { + abundantNumber2 = abundantNumbers[--j]; + } + + if (abundantNumber1 + abundantNumber2 == testNum) { + sumOfAbundant = true; + break; + } + } + if (!sumOfAbundant) { + sum += testNum; + } + } + + return sum; +} +``` + +After finished solving the problem, you can improve the task a little bit, for +example compared to asking campers to find the sum of all the positive integers, +you can ask campers to find the sum of all positive integers <= n. + +(if you add more assertions to the problem, always assert less than the original +problem, to prevent infinite loop, etc) + +One last thing, always make sure that the return value of the function is always +the same data type to which you want the function to return + +Like in the example above, we want the user to return integer, so we changed the +return value from true into integer. + +### Step 4: Running Test on Arcade Mode + +After done with the solution, run the test on +[ FCC's Arcade Mode ](https://github.com/freeCodeCamp/arcade-mode) + +### Step 5: Commit changes and push to your origin + +1. Do changes and add changed files to stage `$ git add .` +2. Commit those changes using `$ npm run commit` and follow the instruction + there. +3. And run `$ git push origin ` + +### Step 5: Create Pull Request to freeCodeCamp's staging branch + +Create PR to freeCodeCamp's staging branch and wait for your code to be assesed +from the maintainer. + +That's all it! if there's something unclear and you still have questions, you +can chat from gitter in +[Arcade-Mode](https://gitter.im/FreeCodeCamp/arcade-mode) +[Contributors](https://gitter.im/FreeCodeCamp/Contributors) or you can text me +right away @alvinkl + +# Why do we have to improve Project Euler problems? + +Our goal is to prevent user from cheating and just returning the project euler +result rightaway, and by giving more assertions and improving a bit of the task +we are able to make the challenge more challenging as well. + +With your help, we can help people to practice their skills and be confident to +face technical interviews like this :) diff --git a/packages/learn/seed/quiz-conversion/system-design-and-concept-questions.json b/packages/learn/seed/quiz-conversion/system-design-and-concept-questions.json new file mode 100644 index 0000000000..7c6ddeea67 --- /dev/null +++ b/packages/learn/seed/quiz-conversion/system-design-and-concept-questions.json @@ -0,0 +1,1089 @@ +{ + "name": "System Design and Concept Questions", + "order": 3, + "time": "", + "helpRoom": "HelpJavaScript", + "challenges": [ + { + "id": "59874fc749228906236a3275", + "title": "Array.prototype.map", + "description": [ + { + "subtitle": "Flooring an Array", + "question": + "What will the following code print out?\n
const results = [1.32, 2.43, 3.9]\n  .map(Math.floor);\nconsole.log(results);
", + "choices": [ + "
1.32 2.43 3.9
", + "
['1.32', '2.43', '3.9']
", + "
[1, 2, 3]
", + "
'1 2 3'
" + ], + "answer": 2, + "explanation": + "The map function takes a callback function as it's first parameter and applies that function against every value inside the array. In this example, our callback function is the Math.floor function which will truncate the decimal points of all the numbers and convert them to integers." + }, + { + "subtitle": "Custom Map Functions", + "question": + "What will the following code print out?\n
const results = ['a', 'b', 'c']\n  .map(a => [a.toUpperCase()]);\nconsole.log(results);
", + "choices": [ + "
[['A'], ['B'], ['C']]
", + "
['A', 'B', 'C']
", + "
['a', 'b', 'c]
", + "
'ABC'
" + ], + "answer": 0, + "explanation": + "The map function will return a new array with each element equal to the old element ran through a callback function. Our callback function takes our original element, changes it to a upper case, and then wraps it in an array; thus, leaving us with [['A'], ['B'], ['C']]" + }, + { + "subtitle": "Maps on Maps", + "question": + "What will the following code print out?\n
const results = [[4, 1], [2, 0], [3, 3]]\n  .map(a => \n    a.map(b => b % 2)[0] + a.map(b => b - 1)[1]\n  )\nconsole.log(results);
", + "choices": [ + "
[[0, 1], [0, 0], [1, 1]]
", + "
[[0, 0], [0, -1], [1, 2]]
", + "
[1, 1, 2]
", + "
[0, -1, 3]
" + ], + "answer": 3, + "explanation": + "This answer can be explained by first looking at the example of what happens with the first element in our array, [4, 1]. Our first map callback will run a mod 2 map function over [4, 1] leaving us with a new array of [0, 1]. The second map call which is inside our callback will subtract 1 from every element, leaving us with [3, 0]. Last, we take element at index 0, 0, and add it to element of index 1 from our second map function, 0, leaving us with 0; thus, after the first iteration of the top level map function, we are left with an array that looks like so: [1, [2, 0], [3, 3]]. We simply keep doing that logic for the other elements until we finish: [1, -1, [3, 3]], and [1, -1, 3]" + }, + { + "subtitle": "Words Containing 'a'", + "question": + "What will the following code print out?\n
const results = ['apple', 'dog', 'cat']\n  .map((a, i) => \n    a.indexOf('a') !== -1 ? i : null)\nconsole.log(results);
", + "choices": [ + "
[0, -1, 1]
", + "
[0, null, 2]
", + "
[null, null, null]
", + "
[-1, null, 2]
" + ], + "answer": 1, + "explanation": + "This map example will return an array where each elements of the new array is either the original array index when the element contains the character 'a'; otherwise, an element of null for any words that do not have the character 'a'." + }, + { + "subtitle": "Accessing the Original Array Elements", + "question": + "What will the following code print out?\n
const results = [1, 2, 3]\n  .map((a, _, o) => a + o[0])\nconsole.log(results);
", + "choices": [ + "
[1, 2, 3]
", + "
[0, 0, 0]
", + "
[3, 2, 1]
", + "
[2, 3, 4]
" + ], + "answer": 3, + "explanation": + "This map example will add the value of the first element in the original array to all the other elements in the array." + }, + { + "subtitle": "More Map Hacking", + "question": + "What will the following code print out?\n
const results = [8, 5, 3]\n  .map((a, i, o) => o[o.length - i - 1])\nconsole.log(results);
", + "choices": [ + "
[3, 5, 8]
", + "
[5, 3, 8]
", + "
[8, 5, 3]
", + "
[3, 8, 5]
" + ], + "answer": 0, + "explanation": + "This map example will reverse the array. The third argument to the map callback function is the original array; therefore, we can use the current index in the map function, and work our way backwards from the end of the array using the o.length." + }, + { + "subtitle": "Custom Scoping", + "question": + "What will the following code print out?\n
const results = ['a', 'b', 'c']\n  .map(function(a) { return this[a]; }, {a: 9, b: 3, c: 1})\nconsole.log(results);
", + "choices": [ + "
['a', 'b', 'c']
", + "
[9, 3, 1]
", + "
[3, 9, 1]
", + "
[{a: 9}, {b: 3}, {c: 1}]
" + ], + "answer": 1, + "explanation": + "This map example will reverse the array. The third argument to the map callback function is the original array; therefore, we can use the current index in the map function, and work our way backwards from the end of the array using the o.length." + }, + { + "subtitle": "Reversing in Map, Just Because", + "question": + "What will the following code print out?\n
const results = [1, 2, 3, 4, 5]\n  .map((a, _, o) => o.reverse() && a)\nconsole.log(results);
", + "choices": [ + "
[5, 4, 3, 2, 1]
", + "
[5, 2, 3, 5, 1]
", + "
[1, 2, 3, 4, 5]
", + "
[1, 4, 3, 2, 5]
" + ], + "answer": 3, + "explanation": + "This map example will reverse the array. The third argument to the map callback function is the original array; therefore, we can use the current index in the map function, and work our way backwards from the end of the array using the o.length." + } + ], + "tests": [], + "challengeType": 8 + }, + { + "id": "5a916843a9178457a6f1281f", + "title": "General questions", + "description": [ + { + "subtitle": "Data Structure stack", + "question": + "A stack data structure obeys the principles of Last in First Out (LIFO) true or false", + "choices": [ + "
true
", + "
false
" + ], + "answer": 0, + "explanation": "true" + }, + { + "subtitle": "Sorting algorithm", + "question": + "Which of the following is not a common sorting algorithm ?", + "choices": [ + "
Bubble Sort
", + "
QuickSort
", + "
HeapSort
", + "
Branch Sort
" + ], + "answer": 3, + "explanation": "Branch sort is not a sorting algorithm" + }, + { + "subtitle": "Persistant storage", + "question": "CRUD operation stand for ?", + "choices": [ + "
Create, Read, Update, Delete
", + "
Copy, Reduce, Update, Define
", + "
Create, Rich, Unique, Document
", + "
Cancel, Reduce, Unify, Dispose
" + ], + "answer": 0, + "explanation": + "CRUD stands for Create - Read - Update and Delete and are the four basic operations of persistant storage" + }, + { + "subtitle": "Numeric types", + "question": "Select the correct Numeric types to their correct size.", + "choices": [ + "
Byte - 8 bits, long - 64 bits,int - 32 bits, short - 16 bits.
", + "
Byte - 8 bits, long - 32 bits ,int - 64 bits, short - 16 bits.
", + "
Byte - 8 bits, long - 16 bits ,int - 32 bits, short - 64 bits.
", + "
Byte - 32 bits, long - 8 bits ,int - 64 bits, short - 16 bits.
" + ], + "answer": 0, + "explanation": + "byte 8 bits, short 16 bits, int 32 bits, long 64 bits." + }, + { + "subtitle": "Software architecture pattern", + "question": "The MVC software architectural pattern stands for ?", + "choices": [ + "
MeanStack - View - Class
", + "
Modal - Vector - Controll
", + "
Model - View - Controller
", + "
Mapped - Volume - Content
" + ], + "answer": 2, + "explanation": + "The MVC pattern is used to keep separate three main componants of an application, the idea being for example the data or 'Model' does not need to know what the 'View' or presentation of that data is doing and vice versa, with the 'Controller' handling any logic or input from the user to manipulate the 'Model'." + }, + { + "subtitle": "XPath navigation", + "question": + "The XPath syntax is used to traverse data stored in which format", + "choices": [ + "
XML
", + "
JSON
", + "
Xtend
", + "
Text
" + ], + "answer": 0, + "explanation": + "is used to navigate nodes and attributes within an XML document and stands for XML Path Language." + }, + { + "subtitle": "Functions and side effects", + "question": + "If a function is said to have side-effects it is expected to ?", + "choices": [ + "
Only return after an enclosed inner function has returned
", + "
Contain 'Blocking' code which can affect the stability of the program
", + "
Modify some kind of state outside of its own scope such as a global variable or change the value of its own arguments.
", + "
Have high algorithm complexity.
" + ], + "answer": 2, + "explanation": + "Other charateristics of side-effects would be writing data to the log, interacting with users or systems on the same network and calling other functions with side-effects." + }, + { + "subtitle": "Time-Complexity", + "question": "The term 'Time-Complexity' relates to ?", + "choices": [ + "
HTTP requests
", + "
Algorithms
", + "
Inheritance
", + "
Consuming API's
" + ], + "answer": 1, + "explanation": + "Algorithm Time-Complexity is the total amount of time needed for an algorithm to run till full completion and is more often expressed with 'big-O-notation'." + }, + { + "subtitle": "Find the odd", + "question": + "Which of the following programming languages is the odd one out ?", + "choices": [ + "
C#
", + "
Java
", + "
Cobol
", + "
PHP
" + ], + "answer": 3, + "explanation": + "PHP is generally referred to as an interpreted language where as the other three are considered languages generally processed by compilers." + }, + { + "subtitle": "Find the odd, again", + "question": "Which in the following list is the odd one out ?", + "choices": [ + "
Boolean
", + "
Character
", + "
Array
", + "
Null
" + ], + "answer": 2, + "explanation": + "An array in most languages is considered an object where as the other three are primitive data types." + }, + { + "subtitle": "Programming languages paradigms", + "question": + "Object-oriented and Functional are said to be programming language paradigms which of the following isn't a language paradigm.", + "choices": [ + "
Procedural
", + "
Imperative
", + "
Declarative
", + "
Instance
" + ], + "answer": 3, + "explanation": "Instance is not a recognised programming paradigm." + }, + { + "subtitle": "UML", + "question": + "UML or Universal Modeling Language is a language created for?", + "choices": [ + "
Creating database schemas.
", + "
Software visualization using diagrams.
", + "
Simplifying multi language software applications.
", + "
Integration of cross-platform systems on one network.
" + ], + "answer": 1, + "explanation": + "UML is used for software modeling in diagram form including Class diagrams, Object diagrams and Use case diagrams among others." + } + ], + "tests": [], + "challengeType": 8 + }, + { + "id": "5a91690fa9178457a6f12820", + "title": "CSS questions part 1", + "description": [ + { + "subtitle": "Elements properties", + "question": + "Which properties do inline elements not possess under normal document flow.", + "choices": [ + "
overflow, left or right margins
", + "
border-radius, z-index
", + "
font-size, animation
", + "
width, top or bottom margins
" + ], + "answer": 3, + "explanation": + "An inline element will only take up the width of the inner content." + }, + { + "subtitle": "CSS rules", + "question": + "What will the following css rule select?\n
.test > div {\n...\n}
", + "choices": [ + "
Selects all divs within elements with the class of test.
", + "
Selects all divs outside of elements with the class of test.
", + "
Selects only divs that are immediate children of elements with the class of test.
", + "
This would not be considered a valid selector.
" + ], + "answer": 2, + "explanation": + "eg: \n
<div class='test'>\n<div class='box'>\n<div class='content'>...</div>\n</div>\n<div class='box'>\n<div class='content'>...</div>\n</div>\n</div>
\n\nWould target only the elements with a class of 'box' as these are the direct children of 'test'." + }, + { + "subtitle": "Overriding properties", + "question": + "Which keyword would you add to the end of a style rule to override another Css style for a specific element ?", + "choices": [ + "
*override
", + "
*overrideAll
", + "
!vital
", + "
!important
" + ], + "answer": 3, + "explanation": + "For example if you wanted all the paragraph tags in a specific class to have the colour blue instead of black\n
.myClass p  {\ncolor: blue !important\n}
" + }, + { + "subtitle": "Preprocessor CSS", + "question": "Which is not considered a Css preprocessor?", + "choices": [ + "
Less
", + "
Sass
", + "
Stylus
", + "
Express
" + ], + "answer": 3, + "explanation": "Express is an application framework for Node.js" + }, + { + "subtitle": "CSS Box Model", + "question": "Which is not a property of the Css 'Box Model'?", + "choices": [ + "
Border
", + "
Padding
", + "
Margin
", + "
Outline
" + ], + "answer": 3, + "explanation": + "Content is the fourth property of the box model not outline." + }, + { + "subtitle": "CSS positioning", + "question": + "Absolute positioning in Css removes an element from the normal document flow true/false?", + "choices": [ + "
true
", + "
false
" + ], + "answer": 0, + "explanation": + "Giving an element absolute positioning removes it from the normal document flow completely allowing positioning attributes top, left, bottom." + }, + { + "subtitle": "CSS selector", + "question": + "With this Css Selector it is possible to select every element in a document.", + "choices": [ + "
Body
", + "
Universal
", + "
Wildcard
", + "
SelectAll
" + ], + "answer": 1, + "explanation": + "The Universal selector will select every element on a page and is denoted by *{}. note: The rule of specificity still applies, so a more specific selector can override the universal selector in a Css document." + }, + { + "subtitle": "Font size in CSS", + "question": "Which is not a valid Css font size?", + "choices": [ + "
em
", + "
%
", + "
tp
", + "
px
" + ], + "answer": 2, + "explanation": "tp is not valid this should be pt." + }, + { + "subtitle": "CSS clear property", + "question": "The Css 'clear' property fulfills which task?", + "choices": [ + "
Allows transparency of an element.
", + "
Prevents prior properties of the selector from taking effect.
", + "
Positions an element clear of a siblings margins and borders.
", + "
Sets which sides of an element floating elements are not allowed to be floated.
" + ], + "answer": 3, + "explanation": + "The clear property has the following values available: both, left, right, inherit, initial and none." + }, + { + "subtitle": "CSS sudo-class", + "question": + "An example of a sudo-class of a ul element written in Css would be defined?", + "choices": [ + "
ul:first-child
", + "
ul..first-child
", + "
ul::first-child
", + "
ul first-child
" + ], + "answer": 0, + "explanation": + "First answer : Would be correct of a sudo-class.
Second answer : Would be an error of syntax.
Third answer: The double colon would be an example of a sudo element used with the likes of ::before and ::after which are examples of content.
Fourth answer : This would relate to html tag elements of which there is no first-child tag." + } + ], + "tests": [], + "challengeType": 8 + }, + { + "id": "5a91a167a9178457a6f12821", + "title": "CSS questions part 2", + "description": [ + { + "subtitle": "CSS selector", + "question": + "An entire Css selector and declaration block whithin a Css document eg:
.container div p {
position: relative;
width: 300px;
margin: auto;
color: #ffffff;
}

is referred to as?", + "choices": [ + "
Base-Block
", + "
Selection Properties
", + "
Selector Group
", + "
Ruleset
" + ], + "answer": 3, + "explanation": + "The selectors name and properties are collectively called a Ruleset." + }, + { + "subtitle": "CSS Browser compatibility", + "question": + "Which is not a valid Css prefix to ensure browser compatibility?", + "choices": [ + "
-webkit-
", + "
-win-
", + "
-moz-
", + "
-o-
" + ], + "answer": 1, + "explanation": + "-win- is incorrect, -webkit- (Chrome, Safari, ioS and modern versions of Opera), -moz- (Firefox), -o- (Older versions of Opera), the other would be -ms- used for (IE and Microsoft Edge)." + }, + { + "subtitle": "CSS 'text-transform' property", + "question": "The Css property 'text-transform' is mainly used for?", + "choices": [ + "
Alteration of text letter case.
", + "
Changing the alignment of text.
", + "
Increase/Decrease font size.
", + "
Transformation of font family.
" + ], + "answer": 0, + "explanation": + "The values for the property 'text-transform' are, capitalize, full-width, inherit, lowercase, none and uppercase." + }, + { + "subtitle": "CSS font-sizes", + "question": + "If the default font size for a page is 12px, What is the pixel equivalent of 1.5em?", + "choices": [ + "
12.5px
", + "
9px
", + "
18px
", + "
6px
" + ], + "answer": 2, + "explanation": + "1em is equivalent to the base or default font size therefore (12 * 1.5 = 18)." + }, + { + "subtitle": "CCSS font weight", + "question": "In Css 'font-weight: bold;' is the same as?", + "choices": [ + "
font-weight: 400;
", + "
font-weight: 900
", + "
font-weight: 700
", + "
font-weight: 500
" + ], + "answer": 2, + "explanation": + "The keyword 'bold' is the same as the numerical value 700." + }, + { + "subtitle": "CSS ruleset", + "question": + "Given this ruleset
.testDiv {
width: 20%;
height: 20%;
content: 'add this text'
}

What would happen with the content properties text?", + "choices": [ + "
Nothing
", + "
Appended to any text contained in element with class of testDiv.
", + "
Prepended to any text contained in element with class of testDiv.
", + "
Overwrite any text contained in element with class of testDiv.
" + ], + "answer": 0, + "explanation": + "Nothing would appear on the page, the content property needs to be used with sudo elements like ::after or ::before eg:
.testDiv {
width: 20%;
height: 20%;\n}\n.testDiv::after {\ncontent: 'add this text'\n}
" + }, + { + "subtitle": "CSS match selector", + "question": + "What would the following Css selector match?
section + p", + "choices": [ + "
All <section> and <p> tags.
", + "
All <p> tags within a <section> tag.
", + "
All <p> tags placed immediately after a <section> tag.
", + "
Not a valid selector.
" + ], + "answer": 2, + "explanation": + "
<p>First Paragraph</p>
<section>...</section>
<p>Second Paragraph</p>
<p>Third Paragraph</p>

Only the second paragraph tag will be selected and matched." + }, + { + "subtitle": "How to incorporte CSS into web document", + "question": + "How many different ways is it possible to incorporate Css into a web document?", + "choices": [ + "
1
", + "
2
", + "
3
", + "
4
" + ], + "answer": 2, + "explanation": + "Currently Css can be used 'Inline' as a style attribute of an Html element, 'Embedded' in a style tag of a document and 'Imported' as an external file with the link tag element." + }, + { + "subtitle": "Using target in css", + "question": + "What would [role=contentinfo] {...} target in Css?", + "choices": [ + "
Any element with the role attribute of contentinfo.
", + "
Any element within a <span> tag.
", + "
Any element within a <span> tag with the role attribute of contentinfo.
", + "
This would only be valid using Sass or Scss.
" + ], + "answer": 0, + "explanation": + "The square bracket notation is used to target elements with specific attributes." + }, + { + "subtitle": "CSS positioning", + "question": "Which is not a value for 'position' in css?", + "choices": [ + "
Absolute
", + "
Static
", + "
Responsive
", + "
inherit
" + ], + "answer": 2, + "explanation": + "There is no such positioning as responsive, currently there is (absolute, fixed, inherit, relative and static)." + } + ], + "tests": [], + "challengeType": 8 + }, + { + "id": "5a91b5bfa9178457a6f12822", + "title": "Javascript questions part 1", + "description": [ + { + "subtitle": "JavaScript Array method", + "question": "which of the following is not an Array method?", + "choices": [ + "
pop()
", + "
unshift()
", + "
split()
", + "
every()
" + ], + "answer": 2, + "explanation": + "split() is a string method
pop() removes from the end of an array
unshift() adds to the front of an array
and every() returns a true or false value for each element in an array." + }, + { + "subtitle": "JavaScript ES6 feature", + "question": + "ES6 Arrow functions written on one line require no return statement.", + "choices": [ + "
True
", + "
False
" + ], + "answer": 0, + "explanation": "True" + }, + { + "subtitle": "JavaScript strict syntax", + "question": + "Where is the correct place to insert the \"use strict\" expression.", + "choices": [ + "
Before declaring a variable
", + "
At the start of a script or function
", + "
It is used inline within an HTML element
", + "
Within a Css selector
" + ], + "answer": 1, + "explanation": + "The \"use strict\"; expression should be placed at the start of a script for global scope or\nwithin a function for local scope." + }, + { + "subtitle": "JavaScript equality", + "question": + "The following code will output?
const x = '7'
const y = 7
console.log(x == y)
", + "choices": [ + "
true
", + "
false
", + "
NaN
", + "
undefined
" + ], + "answer": 0, + "explanation": + "true, if triple equals '===' was used it would then evaluate to false." + }, + { + "subtitle": "JavaScript modules", + "question": + "In which of the following can you expect to see the require() function?", + "choices": [ + "
Vanilla Javascript
", + "
React.js
", + "
Node.js
", + "
Jquery
" + ], + "answer": 2, + "explanation": + "require() is built into Node.js in order to load modules for use with an application." + }, + { + "subtitle": "JavaScript recursive methods", + "question": + "What is the main function or job of a 'base case' in a typical recursive method ?", + "choices": [ + "
To reduce the algorithm complexity of the function.
", + "
To terminate the recursion.
", + "
To keep track of each invocation of the function on the stack.
", + "
To return null.
" + ], + "answer": 1, + "explanation": + "To allow the recursive function to terminate and inititate the popping off of the stack of each function call pushed upon it." + }, + { + "subtitle": "JavaScript framework", + "question": + "In which Javascript framework will you find the ng style of attributes?", + "choices": [ + "
Jquery
", + "
React
", + "
Angular
", + "
Ember
" + ], + "answer": 2, + "explanation": + "The ng- style prefix is used to denote an angularJS directive." + }, + { + "subtitle": "JavaScript syntax", + "question": + "The following code will return 24 true or false?
function multiply(num1, num2) {
return
num1 * num2;
}
multiply(4,6)
", + "choices": [ + "
True
", + "
False
" + ], + "answer": 1, + "explanation": + "The function will return undefined before it reaches the multiplication of the two arguments." + }, + { + "subtitle": "JavaScript callback", + "question": "A callback function is also known as?", + "choices": [ + "
Loopback function
", + "
Higher-order function
", + "
Recursive function
", + "
Pure Function
" + ], + "answer": 1, + "explanation": + "Also Known as a Higher-order function a callback function can be passed to another function as a parameter and is called inside that function." + }, + { + "subtitle": "JavaScript syntax, again", + "question": "Javascript is case sensitive true or false?", + "choices": [ + "
true
", + "
false
" + ], + "answer": 0, + "explanation": "true" + } + ], + "tests": [], + "challengeType": 8 + }, + { + "id": "5a92c913a9178457a6f12823", + "title": "Javascript questions part 2", + "description": [ + { + "subtitle": "JavaScript pop up", + "question": "Which is not a pop up box in JavaScript", + "choices": [ + "
Confirm Box
", + "
Alert Box
", + "
Message Box
", + "
Prompt Box
" + ], + "answer": 2, + "explanation": "Message Box." + }, + { + "subtitle": "JavaScript Loops", + "question": + "Which of the following is not a looping format in javascript", + "choices": [ + "
For
", + "
While
", + "
Next
", + "
Do-While
" + ], + "answer": 2, + "explanation": "Next is not a loop available in javascript." + }, + { + "subtitle": "JavaScript types", + "question": + "What is the result of the following code?\nconsole.log( 4 + 4 + \"2\" );", + "choices": [ + "
\"82\"
", + "
10
", + "
82
", + "
\"10\"
" + ], + "answer": 0, + "explanation": + "The first two integers will be added as normal then the string will be concatenated to the result of 8 giving \"82\"." + }, + { + "subtitle": "JavaScript types", + "question": + "What is the result of the following code?\nconsole.log( \"3\" + 6 + 6 );", + "choices": [ + "
15
", + "
\"15\"
", + "
\"366\"
", + "
366
" + ], + "answer": 2, + "explanation": + "As the equation begins with a string, each integer will be converted and appended in string form giving \"366\"" + }, + { + "subtitle": "JavaScript Event loop", + "question": + "Which best describes the function of the Javascript event loop?", + "choices": [ + "
To Handle synchronous code one line at a time in the main script.
", + "
To remove any blocking functions accidently pushed on to the call stack.
", + "
To constantly monitor if the call stack is empty and then invoke any asynchronous functions from the event queue.
", + "
A mechanism to best decide how to terminate any looping structure.
" + ], + "answer": 2, + "explanation": + "Briefly the event loop constantly runs to monitor state between the callstack, the event table and the event queue. When asynchronous code is executed it\nis placed on to the event table only to be executed as and when a specific event occurs, when it does it is then placed on the event queue until the call\nstack is empty then when invoked, moved from the queue to the callstack." + }, + { + "subtitle": "JavaSript type", + "question": "console.log(typeof(NaN)) Will log?", + "choices": [ + "
false
", + "
null
", + "
number
", + "
undefined
" + ], + "answer": 2, + "explanation": + "Despite standing for Not a Number NaN is still regarded as a numeric type." + }, + { + "subtitle": "JavaScript ES6 operators", + "question": + "What will the following log?
let x = 'teststring';
console.log([...x]);
", + "choices": [ + "
[\"t\",\"e\",\"s\",\"t\",\"s\",\"t\",\"r\",\"i\",\"n\",\"g\"]
", + "
uncaught syntax error
", + "
[\"teststring\"]
", + "
t e s t s t r i n g
" + ], + "answer": 0, + "explanation": + "The spread syntax introduced in es6 can be used to iterate through each character of a string, and here stored in an array similar to calling x.split(\"\")" + }, + { + "subtitle": "ES6 let / const declarations", + "question": + "What will the following code log?
function myFunction() {
const a = 'variableA'
if( 3 > 1) {
let b = 'variableB'
}
console.log(a)
console.log(b)
}
myFunction();
", + "choices": [ + "
variableA, variableB
", + "
variableA
", + "
variableB, variableA
", + "
variableA, Uncaught ReferenceError: b is not defined
" + ], + "answer": 3, + "explanation": + "Due to the keywords let and const being block scoped rather than just locally function scoped like var, the variable b will be garbage collected after the\nconditional if statement has finished and will no longer exist for the console.log() method." + }, + { + "subtitle": "JavaSript function arguments", + "question": + "The following code will return?
function getsum(num1 = 1, num2 = 1) {
return num1 + num2;
}
getsum(3);
", + "choices": [ + "
4
", + "
6
", + "
2
", + "
5
" + ], + "answer": 0, + "explanation": + "Due to only one argument being passed this will override the first default parameter giving num1 the value of 3 + num2 default value of 1.\nIf the function were to be executed without any arguments at all both defaults would be used and return 2." + }, + { + "subtitle": "JavaSript inheritance", + "question": + "All Javascript objects inherit properties and methods from a class true or false?", + "choices": [ + "
true
", + "
false
" + ], + "answer": 1, + "explanation": + "Due to only one argument being passed this will override the first default parameter giving num1 the value of 3 + num2 default value of 1.\nIf the function were to be executed without any arguments at all both defaults would be used and return 2." + } + ], + "tests": [], + "challengeType": 8 + }, + { + "id": "5a933ce3a9178457a6f12824", + "title": "Networking questions part 1", + "description": [ + { + "subtitle": "Address identification", + "question": "00:26:2D:55:42:1f is an example of what?", + "choices": [ + "
MAC Address
", + "
IPv4 Address
", + "
IPv6 Address
", + "
A wireless protocol
" + ], + "answer": 0, + "explanation": "A valid MAC Address." + }, + { + "subtitle": "OSI networking model", + "question": + "Which one of the following is not part of the seven layer OSI networking model.", + "choices": [ + "
Application
", + "
Presentation
", + "
Session
", + "
Protocol
", + "
Network
", + "
Data Link
", + "
Physical
" + ], + "answer": 3, + "explanation": + "Protocol is not part of the OSI networking model layer 4 should be the transport layer." + }, + { + "subtitle": "RAID", + "question": "In networking a RAID implementation relates to?", + "choices": [ + "
Wireless standards
", + "
Password policies
", + "
Remote access
", + "
Fault tolerance
" + ], + "answer": 3, + "explanation": + "RAID stands for Redundant array of inexpensive disks and is a model that allows servers to\nendure the failure of one or more hard disks without interuption to services and resources." + }, + { + "subtitle": "Server status", + "question": + "Your console or terminal throws up a 404 error, this means?", + "choices": [ + "
Upgrade required
", + "
Not found
", + "
Gateway Timeout
", + "
No Response
" + ], + "answer": 1, + "explanation": + "This error informs you that an internal or external resource has not been found and can not be loaded into a page or application." + }, + { + "subtitle": "Server Status, again", + "question": + "Your console or terminal throws up a 500 error, this means?", + "choices": [ + "
Internal Server Error
", + "
Proxy Authentication Required
", + "
Upgrade Required
", + "
Too Many Requests
" + ], + "answer": 0, + "explanation": + "A generic error message which refers to an error on the webserver when no precise detail is available." + }, + { + "subtitle": "HTTP methods", + "question": + "GET and POST are important HTTP request methods which of the following list are Not an example of an HTTP request method?", + "choices": [ + "
HEAD
", + "
PUT
", + "
BODY
", + "
DELETE
" + ], + "answer": 2, + "explanation": + "HEAD is similar to the Get method but returns no response body, PUT is used to replace and update a specified resource, DELETE will delete a resource,\nthere is no such method as a BODY request." + }, + { + "subtitle": "Loopback", + "question": + "In networking which of the following is considered to be a loopback ip address or 'localhost'?", + "choices": [ + "
172.0.0.1
", + "
127.0.0.1
", + "
10.0.0.0
", + "
192.168.0.0
" + ], + "answer": 1, + "explanation": + "127.0.0.1 is the loopback address or localhost, option a is an example of a public address and options c and d are examples of private network addresses." + }, + { + "subtitle": "Network & Security Architecture", + "question": "Ring, Star, Mesh and Bus are all examples of?", + "choices": [ + "
Network topologies
", + "
Security Protocols for mobile development
", + "
Restful API's
", + "
File server storage methods
" + ], + "answer": 0, + "explanation": + "A network topology is a logical and physical layout of how the network appears to the devices using it." + } + ], + "tests": [], + "challengeType": 8 + }, + { + "id": "5a933d04a9178457a6f12825", + "title": "Networking questions part 2", + "description": [ + { + "subtitle": "Default port for FTP", + "question": + "In attempting to connect to an FTP (File Transfer Protocol) server and failing, which port can you check is open to troubleshoot the connection issue?", + "choices": [ + "
25
", + "
443
", + "
23
", + "
21
" + ], + "answer": 3, + "explanation": + "Port 21 is traditionally used as the default port on a system for FTP." + }, + { + "subtitle": "Network types", + "question": "Which of the following is not a type of network?", + "choices": [ + "
LAN
", + "
MAN
", + "
PAN
", + "
NAN
" + ], + "answer": 3, + "explanation": + "NAN is not a current network type. LAN (Local Area Network), MAN (Metropolitan Area Network), PAN (Personal Area Network)." + }, + { + "subtitle": "Subnet mask usage", + "question": "What is a subnet mask used for?", + "choices": [ + "
To hide the id of a wireless access point.
", + "
To identyfy the extended and host address.
", + "
To encrypt the broadcasting of ip addresses.
", + "
To connect to a vpn.
" + ], + "answer": 1, + "explanation": + "A subnet mask is used along side an IP address in order to isolate the extended or 'subnet' of the network address and the host machine address." + }, + { + "subtitle": "Network acronym", + "question": "What does NIC stand for?", + "choices": [ + "
Network Isolated Connection
", + "
Network Interconnect Cables
", + "
Network Interface Card
", + "
Network Interference Cause
" + ], + "answer": 2, + "explanation": + "A Network Interface Card or (Network Interface Controller) is a hardware component that connects to a Pc or printer in order to\nconnect and be identified on a network." + }, + { + "subtitle": "Default gateway", + "question": + "A 'default gateway' provides a way for a local network to connect to a larger external network true or false?", + "choices": [ + "
true
", + "
false
" + ], + "answer": 0, + "explanation": + "True this is usually the address of of an external router or switch." + }, + { + "subtitle": "The ipconfig commad", + "question": "'ipconfig' is used for?", + "choices": [ + "
Reassigning ip addresses.
", + "
Tool for masking ip adresses.
", + "
Monitoring network traffic.
", + "
Identify address information of a machine on a network.
" + ], + "answer": 3, + "explanation": + "ipconfig or ifconfig(linux) is a utility for gaining various address information of a computer on a network." + }, + { + "subtitle": "Network terminology", + "question": "The term 'Latency' refers to?", + "choices": [ + "
The logical state of a network.
", + "
A loss of data expected in transfer over a network.
", + "
A measure of time delay between request and response experienced by a system.
", + "
The scope for expanding a network.
" + ], + "answer": 2, + "explanation": + "Latency can affect host to host transfers http requests etc." + }, + { + "subtitle": "Network terminology, again", + "question": "The term 'full duplex' refers to?", + "choices": [ + "
Two way data transfer but not at the same time.
", + "
Two way data transfer simultaneously.
", + "
One way data transfer at high speed.
", + "
One way data transfer with encryption
" + ], + "answer": 1, + "explanation": + "An example of full duplex would be like a telephone conversation between two people." + } + ], + "tests": [], + "challengeType": 8 + } + ] +} diff --git a/packages/learn/seed/requiresTests/rosetta-code-problems.json b/packages/learn/seed/requiresTests/rosetta-code-problems.json new file mode 100644 index 0000000000..edaae60f51 --- /dev/null +++ b/packages/learn/seed/requiresTests/rosetta-code-problems.json @@ -0,0 +1,37084 @@ +[ + { + "title": "24 game/Solve", + "type": "Waypoint", + "description": [ + "task:", + "

Write a program that takes four digits, either from user input or by random generation, and computes arithmetic expressions following the rules of the 24 game.

Show examples of solutions generated by the program.

", + "Related task:", + " Arithmetic Evaluator" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "This is a translation of the C code.", + "var ar=[],order=[0,1,2],op=[],val=[];", + "var NOVAL=9999,oper=\"+-*/\",out;", + "", + "function rnd(n){return Math.floor(Math.random()*n)}", + "", + "function say(s){", + " try{document.write(s+\"
\")}", + " catch(e){WScript.Echo(s)}", + "}", + "", + "function getvalue(x,dir){", + " var r=NOVAL;", + " if(dir>0)++x;", + " while(1){", + " if(val[x]!=NOVAL){", + " r=val[x];", + " val[x]=NOVAL;", + " break;", + " }", + " x+=dir;", + " }", + " return r*1;", + "}", + "", + "function calc(){", + " var c=0,l,r,x;", + " val=ar.join('/').split('/');", + " while(c<3){", + " x=order[c];", + " l=getvalue(x,-1);", + " r=getvalue(x,1);", + " switch(op[x]){", + " case 0:val[x]=l+r;break;", + " case 1:val[x]=l-r;break;", + " case 2:val[x]=l*r;break;", + " case 3:", + " if(!r||l%r)return 0;", + " val[x]=l/r;", + " }", + " ++c;", + " }", + " return getvalue(-1,1);", + "}", + "", + "function shuffle(s,n){", + " var x=n,p=eval(s),r,t;", + " while(x--){", + " r=rnd(n);", + " t=p[x];", + " p[x]=p[r];", + " p[r]=t;", + " }", + "}", + "", + "function parenth(n){", + " while(n>0)--n,out+='(';", + " while(n<0)++n,out+=')';", + "}", + "", + "function getpriority(x){", + " for(var z=3;z--;)if(order[z]==x)return 3-z;", + " return 0;", + "}", + "", + "function showsolution(){", + " var x=0,p=0,lp=0,v=0;", + " while(x<4){", + " if(x<3){", + " lp=p;", + " p=getpriority(x);", + " v=p-lp;", + " if(v>0)parenth(v);", + " }", + " out+=ar[x];", + " if(x<3){", + " if(v<0)parenth(v);", + " out+=oper.charAt(op[x]);", + " }", + " ++x;", + " }", + " parenth(-p);", + " say(out);", + "}", + "", + "function solve24(s){", + " var z=4,r;", + " while(z--)ar[z]=s.charCodeAt(z)-48;", + " out=\"\";", + " for(z=100000;z--;){", + " r=rnd(256);", + " op[0]=r&3;", + " op[1]=(r>>2)&3;", + " op[2]=(r>>4)&3;", + " shuffle(\"ar\",4);", + " shuffle(\"order\",3);", + " if(calc()!=24)continue;", + " showsolution();", + " break;", + " }", + "}", + "", + "solve24(\"1234\");", + "solve24(\"6789\");", + "solve24(\"1127\");
", + "", + "Examples:", + "", + "
(((3*1)*4)*2)",
+      "((6*8)/((9-7)))",
+      "(((1+7))*(2+1))
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d62", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var ar=[],order=[0,1,2],op=[],val=[];\nvar NOVAL=9999,oper=\"+-*/\",out;\n\nfunction rnd(n){return Math.floor(Math.random()*n)}\n\nfunction say(s){\n try{document.write(s+\"
\")}\n catch(e){WScript.Echo(s)}\n}\n\nfunction getvalue(x,dir){\n var r=NOVAL;\n if(dir>0)++x;\n while(1){\n if(val[x]!=NOVAL){\n r=val[x];\n val[x]=NOVAL;\n break;\n }\n x+=dir;\n }\n return r*1;\n}\n\nfunction calc(){\n var c=0,l,r,x;\n val=ar.join('/').split('/');\n while(c<3){\n x=order[c];\n l=getvalue(x,-1);\n r=getvalue(x,1);\n switch(op[x]){\n case 0:val[x]=l+r;break;\n case 1:val[x]=l-r;break;\n case 2:val[x]=l*r;break;\n case 3:\n if(!r||l%r)return 0;\n val[x]=l/r;\n }\n ++c;\n }\n return getvalue(-1,1);\n}\n\nfunction shuffle(s,n){\n var x=n,p=eval(s),r,t;\n while(x--){\n r=rnd(n);\n t=p[x];\n p[x]=p[r];\n p[r]=t;\n }\n}\n\nfunction parenth(n){\n while(n>0)--n,out+='(';\n while(n<0)++n,out+=')';\n}\n\nfunction getpriority(x){\n for(var z=3;z--;)if(order[z]==x)return 3-z;\n return 0;\n}\n\nfunction showsolution(){\n var x=0,p=0,lp=0,v=0;\n while(x<4){\n if(x<3){\n lp=p;\n p=getpriority(x);\n v=p-lp;\n if(v>0)parenth(v);\n }\n out+=ar[x];\n if(x<3){\n if(v<0)parenth(v);\n out+=oper.charAt(op[x]);\n }\n ++x;\n }\n parenth(-p);\n say(out);\n}\n\nfunction solve24(s){\n var z=4,r;\n while(z--)ar[z]=s.charCodeAt(z)-48;\n out=\"\";\n for(z=100000;z--;){\n r=rnd(256);\n op[0]=r&3;\n op[1]=(r>>2)&3;\n op[2]=(r>>4)&3;\n shuffle(\"ar\",4);\n shuffle(\"order\",3);\n if(calc()!=24)continue;\n showsolution();\n break;\n }\n}\n\nsolve24(\"1234\");\nsolve24(\"6789\");\nsolve24(\"1127\");\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "4-rings or 4-squares puzzle", + "type": "Waypoint", + "description": [ + "

Task:", + "

Replace a, b, c, d, e, f, and

", + "

g with the decimal

", + "

digits LOW ───► HIGH

", + "such that the sum of the letters inside of each of the four large squares add up to", + "

the same sum.

",
+      "            ╔══════════════╗      ╔══════════════╗",
+      "            ║              ║      ║              ║",
+      "            ║      a       ║      ║      e       ║",
+      "            ║              ║      ║              ║",
+      "            ║          ┌───╫──────╫───┐      ┌───╫─────────┐",
+      "            ║          │   ║      ║   │      │   ║         │",
+      "            ║          │ b ║      ║ d │      │ f ║         │",
+      "            ║          │   ║      ║   │      │   ║         │",
+      "            ║          │   ║      ║   │      │   ║         │",
+      "            ╚══════════╪═══╝      ╚═══╪══════╪═══╝         │",
+      "                       │       c      │      │      g      │",
+      "                       │              │      │             │",
+      "                       │              │      │             │",
+      "                       └──────────────┘      └─────────────┘",
+      "

Show all output here.

", + "

* Show all solutions for each letter being unique with

", + "

LOW=1 HIGH=7

", + "

* Show all solutions for each letter being unique with

", + "

LOW=3 HIGH=9

", + "

* Show only the number of solutions when each letter can be non-unique

", + "

LOW=0 HIGH=9

", + "Related task:", + "Solve the no connection puzzle" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "{{Trans|Haskell}} (Structured search version)", + "(() => {", + "", + " // RINGS -------------------------------------------------------------------", + "", + " // rings :: noRepeatedDigits -> DigitList -> Lists of solutions", + " // rings :: Bool -> [Int] -> [[Int]]", + " const rings = (u, digits) => {", + " const", + " ds = sortBy(flip(compare), digits),", + " h = head(ds);", + "", + " // QUEEN (i.e. middle digit of 7)---------------------------------------", + " return concatMap(", + " q => {", + " const", + " ts = filter(x => (x + q) <= h, ds),", + " bs = u ? delete_(q, ts) : ds;", + "", + " // LEFT BISHOP (next to queen) AND ITS ROOK (leftmost digit)----", + " return concatMap(", + " lb => {", + " const lRook = lb + q;", + " return lRook > h ? [] : (() => {", + " const rbs = u ? difference(ts, [q, lb, lRook]) : ds;", + "", + " // RIGHT BISHOP AND ITS ROOK -----------------------", + " return concatMap(rb => {", + " const rRook = q + rb;", + " return ((rRook > h) || (u && (rRook === lb))) ? (", + " []", + " ) : (() => {", + " const", + " rookDelta = lRook - rRook,", + " ks = u ? difference(", + " ds, [q, lb, rb, rRook, lRook]", + " ) : ds;", + "", + " // KNIGHTS LEFT AND RIGHT ------------------", + " return concatMap(k => {", + " const k2 = k + rookDelta;", + " return (elem(k2, ks) &&", + " (!u || notElem(k2, [", + " lRook, k, lb, q, rb, rRook", + " ]))) ? (", + " [", + " [lRook, k, lb, q, rb, k2, rRook]", + " ]", + " ) : [];", + " }, ks);", + " })();", + " }, rbs);", + " })();", + " },", + " bs", + " );", + " },", + " ds", + " );", + " };", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // compare :: a -> a -> Ordering", + " const compare = (a, b) => a < b ? -1 : (a > b ? 1 : 0);", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // delete_ :: Eq a => a -> [a] -> [a]", + " const delete_ = (x, xs) =>", + " xs.length > 0 ? (", + " (x === xs[0]) ? (", + " xs.slice(1)", + " ) : [xs[0]].concat(delete_(x, xs.slice(1)))", + " ) : [];", + "", + " // (\\\\) :: (Eq a) => [a] -> [a] -> [a]", + " const difference = (xs, ys) =>", + " ys.reduce((a, x) => delete_(x, a), xs);", + "", + " // elem :: Eq a => a -> [a] -> Bool", + " const elem = (x, xs) => xs.indexOf(x) !== -1;", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " const enumFromTo = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // filter :: (a -> Bool) -> [a] -> [a]", + " const filter = (f, xs) => xs.filter(f);", + "", + " // flip :: (a -> b -> c) -> b -> a -> c", + " const flip = f => (a, b) => f.apply(null, [b, a]);", + "", + " // head :: [a] -> a", + " const head = xs => xs.length ? xs[0] : undefined;", + "", + " // length :: [a] -> Int", + " const length = xs => xs.length;", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // notElem :: Eq a => a -> [a] -> Bool", + " const notElem = (x, xs) => xs.indexOf(x) === -1;", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x); //, null, 2);", + "", + " // sortBy :: (a -> a -> Ordering) -> [a] -> [a]", + " const sortBy = (f, xs) => xs.sort(f);", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + "", + " // TEST --------------------------------------------------------------------", + " return unlines([", + " 'rings(true, enumFromTo(1,7))\\n',", + " unlines(map(show, rings(true, enumFromTo(1, 7)))),", + " '\\nrings(true, enumFromTo(3, 9))\\n',", + " unlines(map(show, rings(true, enumFromTo(3, 9)))),", + " '\\nlength(rings(false, enumFromTo(0, 9)))\\n',", + " length(rings(false, enumFromTo(0, 9)))", + " .toString(),", + " ''", + " ]);", + "})();", + "{{Out}}", + "
rings(true, enumFromTo(1,7))",
+      "",
+      "[7,3,2,5,1,4,6]",
+      "[6,4,1,5,2,3,7]",
+      "[5,6,2,3,1,7,4]",
+      "[4,7,1,3,2,6,5]",
+      "[7,2,6,1,3,5,4]",
+      "[6,4,5,1,2,7,3]",
+      "[4,5,3,1,6,2,7]",
+      "[3,7,2,1,5,4,6]",
+      "",
+      "rings(true, enumFromTo(3, 9))",
+      "",
+      "[9,6,4,5,3,7,8]",
+      "[8,7,3,5,4,6,9]",
+      "[9,6,5,4,3,8,7]",
+      "[7,8,3,4,5,6,9]",
+      "",
+      "length(rings(false, enumFromTo(0, 9)))",
+      "",
+      "2860
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d63", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n\n // RINGS -------------------------------------------------------------------\n\n // rings :: noRepeatedDigits -> DigitList -> Lists of solutions\n // rings :: Bool -> [Int] -> [[Int]]\n const rings = (u, digits) => {\n const\n ds = sortBy(flip(compare), digits),\n h = head(ds);\n\n // QUEEN (i.e. middle digit of 7)---------------------------------------\n return concatMap(\n q => {\n const\n ts = filter(x => (x + q) <= h, ds),\n bs = u ? delete_(q, ts) : ds;\n\n // LEFT BISHOP (next to queen) AND ITS ROOK (leftmost digit)----\n return concatMap(\n lb => {\n const lRook = lb + q;\n return lRook > h ? [] : (() => {\n const rbs = u ? difference(ts, [q, lb, lRook]) : ds;\n\n // RIGHT BISHOP AND ITS ROOK -----------------------\n return concatMap(rb => {\n const rRook = q + rb;\n return ((rRook > h) || (u && (rRook === lb))) ? (\n []\n ) : (() => {\n const\n rookDelta = lRook - rRook,\n ks = u ? difference(\n ds, [q, lb, rb, rRook, lRook]\n ) : ds;\n\n // KNIGHTS LEFT AND RIGHT ------------------\n return concatMap(k => {\n const k2 = k + rookDelta;\n return (elem(k2, ks) &&\n (!u || notElem(k2, [\n lRook, k, lb, q, rb, rRook\n ]))) ? (\n [\n [lRook, k, lb, q, rb, k2, rRook]\n ]\n ) : [];\n }, ks);\n })();\n }, rbs);\n })();\n },\n bs\n );\n },\n ds\n );\n };\n\n // GENERIC FUNCTIONS ------------------------------------------------------\n\n // compare :: a -> a -> Ordering\n const compare = (a, b) => a < b ? -1 : (a > b ? 1 : 0);\n\n // concatMap :: (a -> [b]) -> [a] -> [b]\n const concatMap = (f, xs) => [].concat.apply([], xs.map(f));\n\n // delete_ :: Eq a => a -> [a] -> [a]\n const delete_ = (x, xs) =>\n xs.length > 0 ? (\n (x === xs[0]) ? (\n xs.slice(1)\n ) : [xs[0]].concat(delete_(x, xs.slice(1)))\n ) : [];\n\n // (\\\\) :: (Eq a) => [a] -> [a] -> [a]\n const difference = (xs, ys) =>\n ys.reduce((a, x) => delete_(x, a), xs);\n\n // elem :: Eq a => a -> [a] -> Bool\n const elem = (x, xs) => xs.indexOf(x) !== -1;\n\n // enumFromTo :: Int -> Int -> [Int]\n const enumFromTo = (m, n) =>\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i);\n\n // filter :: (a -> Bool) -> [a] -> [a]\n const filter = (f, xs) => xs.filter(f);\n\n // flip :: (a -> b -> c) -> b -> a -> c\n const flip = f => (a, b) => f.apply(null, [b, a]);\n\n // head :: [a] -> a\n const head = xs => xs.length ? xs[0] : undefined;\n\n // length :: [a] -> Int\n const length = xs => xs.length;\n\n // map :: (a -> b) -> [a] -> [b]\n const map = (f, xs) => xs.map(f);\n\n // notElem :: Eq a => a -> [a] -> Bool\n const notElem = (x, xs) => xs.indexOf(x) === -1;\n\n // show :: a -> String\n const show = x => JSON.stringify(x); //, null, 2);\n\n // sortBy :: (a -> a -> Ordering) -> [a] -> [a]\n const sortBy = (f, xs) => xs.sort(f);\n\n // unlines :: [String] -> String\n const unlines = xs => xs.join('\\n');\n\n\n // TEST --------------------------------------------------------------------\n return unlines([\n 'rings(true, enumFromTo(1,7))\\n',\n unlines(map(show, rings(true, enumFromTo(1, 7)))),\n '\\nrings(true, enumFromTo(3, 9))\\n',\n unlines(map(show, rings(true, enumFromTo(3, 9)))),\n '\\nlength(rings(false, enumFromTo(0, 9)))\\n',\n length(rings(false, enumFromTo(0, 9)))\n .toString(),\n ''\n ]);\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "A+B", + "type": "Waypoint", + "description": [ + "

A+B ─── a classic problem in programming contests, it's given so contestants can gain familiarity with the online judging system being used.

", + "Task:", + "

Given two integer, A and B.

Their sum needs to be calculated.

", + "Input data:", + "

Two integers are written in the input stream, separated by space(s):

", + "

$(-1000 \\le A,B \\le +1000)$

", + "Output data:", + "

The required output is one integer: the sum of A and B.

", + "Example:", + "

:{|class=\"standard\"

", + "

! input

", + "

! output

", + "

|-

", + "

| 2 2

", + "

| 4

", + "

|-

", + "

| 3 2

", + "

| 5

", + "

|}

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "=== ES5 ===", + "Client side:", + "", + "", + "", + "
", + "
", + "", + "", + "
", + "", + "Server side (with [http://nodejs.org node.js]):", + "", + "process.openStdin().on (", + " 'data',", + " function (line) {", + " var xs = String(line).match(/^\\s*(\\d+)\\s+(\\d+)\\s*/)", + " console.log (", + " xs ? Number(xs[1]) + Number(xs[2]) : 'usage: '", + " )", + " process.exit()", + " }", + ")", + "", + " $ node io.js", + " 2 3", + " 5", + " $ node io.js", + " x 3", + " usage: ", + "", + "=== ES6 ===", + "Node.js in a terminal: ", + "process.stdin.on(\"data\", buffer => {", + " console.log(", + " (buffer + \"\").trim().split(\" \").map(Number).reduce((a, v) => a + v, 0)", + " );", + "});", + "", + "", + "
 $ node io.js",
+      " 2 3",
+      " 5",
+      "
", + "", + "=== JScript Windows Script Host Version 5.8 ===", + "var a = WScript.StdIn.ReadLine();", + "var b = WScript.StdIn.ReadLine();", + "WSH.echo(a, \" + \" , b , \" = \" , Number(a)+Number(b));", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d67", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "process.openStdin().on (\n 'data',\n function (line) {\n var xs = String(line).match(/^\\s*(\\d+)\\s+(\\d+)\\s*/)\n console.log (\n xs ? Number(xs[1]) + Number(xs[2]) : 'usage: '\n )\n process.exit()\n }\n)\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Active object", + "type": "Waypoint", + "description": [ + "

In object-oriented programming an object is active when its state depends on clock. Usually an active object encapsulates a task that updates the object's state. To the outer world the object looks like a normal object with methods that can be called from outside. Implementation of such methods must have a certain synchronization mechanism with the encapsulated task in order to prevent object's state corruption.

A typical instance of an active object is an animation widget. The widget state changes with the time, while as an object it has all properties of a normal widget.

The task

Implement an active integrator object. The object has an input and output. The input can be set using the method Input. The input is a function of time. The output can be queried using the method Output. The object integrates its input over the time and the result becomes the object's output. So if the input is K(t) and the output is S, the object state S is changed to S + (K(t1) + K(t0)) * (t1 - t0) / 2, i.e. it integrates K using the trapeze method. Initially K is constant 0 and S is 0.

In order to test the object:

", + "set its input to sin (2π f t), where the frequency f=0.5Hz. The phase is irrelevant.", + "wait 2s", + "set the input to constant 0", + "wait 0.5s", + "

Verify that now the object's output is approximately 0 (the sine has the period of 2s). The accuracy of the result will depend on the OS scheduler time slicing and the accuracy of the clock.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "{{trans|E}}", + "", + "function Integrator(sampleIntervalMS) {", + " var inputF = function () { return 0.0 };", + " var sum = 0.0;", + " ", + " var t1 = new Date().getTime();", + " var input1 = inputF(t1 / 1000);", + " ", + " function update() {", + " var t2 = new Date().getTime();", + " var input2 = inputF(t2 / 1000);", + " var dt = (t2 - t1) / 1000;", + " ", + " sum += (input1 + input2) * dt / 2;", + " ", + " t1 = t2;", + " input1 = input2;", + " }", + " ", + " var updater = setInterval(update, sampleIntervalMS);", + " ", + " return ({", + " input: function (newF) { inputF = newF },", + " output: function () { return sum },", + " shutdown: function () { clearInterval(updater) },", + " });", + "}", + "", + "Test program as a HTML fragment:", + "", + "

Test running... -

", + "", + "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d6e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function Integrator(sampleIntervalMS) {\n var inputF = function () { return 0.0 };\n var sum = 0.0;\n \n var t1 = new Date().getTime();\n var input1 = inputF(t1 / 1000);\n \n function update() {\n var t2 = new Date().getTime();\n var input2 = inputF(t2 / 1000);\n var dt = (t2 - t1) / 1000;\n \n sum += (input1 + input2) * dt / 2;\n \n t1 = t2;\n input1 = input2;\n }\n \n var updater = setInterval(update, sampleIntervalMS);\n \n return ({\n input: function (newF) { inputF = newF },\n output: function () { return sum },\n shutdown: function () { clearInterval(updater) },\n });\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "AKS test for primes", + "type": "Waypoint", + "description": [ + "

The AKS algorithm for testing whether a number is prime is a polynomial-time algorithm based on an elementary theorem about Pascal triangles.

The theorem on which the test is based can be stated as follows:

a number $p$ is prime if and only if all the coefficients of the polynomial expansion of:: $(x-1)^p - (x^p - 1)$", + "

are divisible by $p$.

", + "Example:", + "

Using $p=3$:

(x-1)^3 - (x^3 - 1)

", + "

= (x^3 - 3x^2 + 3x - 1) - (x^3 - 1)

", + "

= -3x^2 + 3x

", + "

And all the coefficients are divisible by 3, so 3 is prime.

", + "Task:", + "Create a function/subroutine/method that given $p$ generates the coefficients of the expanded polynomial representation of $(x-1)^p$.", + "Use the function to show here the polynomial expansions of $(x-1)^p$ for $p$ in the range 0 to at least 7, inclusive.", + "Use the previous function in creating another function that when given $p$ returns whether $p$ is prime using the theorem.", + "Use your test to generate a list of all primes under 35.", + "As a stretch goal, generate all primes under 50 (needs integers larger than 31-bit).References:", + "Agrawal-Kayal-Saxena (AKS) primality test (Wikipedia) ", + "Fool-Proof Test for Primes - Numberphile (Video). The accuracy of this video is disputed -- at best it is an oversimplification." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{trans|CoffeeScript}}", + "var i, p, pascal, primerow, primes, show, _i;", + "", + "pascal = function() {", + " var a;", + " a = [];", + " return function() {", + " var b, i;", + " if (a.length === 0) {", + " return a = [1];", + " } else {", + " b = (function() {", + " var _i, _ref, _results;", + " _results = [];", + " for (i = _i = 0, _ref = a.length - 1; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {", + " _results.push(a[i] + a[i + 1]);", + " }", + " return _results;", + " })();", + " return a = [1].concat(b).concat([1]);", + " }", + " };", + "};", + "", + "show = function(a) {", + " var degree, i, sgn, show_x, str, _i, _ref;", + " show_x = function(e) {", + " switch (e) {", + " case 0:", + " return \"\";", + " case 1:", + " return \"x\";", + " default:", + " return \"x^\" + e;", + " }", + " };", + " degree = a.length - 1;", + " str = \"(x - 1)^\" + degree + \" =\";", + " sgn = 1;", + " for (i = _i = 0, _ref = a.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {", + " str += ' ' + (sgn > 0 ? \"+\" : \"-\") + ' ' + a[i] + show_x(degree - i);", + " sgn = -sgn;", + " }", + " return str;", + "};", + "", + "primerow = function(row) {", + " var degree;", + " degree = row.length - 1;", + " return row.slice(1, degree).every(function(x) {", + " return x % degree === 0;", + " });", + "};", + "", + "p = pascal();", + "", + "for (i = _i = 0; _i <= 7; i = ++_i) {", + " console.log(show(p()));", + "}", + "", + "p = pascal();", + "", + "p();", + "", + "p();", + "", + "primes = (function() {", + " var _j, _results;", + " _results = [];", + " for (i = _j = 1; _j <= 49; i = ++_j) {", + " if (primerow(p())) {", + " _results.push(i + 1);", + " }", + " }", + " return _results;", + "})();", + "", + "console.log(\"\");", + "", + "console.log(\"The primes upto 50 are: \" + primes);", + "{{out}}", + "
(x - 1)^0 = + 1",
+      "(x - 1)^1 = + 1x - 1",
+      "(x - 1)^2 = + 1x^2 - 2x + 1",
+      "(x - 1)^3 = + 1x^3 - 3x^2 + 3x - 1",
+      "(x - 1)^4 = + 1x^4 - 4x^3 + 6x^2 - 4x + 1",
+      "(x - 1)^5 = + 1x^5 - 5x^4 + 10x^3 - 10x^2 + 5x - 1",
+      "(x - 1)^6 = + 1x^6 - 6x^5 + 15x^4 - 20x^3 + 15x^2 - 6x + 1",
+      "(x - 1)^7 = + 1x^7 - 7x^6 + 21x^5 - 35x^4 + 35x^3 - 21x^2 + 7x - 1",
+      "",
+      "The primes upto 50 are: 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47
", + "Reviewed (ES6):", + "function pascal(n) {", + "\tvar cs = []; if (n) while (n--) coef(); return coef", + "\tfunction coef() {", + "\t\tif (cs.length === 0) return cs = [1];", + "\t\tfor (var t=[1,1], i=cs.length-1; i; i-=1) t.splice( 1, 0, cs[i-1]+cs[i] ); return cs = t", + "\t}", + "}", + "", + "function show(cs) {", + "\tfor (var s='', sgn=true, i=0, deg=cs.length-1; i<=deg; sgn=!sgn, i+=1) {", + "\t\ts += ' ' + (sgn ? '+' : '-') + cs[i] + (e => e==0 ? '' : e==1 ? 'x' : 'x' + e + '')(deg-i)", + "\t}", + "\treturn '(x-1)' + deg + ' =' + s;", + "}", + "", + "function isPrime(cs) {", + "\tvar deg=cs.length-1; return cs.slice(1, deg).every( function(c) { return c % deg === 0 } )", + "}", + "", + "var coef=pascal(); for (var i=0; i<=7; i+=1) document.write(show(coef()), '
')", + "", + "document.write('
Primes: ');", + "for (var coef=pascal(2), n=2; n<=50; n+=1) if (isPrime(coef())) document.write(' ', n)
", + "{{output}}", + " (x-1)0 = +1", + " (x-1)1 = +1x -1", + " (x-1)2 = +1x2 -2x +1", + " (x-1)3 = +1x3 -3x2 +3x -1", + " (x-1)4 = +1x4 -4x3 +6x2 -4x +1", + " (x-1)5 = +1x5 -5x4 +10x3 -10x2 +5x -1", + " (x-1)6 = +1x6 -6x5 +15x4 -20x3 +15x2 -6x +1", + " (x-1)7 = +1x7 -7x6 +21x5 -35x4 +35x3 -21x2 +7x -1", + " ", + " Primes: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47", + "{{trans|C}}", + "function coef(n) {", + " \tfor (var c=[1], i=0; i0 ? ' +' : ' ') + cs[n] + (n==0 ? '' : n==1 ? 'x' :'x'+n+''); while (n--)", + "\treturn s", + "}", + " ", + "function isPrime(n) {", + "\tvar cs=coef(n), i=n-1; while (i-- && cs[i]%n == 0);", + "\treturn i < 1", + "}", + " ", + "for (var n=0; n<=7; n++) document.write('(x-1)',n,' = ', show(coef(n)), '
')", + " ", + "document.write('
Primes: ');", + "for (var n=2; n<=50; n++) if (isPrime(n)) document.write(' ', n)
", + "{{output}}", + " (x-1)0 = +1", + " (x-1)1 = +1x -1", + " (x-1)2 = +1x2 -2x +1", + " (x-1)3 = +1x3 -3x2 +3x -1", + " (x-1)4 = +1x4 -4x3 +6x2 -4x +1", + " (x-1)5 = +1x5 -5x4 +10x3 -10x2 +5x -1", + " (x-1)6 = +1x6 -6x5 +15x4 -20x3 +15x2 -6x +1", + " (x-1)7 = +1x7 -7x6 +21x5 -35x4 +35x3 -21x2 +7x -1", + " ", + " Primes: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d71", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var i, p, pascal, primerow, primes, show, _i;\n\npascal = function() {\n var a;\n a = [];\n return function() {\n var b, i;\n if (a.length === 0) {\n return a = [1];\n } else {\n b = (function() {\n var _i, _ref, _results;\n _results = [];\n for (i = _i = 0, _ref = a.length - 1; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n _results.push(a[i] + a[i + 1]);\n }\n return _results;\n })();\n return a = [1].concat(b).concat([1]);\n }\n };\n};\n\nshow = function(a) {\n var degree, i, sgn, show_x, str, _i, _ref;\n show_x = function(e) {\n switch (e) {\n case 0:\n return \"\";\n case 1:\n return \"x\";\n default:\n return \"x^\" + e;\n }\n };\n degree = a.length - 1;\n str = \"(x - 1)^\" + degree + \" =\";\n sgn = 1;\n for (i = _i = 0, _ref = a.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n str += ' ' + (sgn > 0 ? \"+\" : \"-\") + ' ' + a[i] + show_x(degree - i);\n sgn = -sgn;\n }\n return str;\n};\n\nprimerow = function(row) {\n var degree;\n degree = row.length - 1;\n return row.slice(1, degree).every(function(x) {\n return x % degree === 0;\n });\n};\n\np = pascal();\n\nfor (i = _i = 0; _i <= 7; i = ++_i) {\n console.log(show(p()));\n}\n\np = pascal();\n\np();\n\np();\n\nprimes = (function() {\n var _j, _results;\n _results = [];\n for (i = _j = 1; _j <= 49; i = ++_j) {\n if (primerow(p())) {\n _results.push(i + 1);\n }\n }\n return _results;\n})();\n\nconsole.log(\"\");\n\nconsole.log(\"The primes upto 50 are: \" + primes);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Amb", + "type": "Waypoint", + "description": [ + "

Define and give an example of the Amb operator.

The Amb operator expresses nondeterminism. This doesn't refer to randomness (as in \"nondeterministic universe\") but is closely related to the term as it is used in automata theory (\"non-deterministic finite automaton\").

The Amb operator takes a variable number of expressions (or values if that's simpler in the language) and yields a correct one which will satisfy a constraint in some future computation, thereby avoiding failure.

Problems whose solution the Amb operator naturally expresses can be approached with other tools, such as explicit nested iterations over data sets, or with pattern matching. By contrast, the Amb operator appears integrated into the language. Invocations of Amb are not wrapped in any visible loops or other search patterns; they appear to be independent.

Essentially Amb(x, y, z) splits the computation into three possible futures: a future in which the value x is yielded, a future in which the value y is yielded and a future in which the value z is yielded. The future which leads to a successful subsequent computation is chosen. The other \"parallel universes\" somehow go away. Amb called with no arguments fails.

For simplicity, one of the domain values usable with Amb may denote failure, if that is convenient. For instance, it is convenient if a Boolean false denotes failure, so that Amb(false) fails, and thus constraints can be expressed using Boolean expressions like Amb(x * y == 8) which unless x and y add to four.

A pseudo-code program which satisfies this constraint might look like:

let x = Amb(1, 2, 3)",
+      "let y = Amb(7, 6, 4, 5)",
+      "Amb(x * y = 8)",
+      "print x, y

The output is 2 4 because Amb(1, 2, 3) correctly chooses the future in which x has value 2, Amb(7, 6, 4, 5) chooses 4 and consequently Amb(x * y = 8) produces a success.

Alternatively, failure could be represented using strictly Amb():

unless x * y = 8 do Amb()

Or else Amb could take the form of two operators or functions: one for producing values and one for enforcing constraints:

let x = Ambsel(1, 2, 3)",
+      "let y = Ambsel(4, 5, 6)",
+      "Ambassert(x * y = 8)",
+      "print x, y

where Ambassert behaves like Amb() if the Boolean expression is false, otherwise it allows the future computation to take place, without yielding any value.

The task is to somehow implement Amb, and demonstrate it with a program which chooses one word from each of the following four sets of character strings to generate a four-word sentence:

\"the\" \"that\" \"a\"", + "\"frog\" \"elephant\" \"thing\"", + "\"walked\" \"treaded\" \"grows\"", + "\"slowly\" \"quickly\"", + "

The constraint to be satisfied is that the last character of each word (other than the last) is the same as the first character of its successor.

The only successful sentence is \"that thing grows slowly\"; other combinations do not satisfy the constraint and thus fail.

The goal of this task isn't to simply process the four lists of words with explicit, deterministic program flow such as nested iteration, to trivially demonstrate the correct output. The goal is to implement the Amb operator, or a facsimile thereof that is possible within the language limitations.

====

", + "

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

", + "

with Ada.Text_IO; use Ada.Text_IO;

procedure Test_Amb is

", + "

type Alternatives is array (Positive range <>) of Unbounded_String;

type Amb (Count : Positive) is record

", + "

This : Positive := 1;

", + "

Left : access Amb;

", + "

List : Alternatives (1..Count);

", + "

end record;

function Image (L : Amb) return String is

", + "

begin

", + "

return To_String (L.List (L.This));

", + "

end Image;

function \"/\" (L, R : String) return Amb is

", + "

Result : Amb (2);

", + "

begin

", + "

Append (Result.List (1), L);

", + "

Append (Result.List (2), R);

", + "

return Result;

", + "

end \"/\";

function \"/\" (L : Amb; R : String) return Amb is

", + "

Result : Amb (L.Count + 1);

", + "

begin

", + "

Result.List (1..L.Count) := L.List ;

", + "

Append (Result.List (Result.Count), R);

", + "

return Result;

", + "

end \"/\";

function \"=\" (L, R : Amb) return Boolean is

", + "

Left : Unbounded_String renames L.List (L.This);

", + "

begin

", + "

return Element (Left, Length (Left)) = Element (R.List (R.This), 1);

", + "

end \"=\";

procedure Failure (L : in out Amb) is

", + "

begin

", + "

loop

", + "

if L.This < L.Count then

", + "

L.This := L.This + 1;

", + "

else

", + "

L.This := 1;

", + "

Failure (L.Left.all);

", + "

end if;

", + "

exit when L.Left = null or else L.Left.all = L;

", + "

end loop;

", + "

end Failure;

procedure Join (L : access Amb; R : in out Amb) is

", + "

begin

", + "

R.Left := L;

", + "

while L.all /= R loop

", + "

Failure (R);

", + "

end loop;

", + "

end Join;

W_1 : aliased Amb := \"the\" / \"that\" / \"a\";

", + "

W_2 : aliased Amb := \"frog\" / \"elephant\" / \"thing\";

", + "

W_3 : aliased Amb := \"walked\" / \"treaded\" / \"grows\";

", + "

W_4 : aliased Amb := \"slowly\" / \"quickly\";

", + "

begin

", + "

Join (W_1'Access, W_2);

", + "

Join (W_2'Access, W_3);

", + "

Join (W_3'Access, W_4);

", + "

Put_Line (Image (W_1) & ' ' & Image (W_2) & ' ' & Image (W_3) & ' ' & Image (W_4));

", + "

end Test_Amb;

", + "

The type Amb is implemented with the operations \"/\" to construct it from strings.

", + "

Each instance keeps its state.

", + "

The operation Failure performs back tracing. Join connects two elements into a chain.

", + "

The implementation propagates Constraint_Error when matching fails.

",
+      "that thing grows slowly",
+      "
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function ambRun(func) {", + " var choices = [];", + " var index;", + "", + " function amb(values) {", + " if (values.length == 0) {", + " fail();", + " }", + " if (index == choices.length) {", + " choices.push({i: 0,", + " count: values.length});", + " }", + " var choice = choices[index++];", + " return values[choice.i];", + " }", + "", + " function fail() { throw fail; }", + "", + " while (true) {", + " try {", + " index = 0;", + " return func(amb, fail);", + " } catch (e) {", + " if (e != fail) {", + " throw e;", + " }", + " var choice;", + " while ((choice = choices.pop()) && ++choice.i == choice.count) {}", + " if (choice == undefined) {", + " return undefined;", + " }", + " choices.push(choice);", + " }", + " }", + "}", + "", + "ambRun(function(amb, fail) {", + " function linked(s1, s2) {", + " return s1.slice(-1) == s2.slice(0, 1);", + " }", + "", + " var w1 = amb([\"the\", \"that\", \"a\"]);", + " var w2 = amb([\"frog\", \"elephant\", \"thing\"]);", + " if (!linked(w1, w2)) fail();", + "", + " var w3 = amb([\"walked\", \"treaded\", \"grows\"]);", + " if (!linked(w2, w3)) fail();", + "", + " var w4 = amb([\"slowly\", \"quickly\"]);", + " if (!linked(w3, w4)) fail();", + "", + " return [w1, w2, w3, w4].join(' ');", + "}); // \"that thing grows slowly\"", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d75", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function ambRun(func) {\n var choices = [];\n var index;\n\n function amb(values) {\n if (values.length == 0) {\n fail();\n }\n if (index == choices.length) {\n choices.push({i: 0,\n count: values.length});\n }\n var choice = choices[index++];\n return values[choice.i];\n }\n\n function fail() { throw fail; }\n\n while (true) {\n try {\n index = 0;\n return func(amb, fail);\n } catch (e) {\n if (e != fail) {\n throw e;\n }\n var choice;\n while ((choice = choices.pop()) && ++choice.i == choice.count) {}\n if (choice == undefined) {\n return undefined;\n }\n choices.push(choice);\n }\n }\n}\n\nambRun(function(amb, fail) {\n function linked(s1, s2) {\n return s1.slice(-1) == s2.slice(0, 1);\n }\n\n var w1 = amb([\"the\", \"that\", \"a\"]);\n var w2 = amb([\"frog\", \"elephant\", \"thing\"]);\n if (!linked(w1, w2)) fail();\n\n var w3 = amb([\"walked\", \"treaded\", \"grows\"]);\n if (!linked(w2, w3)) fail();\n\n var w4 = amb([\"slowly\", \"quickly\"]);\n if (!linked(w3, w4)) fail();\n\n return [w1, w2, w3, w4].join(' ');\n}); // \"that thing grows slowly\"\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Anagrams/Deranged anagrams", + "type": "Waypoint", + "description": [ + "

Two or more words are said to be anagrams if they have the same characters, but in a different order.

By analogy with derangements we define a deranged anagram as two words with the same characters, but in which the same character does not appear in the same position in both words.

", + "

Use the word list at unixdict to find and display the longest deranged anagram.

", + "Permutations/Derangements", + "Best shuffle


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "=== Spidermonkey ===", + "", + "This example is a little long because ", + "it tries to emphasize generality and clarity over", + "brevity.", + "", + "#!/usr/bin/env js", + "", + "function main() {", + " var wordList = read('unixdict.txt').split(/\\s+/);", + " var anagrams = findAnagrams(wordList);", + " var derangedAnagrams = findDerangedAnagrams(anagrams);", + " var longestPair = findLongestDerangedPair(derangedAnagrams);", + " print(longestPair.join(' '));", + " ", + "}", + "", + "function findLongestDerangedPair(danas) {", + " var longestLen = danas[0][0].length;", + " var longestPair = danas[0];", + " for (var i in danas) {", + " if (danas[i][0].length > longestLen) {", + " longestLen = danas[i][0].length;", + " longestPair = danas[i];", + " }", + " }", + " return longestPair;", + "}", + "", + "function findDerangedAnagrams(anagrams) {", + " var deranged = [];", + " ", + " function isDeranged(w1, w2) {", + " for (var c = 0; c < w1.length; c++) {", + " if (w1[c] == w2[c]) {", + " return false;", + " }", + " }", + " return true;", + " }", + "", + " function findDeranged(anas) {", + " for (var a = 0; a < anas.length; a++) {", + " for (var b = a + 1; b < anas.length; b++) {", + " if (isDeranged(anas[a], anas[b])) {", + " deranged.push([anas[a], anas[b]]);", + " } ", + " }", + " }", + " }", + " ", + " for (var a in anagrams) {", + " var anas = anagrams[a];", + " findDeranged(anas);", + " }", + " ", + " return deranged;", + "}", + " ", + "function findAnagrams(wordList) {", + " var anagrams = {};", + "", + " for (var wordNum in wordList) {", + " var word = wordList[wordNum];", + " var key = word.split('').sort().join('');", + " if (!(key in anagrams)) {", + " anagrams[key] = [];", + " }", + " anagrams[key].push(word);", + " }", + "", + " for (var a in anagrams) {", + " if (anagrams[a].length < 2) {", + " delete(anagrams[a]);", + " }", + " }", + "", + " return anagrams;", + "}", + "", + "main();", + "", + "", + "", + "{{out}}", + " excitation intoxicate", + "", + "=== Gecko ===", + "Word file is saved locally because browser won't fetch it cross-site. Tested on Gecko.", + "Intoxication", + "
",
+      "
", + "", + "{{Out|Output (in a browser window)}}", + "
intoxicate,excitation
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d77", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "#!/usr/bin/env js\n\nfunction main() {\n var wordList = read('unixdict.txt').split(/\\s+/);\n var anagrams = findAnagrams(wordList);\n var derangedAnagrams = findDerangedAnagrams(anagrams);\n var longestPair = findLongestDerangedPair(derangedAnagrams);\n print(longestPair.join(' '));\n \n}\n\nfunction findLongestDerangedPair(danas) {\n var longestLen = danas[0][0].length;\n var longestPair = danas[0];\n for (var i in danas) {\n if (danas[i][0].length > longestLen) {\n longestLen = danas[i][0].length;\n longestPair = danas[i];\n }\n }\n return longestPair;\n}\n\nfunction findDerangedAnagrams(anagrams) {\n var deranged = [];\n \n function isDeranged(w1, w2) {\n for (var c = 0; c < w1.length; c++) {\n if (w1[c] == w2[c]) {\n return false;\n }\n }\n return true;\n }\n\n function findDeranged(anas) {\n for (var a = 0; a < anas.length; a++) {\n for (var b = a + 1; b < anas.length; b++) {\n if (isDeranged(anas[a], anas[b])) {\n deranged.push([anas[a], anas[b]]);\n } \n }\n }\n }\n \n for (var a in anagrams) {\n var anas = anagrams[a];\n findDeranged(anas);\n }\n \n return deranged;\n}\n \nfunction findAnagrams(wordList) {\n var anagrams = {};\n\n for (var wordNum in wordList) {\n var word = wordList[wordNum];\n var key = word.split('').sort().join('');\n if (!(key in anagrams)) {\n anagrams[key] = [];\n }\n anagrams[key].push(word);\n }\n\n for (var a in anagrams) {\n if (anagrams[a].length < 2) {\n delete(anagrams[a]);\n }\n }\n\n return anagrams;\n}\n\nmain();\n\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Anagrams", + "type": "Waypoint", + "description": [ + "

When two or more words are composed of the same characters, but in a different order, they are called anagrams.

", + "

Using the word list at http://www.puzzlers.org/pub/wordlists/unixdict.txt,

", + "find the sets of words that share the same characters that contain the most words in them.", + "


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{Works with|Node.js}}", + "var fs = require('fs');", + "var words = fs.readFileSync('unixdict.txt', 'UTF-8').split('\\n');", + "", + "var i, item, max = 0,", + " anagrams = {};", + " ", + "for (i = 0; i < words.length; i += 1) {", + " var key = words[i].split('').sort().join('');", + " if (!anagrams.hasOwnProperty(key)) {//check if property exists on current obj only", + " anagrams[key] = [];", + " }", + " var count = anagrams[key].push(words[i]); //push returns new array length", + " max = Math.max(count, max);", + "}", + "", + "//note, this returns all arrays that match the maximum length", + "for (item in anagrams) {", + " if (anagrams.hasOwnProperty(item)) {//check if property exists on current obj only", + " if (anagrams[item].length === max) {", + " console.log(anagrams[item].join(' '));", + " }", + " }", + "}", + "", + "{{Out}}", + "
[ 'abel', 'able', 'bale', 'bela', 'elba' ]",
+      "[ 'alger', 'glare', 'lager', 'large', 'regal' ]",
+      "[ 'angel', 'angle', 'galen', 'glean', 'lange' ]",
+      "[ 'caret', 'carte', 'cater', 'crate', 'trace' ]",
+      "[ 'elan', 'lane', 'lean', 'lena', 'neal' ]",
+      "[ 'evil', 'levi', 'live', 'veil', 'vile' ]
", + "", + "==Alternative Using Reduce==", + "var fs = require('fs');", + "var dictionary = fs.readFileSync('unixdict.txt', 'UTF-8').split('\\n');", + "", + "//group anagrams", + "var sortedDict = dictionary.reduce(function (acc, word) {", + " var sortedLetters = word.split('').sort().join('');", + " if (acc[sortedLetters] === undefined) { acc[sortedLetters] = []; }", + " acc[sortedLetters].push(word);", + " return acc;", + "}, {});", + "", + "//sort list by frequency", + "var keysSortedByFrequency = Object.keys(sortedDict).sort(function (keyA, keyB) {", + " if (sortedDict[keyA].length < sortedDict[keyB].length) { return 1; }", + " if (sortedDict[keyA].length > sortedDict[keyB].length) { return -1; }", + " return 0;", + "});", + "", + "//print first 10 anagrams by frequency", + "keysSortedByFrequency.slice(0, 10).forEach(function (key) {", + " console.log(sortedDict[key].join(' '));", + "});", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d78", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var fs = require('fs');\nvar words = fs.readFileSync('unixdict.txt', 'UTF-8').split('\\n');\n\nvar i, item, max = 0,\n anagrams = {};\n \nfor (i = 0; i < words.length; i += 1) {\n var key = words[i].split('').sort().join('');\n if (!anagrams.hasOwnProperty(key)) {//check if property exists on current obj only\n anagrams[key] = [];\n }\n var count = anagrams[key].push(words[i]); //push returns new array length\n max = Math.max(count, max);\n}\n\n//note, this returns all arrays that match the maximum length\nfor (item in anagrams) {\n if (anagrams.hasOwnProperty(item)) {//check if property exists on current obj only\n if (anagrams[item].length === max) {\n console.log(anagrams[item].join(' '));\n }\n }\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Arbitrary-precision integers (included)", + "type": "Waypoint", + "description": [ + "

Using the in-built capabilities of your language, calculate the integer value of:

$5^{4^{3^2}}$

Confirm that the first and last twenty digits of the answer are: 62060698786608744707...92256259918212890625", + " Find and show the number of decimal digits in the answer.", + "

Note: Do not submit an implementation of arbitrary precision arithmetic. The intention is to show the capabilities of the language as supplied. If a language has a single, overwhelming, library of varied modules that is endorsed by its home site – such as CPAN for Perl or Boost for C++ – then that may be used instead.

", + "Strictly speaking, this should not be solved by fixed-precision numeric libraries where the precision has to be manually set to a large value; although if this is the only recourse then it may be used with a note explaining that the precision must be set manually to a large enough value.", + "See also:", + "Long multiplication", + "Exponentiation order" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d7e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Arithmetic/Complex", + "type": "Waypoint", + "description": [ + "

A complex number is a number which can be written as:

", + "

$a + b \\times i$

", + "

(sometimes shown as:

", + "

$b + a \\times i$

", + "

where $a$ and $b$ are real numbers, and $i$ is

", + "

Typically, complex numbers are represented as a pair of real numbers called the \"imaginary part\" and \"real part\", where the imaginary part is the number to be multiplied by $i$.

", + "Task:", + "Show addition, multiplication, negation, and inversion of complex numbers in separate functions. (Subtraction and division operations can be made with pairs of these operations.) ", + "Print the results for each operation tested.", + "Optional: Show complex conjugation.", + "

By definition, the complex conjugate of

", + "

$a + bi$

", + "

is

", + "

$a - bi$

", + "

Some languages have complex number libraries available. If your language does, show the operations. If your language does not, also show the definition of this type.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function Complex(r, i) {", + "\tthis.r = r;", + "\tthis.i = i;", + "}", + "", + "Complex.add = function() {", + "\tvar num = arguments[0];", + "\t", + "\tfor(var i = 1, ilim = arguments.length; i < ilim; i += 1){", + "\t\tnum.r += arguments[i].r;", + "\t\tnum.i += arguments[i].i;", + "\t}", + "\t", + "\treturn num;", + "}", + "", + "Complex.multiply = function() {", + "\tvar num = arguments[0];", + "\t", + "\tfor(var i = 1, ilim = arguments.length; i < ilim; i += 1){", + "\t\tnum.r = (num.r * arguments[i].r) - (num.i * arguments[i].i);", + "\t\tnum.i = (num.i * arguments[i].r) - (num.r * arguments[i].i);", + "\t}", + "\t", + "\treturn num;", + "}", + "", + "Complex.negate = function (z) {", + "\treturn new Complex(-1*z.r, -1*z.i);", + "}", + "", + "Complex.invert = function(z) {", + "\tvar denom = Math.pow(z.r,2) + Math.pow(z.i,2);", + "\treturn new Complex(z.r/denom, -1*z.i/denom);", + "}", + "", + "Complex.conjugate = function(z) {", + "\treturn new Complex(z.r, -1*z.i);", + "}", + "", + "// BONUSES!", + "", + "", + "Complex.prototype.toString = function() {", + "\treturn this.r === 0 && this.i === 0", + " ? \"0\"", + " : (this.r !== 0 ? this.r : \"\") ", + " + ((this.r !== 0 || this.i < 0) && this.i !== 0 ", + " ? (this.i > 0 ? \"+\" : \"-\") ", + " : \"\" ) + ( this.i !== 0 ? Math.abs(this.i) + \"i\" : \"\" ); ", + "}", + "", + "Complex.prototype.getMod = function() {", + "\treturn Math.sqrt( Math.pow(this.r,2) , Math.pow(this.i,2) )", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d81", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function Complex(r, i) {\n\tthis.r = r;\n\tthis.i = i;\n}\n\nComplex.add = function() {\n\tvar num = arguments[0];\n\t\n\tfor(var i = 1, ilim = arguments.length; i < ilim; i += 1){\n\t\tnum.r += arguments[i].r;\n\t\tnum.i += arguments[i].i;\n\t}\n\t\n\treturn num;\n}\n\nComplex.multiply = function() {\n\tvar num = arguments[0];\n\t\n\tfor(var i = 1, ilim = arguments.length; i < ilim; i += 1){\n\t\tnum.r = (num.r * arguments[i].r) - (num.i * arguments[i].i);\n\t\tnum.i = (num.i * arguments[i].r) - (num.r * arguments[i].i);\n\t}\n\t\n\treturn num;\n}\n\nComplex.negate = function (z) {\n\treturn new Complex(-1*z.r, -1*z.i);\n}\n\nComplex.invert = function(z) {\n\tvar denom = Math.pow(z.r,2) + Math.pow(z.i,2);\n\treturn new Complex(z.r/denom, -1*z.i/denom);\n}\n\nComplex.conjugate = function(z) {\n\treturn new Complex(z.r, -1*z.i);\n}\n\n// BONUSES!\n\n\nComplex.prototype.toString = function() {\n\treturn this.r === 0 && this.i === 0\n ? \"0\"\n : (this.r !== 0 ? this.r : \"\") \n + ((this.r !== 0 || this.i < 0) && this.i !== 0 \n ? (this.i > 0 ? \"+\" : \"-\") \n : \"\" ) + ( this.i !== 0 ? Math.abs(this.i) + \"i\" : \"\" ); \n}\n\nComplex.prototype.getMod = function() {\n\treturn Math.sqrt( Math.pow(this.r,2) , Math.pow(this.i,2) )\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Arithmetic-geometric mean", + "type": "Waypoint", + "description": [ + "task:

Write a function to compute the arithmetic-geometric mean of two numbers.

", + "

[http://mathworld.wolfram.com/Arithmetic-GeometricMean.html]

", + "

The arithmetic-geometric mean of two numbers can be (usefully) denoted as $\\mathrm{agm}(a,g)$, and is equal to the limit of the sequence:

", + "

$a_0 = a; \\qquad g_0 = g$

", + "

$a_{n+1} = \\tfrac{1}{2}(a_n + g_n); \\quad g_{n+1} = \\sqrt{a_n g_n}.$

", + "

Since the limit of $a_n-g_n$ tends (rapidly) to zero with iterations, this is an efficient method.

Demonstrate the function by calculating:

", + "

$\\mathrm{agm}(1,1/\\sqrt{2})$

", + "Also see:", + " mathworld.wolfram.com/Arithmetic-Geometric Mean" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "function agm(a0, g0) {", + " var an = (a0 + g0) / 2,", + " gn = Math.sqrt(a0 * g0);", + " while (Math.abs(an - gn) > tolerance) {", + " an = (an + gn) / 2, gn = Math.sqrt(an * gn)", + " }", + " return an;", + "}", + "", + "agm(1, 1 / Math.sqrt(2));", + "", + "===ES6===", + "(() => {", + " 'use strict';", + "", + " // ARITHMETIC-GEOMETRIC MEAN", + "", + " // agm :: Num a => a -> a -> a", + " let agm = (a, g) => {", + " let abs = Math.abs,", + " sqrt = Math.sqrt;", + "", + " return until(", + " m => abs(m.an - m.gn) < tolerance,", + " m => {", + " return {", + " an: (m.an + m.gn) / 2,", + " gn: sqrt(m.an * m.gn)", + " };", + " }, {", + " an: (a + g) / 2,", + " gn: sqrt(a * g)", + " }", + " )", + " .an;", + " },", + "", + " // GENERIC", + "", + " // until :: (a -> Bool) -> (a -> a) -> a -> a", + " until = (p, f, x) => {", + " let v = x;", + " while (!p(v)) v = f(v);", + " return v;", + " };", + "", + "", + " // TEST", + "", + " let tolerance = 0.000001;", + "", + "", + " return agm(1, 1 / Math.sqrt(2));", + "", + "})();", + "", + "{{Out}}", + "0.8472130848351929", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d84", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function agm(a0, g0) {\n var an = (a0 + g0) / 2,\n gn = Math.sqrt(a0 * g0);\n while (Math.abs(an - gn) > tolerance) {\n an = (an + gn) / 2, gn = Math.sqrt(an * gn)\n }\n return an;\n}\n\nagm(1, 1 / Math.sqrt(2));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Arithmetic/Rational", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a reasonably complete implementation of rational arithmetic in the particular language using the idioms of the language.

", + "Example:", + "

Define a new type called frac with binary operator \"//\" of two integers that returns a structure made up of the numerator and the denominator (as per a rational number).

Further define the appropriate rational unary operators abs and '-', with the binary operators for addition '+', subtraction '-', multiplication '×', division '/', integer division '÷', modulo division, the comparison operators (e.g. '<', '≤', '>', & '≥') and equality operators (e.g. '=' & '≠').

Define standard coercion operators for casting int to frac etc.

If space allows, define standard increment and decrement operators (e.g. '+:=' & '-:=' etc.).

Finally test the operators:

", + "

Use the new type frac to find all perfect numbers less than 219 by summing the reciprocal of the factors.

", + "Related task:", + " Perfect Numbers" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "
''[This section is included from [[Arithmetic/Rational/JavaScript|a subpage]] and should be edited there, not here.]''
", + "{{:Arithmetic/Rational/JavaScript}}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d86", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["null\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Averages/Simple moving average", + "type": "Waypoint", + "description": [ + "

Computing the simple moving average of a series of numbers.

", + "

Create a stateful function/class/instance that takes a period and returns a routine that takes a number as argument and returns a simple moving average of its arguments so far.

", + "

A simple moving average is a method for computing an average of a stream of numbers by only averaging the last P numbers from the stream, where P is known as the period.

It can be implemented by calling an initialing routine with P as its argument, I(P), which should then return a routine that when called with individual, successive members of a stream of numbers, computes the mean of (up to), the last P of them, lets call this SMA().

The word stateful in the task description refers to the need for SMA() to remember certain information between calls to it:

", + " The period, P", + " An ordered container of at least the last P numbers from each of its individual calls.", + "

Stateful also means that successive calls to I(), the initializer, should return separate routines that do not share saved state so they could be used on two independent streams of data.

Pseudo-code for an implementation of SMA is:

", + "
",
+      "function SMA(number: N):",
+      "    stateful integer: P",
+      "    stateful list:    stream",
+      "    number:           average    stream.append_last(N)",
+      "    if stream.length() > P:",
+      "        # Only average the last P elements of the stream",
+      "        stream.delete_first()",
+      "    if stream.length() == 0:",
+      "        average = 0",
+      "    else:    ",
+      "        average = sum( stream.values() ) / stream.length()",
+      "    return average",
+      "
", + "


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===Using for loop===", + "function simple_moving_averager(period) {", + " var nums = [];", + " return function(num) {", + " nums.push(num);", + " if (nums.length > period)", + " nums.splice(0,1); // remove the first element of the array", + " var sum = 0;", + " for (var i in nums)", + " sum += nums[i];", + " var n = period;", + " if (nums.length < period)", + " n = nums.length;", + " return(sum/n);", + " }", + "}", + "", + "var sma3 = simple_moving_averager(3);", + "var sma5 = simple_moving_averager(5);", + "var data = [1,2,3,4,5,5,4,3,2,1];", + "for (var i in data) {", + " var n = data[i];", + " // using WSH", + " WScript.Echo(\"Next number = \" + n + \", SMA_3 = \" + sma3(n) + \", SMA_5 = \" + sma5(n));", + "}", + "{{out}}", + "
Next number = 1, SMA_3 = 1, SMA_5 = 1",
+      "Next number = 2, SMA_3 = 1.5, SMA_5 = 1.5",
+      "Next number = 3, SMA_3 = 2, SMA_5 = 2",
+      "Next number = 4, SMA_3 = 3, SMA_5 = 2.5",
+      "Next number = 5, SMA_3 = 4, SMA_5 = 3",
+      "Next number = 5, SMA_3 = 4.666666666666667, SMA_5 = 3.8",
+      "Next number = 4, SMA_3 = 4.666666666666667, SMA_5 = 4.2",
+      "Next number = 3, SMA_3 = 4, SMA_5 = 4.2",
+      "Next number = 2, SMA_3 = 3, SMA_5 = 3.8",
+      "Next number = 1, SMA_3 = 2, SMA_5 = 3
", + "", + "===Using reduce/filter===", + "[http://jsfiddle.net/79xe381e/ JS Fiddle]", + "", + "// single-sided", + "Array.prototype.simpleSMA=function(N) {", + "return this.map(", + " function(el,index, _arr) { ", + " return _arr.filter(", + " function(x2,i2) { ", + " return i2 <= index && i2 > index - N;", + " })", + " .reduce(", + " function(current, last, index, arr){ ", + " return (current + last); ", + " })/index || 1;", + " }); ", + "};", + "", + "g=[0,1,2,3,4,5,6,7,8,9,10];", + "console.log(g.simpleSMA(3));", + "console.log(g.simpleSMA(5));", + "console.log(g.simpleSMA(g.length));", + "{{out}}", + "
",
+      "[1, 1, 1.5, 2, 2.25, 2.4, 2.5, 2.5714285714285716, 2.625, 2.6666666666666665, 2.7]",
+      "[1, 1, 1.5, 2, 2.5, 3, 3.3333333333333335, 3.5714285714285716, 3.75, 3.888888888888889, 4]",
+      "[1, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5]",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d96", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function simple_moving_averager(period) {\n var nums = [];\n return function(num) {\n nums.push(num);\n if (nums.length > period)\n nums.splice(0,1); // remove the first element of the array\n var sum = 0;\n for (var i in nums)\n sum += nums[i];\n var n = period;\n if (nums.length < period)\n n = nums.length;\n return(sum/n);\n }\n}\n\nvar sma3 = simple_moving_averager(3);\nvar sma5 = simple_moving_averager(5);\nvar data = [1,2,3,4,5,5,4,3,2,1];\nfor (var i in data) {\n var n = data[i];\n // using WSH\n WScript.Echo(\"Next number = \" + n + \", SMA_3 = \" + sma3(n) + \", SMA_5 = \" + sma5(n));\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Best shuffle", + "type": "Waypoint", + "description": [ + "Task:", + "

Shuffle the characters of a string in such a way that as many of the character values are in a different position as possible.

A shuffle that produces a randomized result among the best choices is to be preferred. A deterministic approach that produces the same sequence every time is acceptable as an alternative.

Display the result as follows:

original string, shuffled string, (score)

The score gives the number of positions whose character value did not change.

", + "Example:", + "

tree, eetr, (0)

", + "Test cases:", + "

abracadabra

", + "

seesaw

", + "

elk

", + "

grrrrrr

", + "

up

", + "

a

", + "Related tasks", + " Anagrams/Deranged anagrams", + " Permutations/Derangements" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "Based on the J implementation (and this would be a lot more concise if we used something like jQuery):", + "", + "function raze(a) { // like .join('') except producing an array instead of a string", + " var r= [];", + " for (var j= 0; j", + "", + "Example:", + "", + "
",
+      "
", + "", + "Produced:", + "
abracadabra, raababacdar, (0)",
+      "seesaw, ewaess, (0)",
+      "elk, lke, (0)",
+      "grrrrrr, rrrrrgr, (5)",
+      "up, pu, (0)",
+      "a, a, (1)
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7d9e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function raze(a) { // like .join('') except producing an array instead of a string\n var r= [];\n for (var j= 0; jreplaceMe is a function.');" + ] + }, + { + "title": "Bitwise operations", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a routine to perform a bitwise AND, OR, and XOR on two integers, a bitwise NOT on the first integer, a left shift, right shift, right arithmetic shift, left rotate, and right rotate.

All shifts and rotates should be done on the first integer with a shift/rotate amount of the second integer.

If any operation is not available in your language, note it.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "There are no integers in Javascript, but there are still bitwise operators. They will convert their number operands into integers before performing they task. In other languages, these operators are very close to the hardware and very fast. In JavaScript, they are very far from the hardware and very slow and rarely used.", + "", + "function bitwise(a, b){", + " alert(\"a AND b: \" + (a & b));", + " alert(\"a OR b: \"+ (a | b));", + " alert(\"a XOR b: \"+ (a ^ b));", + " alert(\"NOT a: \" + ~a);", + " alert(\"a << b: \" + (a << b)); // left shift", + " alert(\"a >> b: \" + (a >> b)); // arithmetic right shift", + " alert(\"a >>> b: \" + (a >>> b)); // logical right shift", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7db0", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function bitwise(a, b){\n alert(\"a AND b: \" + (a & b));\n alert(\"a OR b: \"+ (a | b));\n alert(\"a XOR b: \"+ (a ^ b));\n alert(\"NOT a: \" + ~a);\n alert(\"a << b: \" + (a << b)); // left shift\n alert(\"a >> b: \" + (a >> b)); // arithmetic right shift\n alert(\"a >>> b: \" + (a >>> b)); // logical right shift\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Brace expansion", + "type": "Waypoint", + "description": [ + "

Brace expansion is a type of parameter expansion made popular by Unix shells, where it allows users to specify multiple similar string parameters without having to type them all out. E.g. the parameter enable_{audio,video} would be interpreted as if both enable_audio and enable_video had been specified.

", + "

Write a function that can perform brace expansion on any input string, according to the following specification.

", + "

Demonstrate how it would be used, and that it passes the four test cases given below.

", + "

In the input string, balanced pairs of braces containing comma-separated substrings (details below) represent alternations that specify multiple alternatives which are to appear at that position in the output. In general, one can imagine the information conveyed by the input string as a tree of nested alternations interspersed with literal substrings, as shown in the middle part of the following diagram:

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "It{{em,alic}iz,erat}e{d,}", + "
", + "parse―――――▶‌", + "", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "
It

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

⎧⎨⎩

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

⎧⎨⎩

", + "

em

", + "

⎫⎬⎭

", + "

alic

", + "

", + "

iz

", + "

", + "

⎫⎬⎭

", + "

erat

", + "

e

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

⎧⎨⎩

", + "

d

", + "

⎫⎬⎭

", + "

", + "

", + "

", + "expand―――――▶‌", + "ItemizedItemizeItalicizedItalicize", + "

IteratedIterate

", + "
input stringalternation treeoutput (list of strings)
", + "

This tree can in turn be transformed into the intended list of output strings by, colloquially speaking, determining all the possible ways to walk through it from left to right while only descending into one branch of each alternation one comes across (see the right part of the diagram). When implementing it, one can of course combine the parsing and expansion into a single algorithm, but this specification discusses them separately for the sake of clarity.

Expansion of alternations can be more rigorously described by these rules:

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

a

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

⎧⎨⎩

", + "

2

", + "

⎫⎬⎭

", + "

1

", + "

b

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

⎧⎨⎩

", + "

X

", + "

⎫⎬⎭

", + "

Y
X

", + "

c

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "
a2bXc
a2bYc
a2bXc
a1bXc
a1bYc
a1bXc
", + "

", + "

An alternation causes the list of alternatives that will be produced by its parent branch to be increased 𝑛-fold, each copy featuring one of the 𝑛 alternatives produced by the alternation's child branches, in turn, at that position.

", + "

This means that multiple alternations inside the same branch are cumulative (i.e. the complete list of alternatives produced by a branch is the string-concatenating \"Cartesian product\" of its parts).

", + "

All alternatives (even duplicate and empty ones) are preserved, and they are ordered like the examples demonstrate (i.e. \"lexicographically\" with regard to the alternations).

", + "

The alternatives produced by the root branch constitute the final output.

", + "

Parsing the input string involves some additional complexity to deal with escaped characters and \"incomplete\" brace pairs:

", + "

", + "

", + "

", + "", + "

", + "

", + "

", + "
a\\\\{\\\\\\{b,c\\,d}

", + "

", + "

", + "

", + "

a\\\\

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

⎧⎨⎩

", + "

\\\\\\{b

", + "

⎫⎬⎭

", + "

c\\,d

", + "

", + "
{a,b{c{,{d}}e}f

", + "

", + "

", + "

", + "

", + "

{a,b{c

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

", + "

⎧⎨⎩

", + "

", + "

⎫⎬⎭

", + "

{d}

", + "

e}f

", + "
", + "

", + "

An unescaped backslash which precedes another character, escapes that character (to force it to be treated as literal). The backslashes are passed along to the output unchanged.

", + "

Balanced brace pairs are identified by, conceptually, going through the string from left to right and associating each unescaped closing brace that is encountered with the nearest still unassociated unescaped opening brace to its left (if any). Furthermore, each unescaped comma is associated with the innermost brace pair that contains it (if any). With that in mind:

", + "

Each brace pair that has at least one comma associated with it, forms an alternation (whose branches are the brace pair's contents split at its commas). The associated brace and comma characters themselves do not become part of the output.

", + "

Brace characters from pairs without any associated comma, as well as unassociated brace and comma characters, as well as all characters that are not covered by the preceding rules, are instead treated as literals.

", + "

For every possible input string, your implementation should produce exactly the output which this specification mandates. Please comply with this even when it's inconvenient, to ensure that all implementations are comparable. However, none of the above should be interpreted as instructions (or even recommendations) for how to implement it. Try to come up with a solution that is idiomatic in your programming language. (See #Perl for a reference implementation.)

", + "

{| style=\"white-space: nowrap;\"

", + "

|-

", + "

! Input(single string)

", + "

! Ouput(list/array of strings)

", + "

|- style=\"vertical-align:top\"

", + "

|

", + "

~/{Downloads,Pictures}/*.{jpg,gif,png}

", + "

|

", + "

~/Downloads/*.jpg

", + "

~/Downloads/*.gif

", + "

~/Downloads/*.png

", + "

~/Pictures/*.jpg

", + "

~/Pictures/*.gif

", + "

~/Pictures/*.png

", + "

|- style=\"vertical-align:top\"

", + "

|

", + "

It{{em,alic}iz,erat}e{d,}, please.

", + "

|

", + "

Itemized, please.

", + "

Itemize, please.

", + "

Italicized, please.

", + "

Italicize, please.

", + "

Iterated, please.

", + "

Iterate, please.

", + "

|- style=\"vertical-align:top\"

", + "

|

", + "

{,{,gotta have{ ,\\, again\\, }}more }cowbell!

", + "

|

", + "

cowbell!

", + "

more cowbell!

", + "

gotta have more cowbell!

", + "

gotta have\\, again\\, more cowbell!

", + "

|- style=\"vertical-align:top\"

", + "

|

", + "

{}} some }{,{\\\\{ edge, edge} \\,}{ cases, {here} \\\\\\\\\\}

", + "

|

", + "

{}} some }{,{\\\\ edge \\,}{ cases, {here} \\\\\\\\\\}

", + "

{}} some }{,{\\\\ edge \\,}{ cases, {here} \\\\\\\\\\}

", + "

|}

", + "


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5 Functional===", + "", + "Without importing Node.js libraries, JavaScript doesn't immediately have access to anything like Haskell's Parsec, but using a functional idiom of JavaScript, and emphasising clarity more than optimisation, we can separate out the tokenizing from the parsing, and the parsing from the generation of strings, to build a function which:", + ":#returns the set of expansions for each brace expression, and ", + ":#logs a pretty-printed abstract syntax tree for each expression to the console (in a JSON format).", + "", + "Each node of the parse tree consists of one of two simple functions (AND: syntagmatic concatenation, OR: flattening of paradigms) with a set of arguments, each of which may be a plain string or an AND or OR subtree. The expansions are derived by evaluating the parse tree as an expression.", + "", + "(function () {", + " 'use strict'", + "", + " // Index of any closing brace matching the opening brace at iPosn", + " // with the indices of any immediately-enclosed commas", + " function bracePair(tkns, iPosn, iNest, lstCommas) {", + " if (iPosn >= tkns.length || iPosn < 0) return null;", + "", + " var t = tkns[iPosn],", + " n = (t === '{') ? iNest + 1 : (t === '}' ? iNest - 1 : iNest),", + " lst = (t === ',' && iNest === 1) ? lstCommas.concat(iPosn) : lstCommas;", + "", + " return n ? bracePair(tkns, iPosn + 1, n, lst) : {", + " close: iPosn,", + " commas: lst", + " };", + " }", + "", + " // Parse of a SYNTAGM subtree", + " function andTree(dctSofar, tkns) {", + " if (!tkns.length) return [dctSofar, []];", + "", + " var dctParse = dctSofar ? dctSofar : {", + " fn: and,", + " args: []", + " },", + "", + " head = tkns[0],", + " tail = head ? tkns.slice(1) : [],", + "", + " dctBrace = head === '{' ? bracePair(", + " tkns, 0, 0, []", + " ) : null,", + "", + " lstOR = dctBrace && dctBrace.close && dctBrace.commas.length ? (", + " splitAt(dctBrace.close + 1, tkns)", + " ) : null;", + "", + " return andTree({", + " fn: and,", + " args: dctParse.args.concat(", + " lstOR ? orTree(dctParse, lstOR[0], dctBrace.commas) : head", + " )", + " }, lstOR ? lstOR[1] : tail);", + " }", + "", + " // Parse of a PARADIGM subtree", + " function orTree(dctSofar, tkns, lstCommas) {", + " if (!tkns.length) return [dctSofar, []];", + " var iLast = lstCommas.length;", + "", + " return {", + " fn: or,", + " args: splitsAt(", + " lstCommas, tkns", + " ).map(function (x, i) {", + " var ts = x.slice(1, i === iLast ? -1 : void 0);", + "", + " return ts.length ? ts : [''];", + " }).map(function (ts) {", + " return ts.length > 1 ? andTree(null, ts)[0] : ts[0];", + " })", + " };", + " }", + "", + " // List of unescaped braces and commas, and remaining strings", + " function tokens(str) {", + " // Filter function excludes empty splitting artefacts", + " var toS = function (x) {", + " return x.toString();", + " };", + "", + " return str.split(/(\\\\\\\\)/).filter(toS).reduce(function (a, s) {", + " return a.concat(s.charAt(0) === '\\\\' ? s : s.split(", + " /(\\\\*[{,}])/", + " ).filter(toS));", + " }, []);", + " }", + "", + " // PARSE TREE OPERATOR (1 of 2)", + " // Each possible head * each possible tail", + " function and(args) {", + " var lng = args.length,", + " head = lng ? args[0] : null,", + " lstHead = \"string\" === typeof head ? [head] : head;", + "", + " return lng ? (", + " 1 < lng ? lstHead.reduce(function (a, h) {", + " return a.concat(and(args.slice(1)).map(function (t) {", + " return h + t;", + " }));", + " }, []) : lstHead", + " ) : [];", + " }", + "", + " // PARSE TREE OPERATOR (2 of 2)", + " // Each option flattened", + " function or(args) {", + " return args.reduce(function (a, b) {", + " return a.concat(b);", + " }, []);", + " }", + "", + " // One list split into two (first sublist length n)", + " function splitAt(n, lst) {", + " return n < lst.length + 1 ? [lst.slice(0, n), lst.slice(n)] : [lst, []];", + " }", + "", + " // One list split into several (sublist lengths [n])", + " function splitsAt(lstN, lst) {", + " return lstN.reduceRight(function (a, x) {", + " return splitAt(x, a[0]).concat(a.slice(1));", + " }, [lst]);", + " }", + "", + " // Value of the parse tree", + " function evaluated(e) {", + " return typeof e === 'string' ? e :", + " e.fn(e.args.map(evaluated));", + " }", + "", + " // JSON prettyprint (for parse tree, token list etc)", + " function pp(e) {", + " return JSON.stringify(e, function (k, v) {", + " return typeof v === 'function' ? (", + " '[function ' + v.name + ']'", + " ) : v;", + " }, 2)", + " }", + "", + "", + " // MAIN", + "", + " // s -> [s]", + " function expansions(s) {", + " // BRACE EXPRESSION PARSED", + " var dctParse = andTree(null, tokens(s))[0];", + "", + " // ABSTRACT SYNTAX TREE LOGGED", + " console.log(pp(dctParse));", + "", + " // AST EVALUATED TO LIST OF STRINGS", + " return evaluated(dctParse);", + " }", + "", + "", + " // Sample expressions, double-escaped for quotation in source code.", + " var lstTests = [", + " '~/{Downloads,Pictures}/*.{jpg,gif,png}',", + " 'It{{em,alic}iz,erat}e{d,}, please.',", + " '{,{,gotta have{ ,\\\\, again\\\\, }}more }cowbell!',", + " '{}} some }{,{\\\\\\\\{ edge, edge} \\\\,}{ cases, {here} \\\\\\\\\\\\\\\\\\\\}'", + " ];", + "", + "", + " // 1. Return each expression with an indented list of its expansions, while", + " // 2. logging each parse tree to the console.log() stream", + "", + " return lstTests.map(function (s) {", + " return s + '\\n\\n' + expansions(s).map(function (x) {", + " return ' ' + x;", + " }).join('\\n');", + " }).join('\\n\\n');", + "", + "})();", + "", + "Value returned by function:", + "", + "
~/{Downloads,Pictures}/*.{jpg,gif,png}",
+      "",
+      "   ~/Downloads/*.jpg",
+      "   ~/Downloads/*.gif",
+      "   ~/Downloads/*.png",
+      "   ~/Pictures/*.jpg",
+      "   ~/Pictures/*.gif",
+      "   ~/Pictures/*.png",
+      "",
+      "It{{em,alic}iz,erat}e{d,}, please.",
+      "",
+      "   Itemized, please.",
+      "   Itemize, please.",
+      "   Italicized, please.",
+      "   Italicize, please.",
+      "   Iterated, please.",
+      "   Iterate, please.",
+      "",
+      "{,{,gotta have{ ,\\, again\\, }}more }cowbell!",
+      "",
+      "   cowbell!",
+      "   more cowbell!",
+      "   gotta have more cowbell!",
+      "   gotta have\\, again\\, more cowbell!",
+      "",
+      "{}} some }{,{\\\\{ edge, edge} \\,}{ cases, {here} \\\\\\\\\\}",
+      "",
+      "   {}} some }{,{\\\\ edge \\,}{ cases, {here} \\\\\\\\\\}",
+      "   {}} some }{,{\\\\ edge \\,}{ cases, {here} \\\\\\\\\\}
", + "", + "Sample of parse trees logged to the console:", + "", + "{", + " \"fn\": \"[function and]\",", + " \"args\": [", + " \"It\",", + " {", + " \"fn\": \"[function or]\",", + " \"args\": [", + " {", + " \"fn\": \"[function and]\",", + " \"args\": [", + " {", + " \"fn\": \"[function or]\",", + " \"args\": [", + " \"em\",", + " \"alic\"", + " ]", + " },", + " \"iz\"", + " ]", + " },", + " \"erat\"", + " ]", + " },", + " \"e\",", + " {", + " \"fn\": \"[function or]\",", + " \"args\": [", + " \"d\",", + " \"\"", + " ]", + " },", + " \",\",", + " \" please.\"", + " ]", + "}", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7db3", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function () {\n 'use strict'\n\n // Index of any closing brace matching the opening brace at iPosn\n // with the indices of any immediately-enclosed commas\n function bracePair(tkns, iPosn, iNest, lstCommas) {\n if (iPosn >= tkns.length || iPosn < 0) return null;\n\n var t = tkns[iPosn],\n n = (t === '{') ? iNest + 1 : (t === '}' ? iNest - 1 : iNest),\n lst = (t === ',' && iNest === 1) ? lstCommas.concat(iPosn) : lstCommas;\n\n return n ? bracePair(tkns, iPosn + 1, n, lst) : {\n close: iPosn,\n commas: lst\n };\n }\n\n // Parse of a SYNTAGM subtree\n function andTree(dctSofar, tkns) {\n if (!tkns.length) return [dctSofar, []];\n\n var dctParse = dctSofar ? dctSofar : {\n fn: and,\n args: []\n },\n\n head = tkns[0],\n tail = head ? tkns.slice(1) : [],\n\n dctBrace = head === '{' ? bracePair(\n tkns, 0, 0, []\n ) : null,\n\n lstOR = dctBrace && dctBrace.close && dctBrace.commas.length ? (\n splitAt(dctBrace.close + 1, tkns)\n ) : null;\n\n return andTree({\n fn: and,\n args: dctParse.args.concat(\n lstOR ? orTree(dctParse, lstOR[0], dctBrace.commas) : head\n )\n }, lstOR ? lstOR[1] : tail);\n }\n\n // Parse of a PARADIGM subtree\n function orTree(dctSofar, tkns, lstCommas) {\n if (!tkns.length) return [dctSofar, []];\n var iLast = lstCommas.length;\n\n return {\n fn: or,\n args: splitsAt(\n lstCommas, tkns\n ).map(function (x, i) {\n var ts = x.slice(1, i === iLast ? -1 : void 0);\n\n return ts.length ? ts : [''];\n }).map(function (ts) {\n return ts.length > 1 ? andTree(null, ts)[0] : ts[0];\n })\n };\n }\n\n // List of unescaped braces and commas, and remaining strings\n function tokens(str) {\n // Filter function excludes empty splitting artefacts\n var toS = function (x) {\n return x.toString();\n };\n\n return str.split(/(\\\\\\\\)/).filter(toS).reduce(function (a, s) {\n return a.concat(s.charAt(0) === '\\\\' ? s : s.split(\n /(\\\\*[{,}])/\n ).filter(toS));\n }, []);\n }\n\n // PARSE TREE OPERATOR (1 of 2)\n // Each possible head * each possible tail\n function and(args) {\n var lng = args.length,\n head = lng ? args[0] : null,\n lstHead = \"string\" === typeof head ? [head] : head;\n\n return lng ? (\n 1 < lng ? lstHead.reduce(function (a, h) {\n return a.concat(and(args.slice(1)).map(function (t) {\n return h + t;\n }));\n }, []) : lstHead\n ) : [];\n }\n\n // PARSE TREE OPERATOR (2 of 2)\n // Each option flattened\n function or(args) {\n return args.reduce(function (a, b) {\n return a.concat(b);\n }, []);\n }\n\n // One list split into two (first sublist length n)\n function splitAt(n, lst) {\n return n < lst.length + 1 ? [lst.slice(0, n), lst.slice(n)] : [lst, []];\n }\n\n // One list split into several (sublist lengths [n])\n function splitsAt(lstN, lst) {\n return lstN.reduceRight(function (a, x) {\n return splitAt(x, a[0]).concat(a.slice(1));\n }, [lst]);\n }\n\n // Value of the parse tree\n function evaluated(e) {\n return typeof e === 'string' ? e :\n e.fn(e.args.map(evaluated));\n }\n\n // JSON prettyprint (for parse tree, token list etc)\n function pp(e) {\n return JSON.stringify(e, function (k, v) {\n return typeof v === 'function' ? (\n '[function ' + v.name + ']'\n ) : v;\n }, 2)\n }\n\n\n // MAIN\n\n // s -> [s]\n function expansions(s) {\n // BRACE EXPRESSION PARSED\n var dctParse = andTree(null, tokens(s))[0];\n\n // ABSTRACT SYNTAX TREE LOGGED\n console.log(pp(dctParse));\n\n // AST EVALUATED TO LIST OF STRINGS\n return evaluated(dctParse);\n }\n\n\n // Sample expressions, double-escaped for quotation in source code.\n var lstTests = [\n '~/{Downloads,Pictures}/*.{jpg,gif,png}',\n 'It{{em,alic}iz,erat}e{d,}, please.',\n '{,{,gotta have{ ,\\\\, again\\\\, }}more }cowbell!',\n '{}} some }{,{\\\\\\\\{ edge, edge} \\\\,}{ cases, {here} \\\\\\\\\\\\\\\\\\\\}'\n ];\n\n\n // 1. Return each expression with an indented list of its expansions, while\n // 2. logging each parse tree to the console.log() stream\n\n return lstTests.map(function (s) {\n return s + '\\n\\n' + expansions(s).map(function (x) {\n return ' ' + x;\n }).join('\\n');\n }).join('\\n\\n');\n\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Cartesian product of two or more lists", + "type": "Waypoint", + "description": [ + "Task:", + "

Show one or more idiomatic ways of generating the Cartesian product of two arbitrary lists in your language.

Demonstrate that your function/method correctly returns:

", + "

:{1, 2} × {3, 4} = {(1, 3), (1, 4), (2, 3), (2, 4)}

and, in contrast:

", + "

:{3, 4} × {1, 2} = {(3, 1), (3, 2), (4, 1), (4, 2)}

Also demonstrate, using your function/method, that the product of an empty list with any other list is empty.

", + "

: {1, 2} × {} = {}

", + "

: {} × {1, 2} = {}

For extra credit, show or write a function returning the n-ary product of an arbitrary number of lists, each of arbitrary length. Your function might, for example, accept a single argument which is itself a list of lists, and return the n-ary product of those lists.

Use your n-ary Cartesian product function to show the following products:

", + "

: {1776, 1789} × {7, 12} × {4, 14, 23} × {0, 1}

", + "

: {1, 2, 3} × {30} × {500, 100}

", + "

: {1, 2, 3} × {} × {500, 100}

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "====Functional====", + "Cartesian products fall quite naturally out of '''concatMap''', and its argument-flipped twin '''bind'''.", + "", + "For the Cartesian product of just two lists:", + "(() => {", + "", + " // CARTESIAN PRODUCT OF TWO LISTS -----------------------------------------", + "", + " // cartProd :: [a] -> [b] -> [[a, b]]", + " const cartProd = (xs, ys) =>", + " concatMap((x => concatMap(y => [", + " [x, y]", + " ], ys)), xs);", + "", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x); //, null, 2);", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // TEST -------------------------------------------------------------------", + " return unlines(map(show, [", + " cartProd([1, 2], [3, 4]),", + " cartProd([3, 4], [1, 2]),", + " cartProd([1, 2], []),", + " cartProd([], [1, 2]),", + " ]));", + "})();", + "{{Out}}", + "
[[1,3],[1,4],[2,3],[2,4]]",
+      "[[3,1],[3,2],[4,1],[4,2]]",
+      "[]",
+      "[]
", + "", + "For the n-ary Cartesian product over a list of lists:", + "(() => {", + " // n-ary Cartesian product of a list of lists", + "", + " // cartProdN :: [[a]] -> [[a]]", + " const cartProdN = lists =>", + " foldr((as, xs) =>", + " bind(xs, x => bind(as, a => [x.concat(a)])), [", + " []", + " ], lists);", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // bind :: [a] -> (a -> [b]) -> [b]", + " const bind = (xs, f) => [].concat.apply([], xs.map(f));", + "", + " // foldr (a -> b -> b) -> b -> [a] -> b", + " const foldr = (f, a, xs) => xs.reduceRight(f, a);", + "", + " // intercalate :: String -> [a] -> String", + " const intercalate = (s, xs) => xs.join(s);", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x);", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // TEST -------------------------------------------------------------------", + " return intercalate('\\n\\n', [unlines(map(show, cartProdN([", + " [1776, 1789],", + " [7, 12],", + " [4, 14, 23],", + " [0, 1]", + " ]))),", + " show(cartProdN([", + " [1, 2, 3],", + " [30],", + " [50, 100]", + " ])),", + " show(cartProdN([", + " [1, 2, 3],", + " [],", + " [50, 100]", + " ]))", + " ])", + "})();", + "{{Out}}", + "
[1776,7,4,0]",
+      "[1776,7,4,1]",
+      "[1776,7,14,0]",
+      "[1776,7,14,1]",
+      "[1776,7,23,0]",
+      "[1776,7,23,1]",
+      "[1776,12,4,0]",
+      "[1776,12,4,1]",
+      "[1776,12,14,0]",
+      "[1776,12,14,1]",
+      "[1776,12,23,0]",
+      "[1776,12,23,1]",
+      "[1789,7,4,0]",
+      "[1789,7,4,1]",
+      "[1789,7,14,0]",
+      "[1789,7,14,1]",
+      "[1789,7,23,0]",
+      "[1789,7,23,1]",
+      "[1789,12,4,0]",
+      "[1789,12,4,1]",
+      "[1789,12,14,0]",
+      "[1789,12,14,1]",
+      "[1789,12,23,0]",
+      "[1789,12,23,1]",
+      "",
+      "[[1,30,50],[1,30,100],[2,30,50],[2,30,100],[3,30,50],[3,30,100]]",
+      "",
+      "[]
", + "", + "====Imperative====", + "Imperative implementations of Cartesian products are inevitably less compact and direct, but we can certainly write an iterative translation of a fold over nested applications of '''bind''' or '''concatMap''':", + "", + "(() => {", + " // n-ary Cartesian product of a list of lists", + " // ( Imperative implementation )", + "", + " // cartProd :: [a] -> [b] -> [[a, b]]", + " const cartProd = lists => {", + " let ps = [],", + " acc = [", + " []", + " ],", + " i = lists.length;", + " while (i--) {", + " let subList = lists[i],", + " j = subList.length;", + " while (j--) {", + " let x = subList[j],", + " k = acc.length;", + " while (k--) ps.push([x].concat(acc[k]))", + " };", + " acc = ps;", + " ps = [];", + " };", + " return acc.reverse();", + " };", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // intercalate :: String -> [a] -> String", + " const intercalate = (s, xs) => xs.join(s);", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x);", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // TEST -------------------------------------------------------------------", + " return intercalate('\\n\\n', [show(cartProd([", + " [1, 2],", + " [3, 4]", + " ])),", + " show(cartProd([", + " [3, 4],", + " [1, 2]", + " ])),", + " show(cartProd([", + " [1, 2],", + " []", + " ])),", + " show(cartProd([", + " [],", + " [1, 2]", + " ])),", + " unlines(map(show, cartProd([", + " [1776, 1789],", + " [7, 12],", + " [4, 14, 23],", + " [0, 1]", + " ]))),", + " show(cartProd([", + " [1, 2, 3],", + " [30],", + " [50, 100]", + " ])),", + " show(cartProd([", + " [1, 2, 3],", + " [],", + " [50, 100]", + " ]))", + " ]);", + "})();", + "{{Out}}", + "
[[1,4],[1,3],[2,4],[2,3]]",
+      "",
+      "[[3,2],[3,1],[4,2],[4,1]]",
+      "",
+      "[]",
+      "",
+      "[]",
+      "",
+      "[1776,12,4,1]",
+      "[1776,12,4,0]",
+      "[1776,12,14,1]",
+      "[1776,12,14,0]",
+      "[1776,12,23,1]",
+      "[1776,12,23,0]",
+      "[1776,7,4,1]",
+      "[1776,7,4,0]",
+      "[1776,7,14,1]",
+      "[1776,7,14,0]",
+      "[1776,7,23,1]",
+      "[1776,7,23,0]",
+      "[1789,12,4,1]",
+      "[1789,12,4,0]",
+      "[1789,12,14,1]",
+      "[1789,12,14,0]",
+      "[1789,12,23,1]",
+      "[1789,12,23,0]",
+      "[1789,7,4,1]",
+      "[1789,7,4,0]",
+      "[1789,7,14,1]",
+      "[1789,7,14,0]",
+      "[1789,7,23,1]",
+      "[1789,7,23,0]",
+      "",
+      "[[1,30,50],[1,30,100],[2,30,50],[2,30,100],[3,30,50],[3,30,100]]",
+      "",
+      "[]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7dc1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n\n // CARTESIAN PRODUCT OF TWO LISTS -----------------------------------------\n\n // cartProd :: [a] -> [b] -> [[a, b]]\n const cartProd = (xs, ys) =>\n concatMap((x => concatMap(y => [\n [x, y]\n ], ys)), xs);\n\n\n // GENERIC FUNCTIONS ------------------------------------------------------\n\n // concatMap :: (a -> [b]) -> [a] -> [b]\n const concatMap = (f, xs) => [].concat.apply([], xs.map(f));\n\n // map :: (a -> b) -> [a] -> [b]\n const map = (f, xs) => xs.map(f);\n\n // show :: a -> String\n const show = x => JSON.stringify(x); //, null, 2);\n\n // unlines :: [String] -> String\n const unlines = xs => xs.join('\\n');\n\n // TEST -------------------------------------------------------------------\n return unlines(map(show, [\n cartProd([1, 2], [3, 4]),\n cartProd([3, 4], [1, 2]),\n cartProd([1, 2], []),\n cartProd([], [1, 2]),\n ]));\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Casting out nines", + "type": "Waypoint", + "description": [ + "Task (in three parts):", + "Part 1", + "

Write a procedure (say $\\mathit{co9}(x)$) which implements Casting Out Nines as described by returning the checksum for $x$. Demonstrate the procedure using the examples given there, or others you may consider lucky.

Part 2", + "

Notwithstanding past Intel microcode errors, checking computer calculations like this would not be sensible. To find a computer use for your procedure:

", + "

Consider the statement \"318682 is 101558 + 217124 and squared is 101558217124\" (see: Kaprekar numbers#Casting Out Nines (fast)).

", + "

note that $318682$ has the same checksum as ($101558 + 217124$);

", + "

note that $101558217124$ has the same checksum as ($101558 + 217124$) because for a Kaprekar they are made up of the same digits (sometimes with extra zeroes);

", + "

note that this implies that for Kaprekar numbers the checksum of $k$ equals the checksum of $k^2$.

Demonstrate that your procedure can be used to generate or filter a range of numbers with the property $\\mathit{co9}(k) = \\mathit{co9}(k^2)$ and show that this subset is a small proportion of the range and contains all the Kaprekar in the range.

Part 3", + "

Considering this MathWorld page, produce a efficient algorithm based on the more mathematical treatment of Casting Out Nines, and realizing:

", + "

$\\mathit{co9}(x)$ is the residual of $x$ mod $9$;

", + "

the procedure can be extended to bases other than 9.

Demonstrate your algorithm by generating or filtering a range of numbers with the property $k%(\\mathit{Base}-1) == (k^2)%(\\mathit{Base}-1)$ and show that this subset is a small proportion of the range and contains all the Kaprekar in the range.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "Assuming the context of a web page:", + "function main(s, e, bs, pbs) {", + " bs = bs || 10;", + " pbs = pbs || 10", + " document.write('start:', toString(s), ' end:', toString(e),", + " ' base:', bs, ' printBase:', pbs)", + " document.write('
castOutNine: ');", + " castOutNine()", + " document.write('
kaprekar: ');", + " kaprekar()", + " document.write('

')", + "", + " function castOutNine() {", + " for (var n = s, k = 0, bsm1 = bs - 1; n <= e; n += 1)", + " if (n % bsm1 == (n * n) % bsm1) k += 1,", + " document.write(toString(n), ' ')", + " document.write('
trying ', k, ' numbers instead of ', n = e - s + 1,", + " ' numbers saves ', (100 - k / n * 100)", + " .toFixed(3), '%')", + " }", + "", + " function kaprekar() {", + " for (var n = s; n <= e; n += 1)", + " if (isKaprekar(n)) document.write(toString(n), ' ')", + "", + " function isKaprekar(n) {", + " if (n < 1) return false", + " if (n == 1) return true", + " var s = (n * n)", + " .toString(bs)", + " for (var i = 1, e = s.length; i < e; i += 1) {", + " var a = parseInt(s.substr(0, i), bs)", + " var b = parseInt(s.substr(i), bs)", + " if (b && a + b == n) return true", + " }", + " return false", + " }", + " }", + "", + " function toString(n) {", + " return n.toString(pbs)", + " .toUpperCase()", + " }", + "}", + "main(1, 10 * 10 - 1)", + "main(1, 16 * 16 - 1, 16)", + "main(1, 17 * 17 - 1, 17)", + "main(parseInt('10', 17), parseInt('gg', 17), 17, 17)
", + "{{Out}}", + "
start:1 end:99 base:10 printBase:10",
+      "castOutNine: 1 9 10 18 19 27 28 36 37 45 46 54 55 63 64 72 73 81 82 90 91 99 ",
+      "trying 22 numbers instead of 99 numbers saves 77.778%",
+      "kaprekar: 1 9 45 55 99 ",
+      "",
+      "start:1 end:255 base:16 printBase:10",
+      "castOutNine: 1 6 10 15 16 21 25 30 31 36 40 45 46 51 55 60 61 66 70 75 76 81 85 90 91 96 100 105 106 111 115 120 121 126 130 135 136",
+      "141 145 150 151 156 160 165 166 171 175 180 181 186 190 195 196 201 205 210 211 216 220 225 226 231 235 240 241 246 250 255 ",
+      "trying 68 numbers instead of 255 numbers saves 73.333%",
+      "kaprekar: 1 6 10 15 51 85 91 120 136 171 205 255 ",
+      "",
+      "start:1 end:288 base:17 printBase:10",
+      "castOutNine: 1 16 17 32 33 48 49 64 65 80 81 96 97 112 113 128 129 144 145 160 161 176 177 192 193 208 209 224 225 240 241 256 257 272 273 288 ",
+      "trying 36 numbers instead of 288 numbers saves 87.500%",
+      "kaprekar: 1 16 64 225 288 ",
+      "",
+      "start:10 end:GG base:17 printBase:17",
+      "castOutNine: 10 1F 1G 2E 2F 3D 3E 4C 4D 5B 5C 6A 6B 79 7A 88 89 97 98 A6 A7 B5 B6 C4 C5 D3 D4 E2 E3 F1 F2 G0 G1 GG ",
+      "trying 34 numbers instead of 272 numbers saves 87.500%",
+      "kaprekar: 3D D4 GG 
", + "", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // co9 :: Int -> Int", + " const co9 = n =>", + " n <= 8 ? n : co9(", + " digits(10, n)", + " .reduce((a, x) => x !== 9 ? a + x : a, 0)", + " );", + "", + " // GENERIC FUNCTIONS", + "", + " // digits :: Int -> Int -> [Int]", + " const digits = (base, n) => {", + " if (n < base) return [n];", + " const [q, r] = quotRem(n, base);", + " return [r].concat(digits(base, q));", + " };", + "", + " // quotRem :: Integral a => a -> a -> (a, a)", + " const quotRem = (m, n) => [Math.floor(m / n), m % n];", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // squared :: Num a => a -> a", + " const squared = n => Math.pow(n, 2);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x, null, 2);", + "", + " // TESTS", + " return show({", + " test1: co9(232345), //-> 1", + " test2: co9(34234234), //-> 7", + " test3: co9(232345 + 34234234) === co9(232345) + co9(34234234), //-> true", + " test4: co9(232345 * 34234234) === co9(232345) * co9(34234234), //-> true,", + " task2: range(1, 100)", + " .filter(n => co9(n) === co9(squared(n))),", + " task3: (k => range(1, 100)", + " .filter(n => (n % k) === (squared(n) % k)))(16)", + " });", + "})();", + "{{Out}}", + "
{",
+      "  \"test1\": 1,",
+      "  \"test2\": 7,",
+      "  \"test3\": true,",
+      "  \"test4\": true,",
+      "  \"task2\": [",
+      "    1,",
+      "    9,",
+      "    10,",
+      "    18,",
+      "    19,",
+      "    27,",
+      "    28,",
+      "    36,",
+      "    37,",
+      "    45,",
+      "    46,",
+      "    54,",
+      "    55,",
+      "    63,",
+      "    64,",
+      "    72,",
+      "    73,",
+      "    81,",
+      "    82,",
+      "    90,",
+      "    91,",
+      "    99,",
+      "    100",
+      "  ],",
+      "  \"task3\": [",
+      "    1,",
+      "    16,",
+      "    17,",
+      "    32,",
+      "    33,",
+      "    48,",
+      "    49,",
+      "    64,",
+      "    65,",
+      "    80,",
+      "    81,",
+      "    96,",
+      "    97",
+      "  ]",
+      "}
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7dc3", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function main(s, e, bs, pbs) {\n bs = bs || 10;\n pbs = pbs || 10\n document.write('start:', toString(s), ' end:', toString(e),\n ' base:', bs, ' printBase:', pbs)\n document.write('
castOutNine: ');\n castOutNine()\n document.write('
kaprekar: ');\n kaprekar()\n document.write('

')\n\n function castOutNine() {\n for (var n = s, k = 0, bsm1 = bs - 1; n <= e; n += 1)\n if (n % bsm1 == (n * n) % bsm1) k += 1,\n document.write(toString(n), ' ')\n document.write('
trying ', k, ' numbers instead of ', n = e - s + 1,\n ' numbers saves ', (100 - k / n * 100)\n .toFixed(3), '%')\n }\n\n function kaprekar() {\n for (var n = s; n <= e; n += 1)\n if (isKaprekar(n)) document.write(toString(n), ' ')\n\n function isKaprekar(n) {\n if (n < 1) return false\n if (n == 1) return true\n var s = (n * n)\n .toString(bs)\n for (var i = 1, e = s.length; i < e; i += 1) {\n var a = parseInt(s.substr(0, i), bs)\n var b = parseInt(s.substr(i), bs)\n if (b && a + b == n) return true\n }\n return false\n }\n }\n\n function toString(n) {\n return n.toString(pbs)\n .toUpperCase()\n }\n}\nmain(1, 10 * 10 - 1)\nmain(1, 16 * 16 - 1, 16)\nmain(1, 17 * 17 - 1, 17)\nmain(parseInt('10', 17), parseInt('gg', 17), 17, 17)\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Combinations with repetitions", + "type": "Waypoint", + "description": [ + "

The set of combinations with repetitions is computed from a set, $S$ (of cardinality $n$), and a size of resulting selection, $k$, by reporting the sets of cardinality $k$ where each member of those sets is chosen from $S$.

", + "

In the real world, it is about choosing sets where there is a “large” supply of each type of element and where the order of choice does not matter.

", + "

For example:

", + "

Q: How many ways can a person choose two doughnuts from a store selling three types of doughnut: iced, jam, and plain? (i.e., $S$ is $\\{\\mathrm{iced}, \\mathrm{jam}, \\mathrm{plain}\\}$, $|S| = 3$, and $k = 2$.)

A: 6: {iced, iced}; {iced, jam}; {iced, plain}; {jam, jam}; {jam, plain}; {plain, plain}.

Note that both the order of items within a pair, and the order of the pairs given in the answer is not significant; the pairs represent multisets.

", + "Also note that doughnut can also be spelled donut. ", + "Task:", + "Write a function/program/routine/.. to generate all the combinations with repetitions of $n$ types of things taken $k$ at a time and use it to show an answer to the doughnut example above.", + "For extra credit, use the function to compute and show just the number of ways of choosing three doughnuts from a choice of ten types of doughnut. Do not show the individual choices for this part.References:", + "k-combination with repetitionsSee also:" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Imperative====", + "Donuts", + "
", + "{{out}}", + "
iced iced",
+      "iced jam",
+      "iced plain",
+      "jam jam",
+      "jam plain",
+      "plain plain",
+      "6 combos",
+      "pick 3 out of 10: 220 combos
", + "", + "====Functional====", + "(function () {", + "", + " // n -> [a] -> [[a]]", + " function combsWithRep(n, lst) {", + " return n ? (", + " lst.length ? combsWithRep(n - 1, lst).map(function (t) {", + " return [lst[0]].concat(t);", + " }).concat(combsWithRep(n, lst.slice(1))) : []", + " ) : [[]];", + " };", + "", + " // If needed, we can derive a significantly faster version of", + " // the simple recursive function above by memoizing it", + "", + " // f -> f", + " function memoized(fn) {", + " m = {};", + " return function (x) {", + " var args = [].slice.call(arguments),", + " strKey = args.join('-');", + "", + " v = m[strKey];", + " if ('u' === (typeof v)[0])", + " m[strKey] = v = fn.apply(null, args);", + " return v;", + " }", + " }", + "", + " // [m..n]", + " function range(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(function (x, i) {", + " return m + i;", + " });", + " }", + "", + "", + " return [", + "", + " combsWithRep(2, [\"iced\", \"jam\", \"plain\"]),", + "", + " // obtaining and applying a memoized version of the function", + " memoized(combsWithRep)(3, range(1, 10)).length", + " ];", + "", + "})();", + "", + "{{Out}}", + "", + "[", + " [[\"iced\", \"iced\"], [\"iced\", \"jam\"], [\"iced\", \"plain\"],", + " [\"jam\", \"jam\"], [\"jam\", \"plain\"], [\"plain\", \"plain\"]],", + " 220", + "]", + "", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // COMBINATIONS WITH REPETITIONS -------------------------------------------", + "", + " // combsWithRep :: Int -> [a] -> [[a]]", + " const combsWithRep = (k, xs) => {", + " const comb = (n, ys) => {", + " if (0 === n) return ys;", + " if (isNull(ys)) return comb(n - 1, map(pure, xs));", + "", + " return comb(n - 1, concatMap(zs => {", + " const h = head(zs);", + " return map(x => [x].concat(zs), dropWhile(x => x !== h, xs));", + " }, ys));", + " };", + " return comb(k, []);", + " };", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // dropWhile :: (a -> Bool) -> [a] -> [a]", + " const dropWhile = (p, xs) => {", + " let i = 0;", + " for (let lng = xs.length;", + " (i < lng) && p(xs[i]); i++) {}", + " return xs.slice(i);", + " };", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " const enumFromTo = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // head :: [a] -> Maybe a", + " const head = xs => xs.length ? xs[0] : undefined;", + "", + " // isNull :: [a] -> Bool", + " const isNull = xs => (xs instanceof Array) ? xs.length < 1 : undefined;", + "", + " // length :: [a] -> Int", + " const length = xs => xs.length;", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // pure :: a -> [a]", + " const pure = x => [x];", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x, null, 2);", + "", + " // TEST -------------------------------------------------------------------", + " return show({", + " twoFromThree: combsWithRep(2, ['iced', 'jam', 'plain']),", + " threeFromTen: length(combsWithRep(3, enumFromTo(0, 9)))", + " });", + "})();", + "{{Out}}", + "
{",
+      "  \"twoFromThree\": [",
+      "    [",
+      "      \"iced\",",
+      "      \"iced\"",
+      "    ],",
+      "    [",
+      "      \"jam\",",
+      "      \"iced\"",
+      "    ],",
+      "    [",
+      "      \"plain\",",
+      "      \"iced\"",
+      "    ],",
+      "    [",
+      "      \"jam\",",
+      "      \"jam\"",
+      "    ],",
+      "    [",
+      "      \"plain\",",
+      "      \"jam\"",
+      "    ],",
+      "    [",
+      "      \"plain\",",
+      "      \"plain\"",
+      "    ]",
+      "  ],",
+      "  \"threeFromTen\": 220",
+      "}
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ddd", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "Donuts\n
\n"
+    ],
+    "betaTests": [
+      "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');"
+    ]
+  },
+  {
+    "title": "Conway's Game of Life",
+    "type": "Waypoint",
+    "description": [
+      "

The Game of Life is a cellular automaton devised by the British mathematician John Horton Conway in 1970. It is the best-known example of a cellular automaton.

Conway's game of life is described here:

A cell C is represented by a 1 when alive, or 0 when dead, in an m-by-m (or m×m) square array of cells.

We calculate N - the sum of live cells in C's eight-location neighbourhood, then cell C is alive or dead in the next generation based on the following table:

", + "

C N new C

", + "

1 0,1 -> 0 # Lonely

", + "

1 4,5,6,7,8 -> 0 # Overcrowded

", + "

1 2,3 -> 1 # Lives

", + "

0 3 -> 1 # It takes three to give birth!

", + "

0 0,1,2,4,5,6,7,8 -> 0 # Barren

Assume cells beyond the boundary are always dead.

The \"game\" is actually a zero-player game, meaning that its evolution is determined by its initial state, needing no input from human players. One interacts with the Game of Life by creating an initial configuration and observing how it evolves.

", + "Task:", + "

Although you should test your implementation on more complex examples such as the glider in a larger universe, show the action of the blinker (three adjoining cells in a row all alive), over three generations, in a 3 by 3 grid.

", + "References:", + " Its creator John Conway, explains the game of life. Video from numberphile on youtube.", + " John Conway Inventing Game of Life - Numberphile video.See also:", + " Langton's ant - another well known cellular automaton." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|SpiderMonkey}}", + "{{works with|V8}}", + "function GameOfLife () {", + "", + "\tthis.init = function (turns,width,height) {", + "\t\tthis.board = new Array(height);", + "\t\tfor (var x = 0; x < height; x++) {", + "\t\t\tthis.board[x] = new Array(width);", + "\t\t\tfor (var y = 0; y < width; y++) {", + "\t\t\t\tthis.board[x][y] = Math.round(Math.random());", + "\t\t\t}", + "\t\t}", + "\t\tthis.turns = turns;", + "\t}", + "", + "\tthis.nextGen = function() {", + "\t\tthis.boardNext = new Array(this.board.length);", + "\t\tfor (var i = 0; i < this.board.length; i++) {", + "\t\t\tthis.boardNext[i] = new Array(this.board[i].length);", + "\t\t}", + "\t\tfor (var x = 0; x < this.board.length; x++) {", + "\t\t\tfor (var y = 0; y < this.board[x].length; y++) {", + "\t\t\t\tvar n = 0;", + "\t\t\t\tfor (var dx = -1; dx <= 1; dx++) {", + "\t\t\t\t\tfor (var dy = -1; dy <= 1; dy++) {", + "\t\t\t\t\t\tif ( dx == 0 && dy == 0){}", + "\t\t\t\t\t\telse if (typeof this.board[x+dx] !== 'undefined'", + "\t\t\t\t\t\t\t\t&& typeof this.board[x+dx][y+dy] !== 'undefined'", + "\t\t\t\t\t\t\t\t&& this.board[x+dx][y+dy]) {", + "\t\t\t\t\t\t\tn++;", + "\t\t\t\t\t\t}", + "\t\t\t\t\t}\t", + "\t\t\t\t}", + "\t\t\t\tvar c = this.board[x][y];", + "\t\t\t\tswitch (n) {", + "\t\t\t\t\tcase 0:", + "\t\t\t\t\tcase 1:", + "\t\t\t\t\t\tc = 0;", + "\t\t\t\t\t\tbreak;", + "\t\t\t\t\tcase 2:", + "\t\t\t\t\t\tbreak; ", + "\t\t\t\t\tcase 3:", + "\t\t\t\t\t\tc = 1;", + "\t\t\t\t\t\tbreak;", + "\t\t\t\t\tdefault:", + "\t\t\t\t\t\tc = 0;", + "\t\t\t\t}", + "\t\t\t\tthis.boardNext[x][y] = c;", + "\t\t\t}", + "\t\t}", + "\t\tthis.board = this.boardNext.slice();", + "\t}", + "", + "\tthis.print = function() {", + "\t\tfor (var x = 0; x < this.board.length; x++) {", + "\t\t\tvar l = \"\";", + "\t\t\tfor (var y = 0; y < this.board[x].length; y++) {", + "\t\t\t\tif (this.board[x][y])", + "\t\t\t\t\tl += \"X\";", + "\t\t\t\telse", + "\t\t\t\t\tl += \" \";", + "\t\t\t}", + "\t\t\tprint(l);", + "\t\t}", + "\t}", + "", + "\tthis.start = function() {", + "\t\tfor (var t = 0; t < this.turns; t++) {", + "\t\t\tprint(\"---\\nTurn \"+(t+1));", + "\t\t\tthis.print();", + "\t\t\tthis.nextGen()", + "\t\t}", + "\t}", + "", + "}", + "", + "", + "var game = new GameOfLife();", + "", + "print(\"---\\n3x3 Blinker over three turns.\");", + "game.init(3);", + "game.board = [", + "\t[0,0,0],", + "\t[1,1,1],", + "\t[0,0,0]];", + "game.start();", + "", + "print(\"---\\n10x6 Glider over five turns.\");", + "game.init(5);", + "game.board = [", + "\t[0,0,0,0,0,0,0,0,0,0],", + "\t[0,0,1,0,0,0,0,0,0,0],", + "\t[0,0,0,1,0,0,0,0,0,0],", + "\t[0,1,1,1,0,0,0,0,0,0],", + "\t[0,0,0,0,0,0,0,0,0,0],", + "\t[0,0,0,0,0,0,0,0,0,0]];", + "game.start();", + "", + "print(\"---\\nRandom 5x10\");", + "game.init(5,5,10);", + "game.start();", + "{{out}}", + "
---",
+      "3x3 Blinker over three turns.",
+      "---",
+      "Turn 1",
+      "   ",
+      "XXX",
+      "   ",
+      "---",
+      "Turn 2",
+      " X ",
+      " X ",
+      " X ",
+      "---",
+      "Turn 3",
+      "   ",
+      "XXX",
+      "   ",
+      "---",
+      "10x6 Glider over five turns.",
+      "---",
+      "Turn 1",
+      "          ",
+      "  X       ",
+      "   X      ",
+      " XXX      ",
+      "          ",
+      "          ",
+      "---",
+      "Turn 2",
+      "          ",
+      "          ",
+      " X X      ",
+      "  XX      ",
+      "  X       ",
+      "          ",
+      "---",
+      "Turn 3",
+      "          ",
+      "          ",
+      "   X      ",
+      " X X      ",
+      "  XX      ",
+      "          ",
+      "---",
+      "Turn 4",
+      "          ",
+      "          ",
+      "  X       ",
+      "   XX     ",
+      "  XX      ",
+      "          ",
+      "---",
+      "Turn 5",
+      "          ",
+      "          ",
+      "   X      ",
+      "    X     ",
+      "  XXX     ",
+      "          ",
+      "---",
+      "Random 5x10",
+      "---",
+      "Turn 1",
+      "XXXX ",
+      "   XX",
+      "X    ",
+      " XX X",
+      "  XX ",
+      "X   X",
+      "X    ",
+      "X   X",
+      " X   ",
+      "X  XX",
+      "---",
+      "Turn 2",
+      " XXXX",
+      "X  XX",
+      " XX X",
+      " XX  ",
+      "  X X",
+      " X X ",
+      "XX   ",
+      "XX   ",
+      "XX XX",
+      "     ",
+      "---",
+      "Turn 3",
+      " XX X",
+      "X    ",
+      "X   X",
+      "     ",
+      "     ",
+      "XX X ",
+      "     ",
+      "     ",
+      "XXX  ",
+      "     ",
+      "---",
+      "Turn 4",
+      " X   ",
+      "X  X ",
+      "     ",
+      "     ",
+      "     ",
+      "     ",
+      "     ",
+      " X   ",
+      " X   ",
+      " X   ",
+      "---",
+      "Turn 5",
+      "     ",
+      "     ",
+      "     ",
+      "     ",
+      "     ",
+      "     ",
+      "     ",
+      "     ",
+      "XXX  ",
+      "     
", + "{{libheader|HTML5}}", + "Essentially the same as the above straight [[JavaScript]] but displayed in an [[HTML5]] Canvas.", + "", + " ", + "\t ", + "\t\t ", + "\t\t ", + "\t ", + "\t ", + "\t\t3x3 Blinker
", + "\t\t ", + "\t\t\tNo canvas support found!", + "\t\t

", + "\t\t6x6 Glider
", + "\t\t ", + "\t\t\tNo canvas support found!", + "\t\t

", + "\t\t8x8 Random
", + "\t\t ", + "\t\t\tNo canvas support found!", + "\t\t
", + "\t ", + "
", + "{{out}} for 3x3 Blinker:", + "", + "[[File:Blinker.gif]]", + "", + "", + "'''More functional style''':", + "", + "const _ = require('lodash');", + "", + "///////////////////", + "// LODASH IMPORT //", + "///////////////////", + "", + "// import all lodash functions to the main namespace, but isNaN not to cause conflicts", + "_.each(_.keys(_), k => global[k === 'isNaN' ? '_isNaN' : k] = _[k]);", + "", + "///////////////", + "// FUNCTIONS //", + "///////////////", + "const WORLD_WIDTH = 3,", + " WORLD_HEIGHT = 3,", + " displayWorld = (world) => console.log(map(world, x => x.join(' ')).join('\\n') + '\\n'),", + "", + " aliveNeighbours = (world, x, y) => chain(range(-1, 2))", + " .reduce((acc, i) => acc.concat(map(range(-1, 2), ii => [i, ii])), [])", + " .reject(partial(isEqual, [0, 0]))", + " .map(i => {", + " try {", + " return world[x + i[0]][y + i[1]];", + " } catch (err) {", + " return null;", + " }", + " })", + " .compact()", + " .value()", + " .length,", + "", + " isAlive = (cell, numAliveNeighbours) => (cell === 1 && inRange(numAliveNeighbours, 2, 4)) || (cell === 0 && numAliveNeighbours === 3) ? 1 : 0,", + " updateWorld = (world) => map(world, (row, rowidx) => map(row, (cell, colidx) => isAlive(cell, aliveNeighbours(world, rowidx, colidx))));", + "", + "", + "// let world = map(range(WORLD_WIDTH), partial(ary(map, 2), range(WORLD_HEIGHT), partial(random, 0, 1, false)));", + "let world = [[0, 0, 0], [1, 1, 1], [0, 0, 0]];", + "", + "setInterval(() => {", + " world = updateWorld(world)", + " displayWorld(world);", + "}, 1000);", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7df4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function GameOfLife () {\n\n\tthis.init = function (turns,width,height) {\n\t\tthis.board = new Array(height);\n\t\tfor (var x = 0; x < height; x++) {\n\t\t\tthis.board[x] = new Array(width);\n\t\t\tfor (var y = 0; y < width; y++) {\n\t\t\t\tthis.board[x][y] = Math.round(Math.random());\n\t\t\t}\n\t\t}\n\t\tthis.turns = turns;\n\t}\n\n\tthis.nextGen = function() {\n\t\tthis.boardNext = new Array(this.board.length);\n\t\tfor (var i = 0; i < this.board.length; i++) {\n\t\t\tthis.boardNext[i] = new Array(this.board[i].length);\n\t\t}\n\t\tfor (var x = 0; x < this.board.length; x++) {\n\t\t\tfor (var y = 0; y < this.board[x].length; y++) {\n\t\t\t\tvar n = 0;\n\t\t\t\tfor (var dx = -1; dx <= 1; dx++) {\n\t\t\t\t\tfor (var dy = -1; dy <= 1; dy++) {\n\t\t\t\t\t\tif ( dx == 0 && dy == 0){}\n\t\t\t\t\t\telse if (typeof this.board[x+dx] !== 'undefined'\n\t\t\t\t\t\t\t\t&& typeof this.board[x+dx][y+dy] !== 'undefined'\n\t\t\t\t\t\t\t\t&& this.board[x+dx][y+dy]) {\n\t\t\t\t\t\t\tn++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\t\n\t\t\t\t}\n\t\t\t\tvar c = this.board[x][y];\n\t\t\t\tswitch (n) {\n\t\t\t\t\tcase 0:\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tc = 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tbreak; \n\t\t\t\t\tcase 3:\n\t\t\t\t\t\tc = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tc = 0;\n\t\t\t\t}\n\t\t\t\tthis.boardNext[x][y] = c;\n\t\t\t}\n\t\t}\n\t\tthis.board = this.boardNext.slice();\n\t}\n\n\tthis.print = function() {\n\t\tfor (var x = 0; x < this.board.length; x++) {\n\t\t\tvar l = \"\";\n\t\t\tfor (var y = 0; y < this.board[x].length; y++) {\n\t\t\t\tif (this.board[x][y])\n\t\t\t\t\tl += \"X\";\n\t\t\t\telse\n\t\t\t\t\tl += \" \";\n\t\t\t}\n\t\t\tprint(l);\n\t\t}\n\t}\n\n\tthis.start = function() {\n\t\tfor (var t = 0; t < this.turns; t++) {\n\t\t\tprint(\"---\\nTurn \"+(t+1));\n\t\t\tthis.print();\n\t\t\tthis.nextGen()\n\t\t}\n\t}\n\n}\n\n\nvar game = new GameOfLife();\n\nprint(\"---\\n3x3 Blinker over three turns.\");\ngame.init(3);\ngame.board = [\n\t[0,0,0],\n\t[1,1,1],\n\t[0,0,0]];\ngame.start();\n\nprint(\"---\\n10x6 Glider over five turns.\");\ngame.init(5);\ngame.board = [\n\t[0,0,0,0,0,0,0,0,0,0],\n\t[0,0,1,0,0,0,0,0,0,0],\n\t[0,0,0,1,0,0,0,0,0,0],\n\t[0,1,1,1,0,0,0,0,0,0],\n\t[0,0,0,0,0,0,0,0,0,0],\n\t[0,0,0,0,0,0,0,0,0,0]];\ngame.start();\n\nprint(\"---\\nRandom 5x10\");\ngame.init(5,5,10);\ngame.start();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Count in factors", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a program which counts up from 1, displaying each number as the multiplication of its prime factors.

For the purpose of this task, 1 (unity) may be shown as itself.

", + "Example:", + "

2 is prime, so it would be shown as itself.

", + " 6 is not prime; it would be shown as $2\\times3$. ", + "2144 is not prime; it would be shown as $2\\times2\\times2\\times2\\times2\\times67$.", + "Related tasks:", + " prime decomposition", + " factors of an integer", + " Sieve of Eratosthenes", + " primality by trial division", + " factors of a Mersenne number", + " trial factoring of a Mersenne number", + " partition an integer X into N primes" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "for(i = 1; i <= 10; i++)", + " console.log(i + \" : \" + factor(i).join(\" x \"));", + "", + "function factor(n) {", + " var factors = [];", + " if (n == 1) return [1];", + " for(p = 2; p <= n; ) {", + "\tif((n % p) == 0) {", + "\t factors[factors.length] = p;", + "\t n /= p;", + "\t}", + "\telse p++;", + " }", + " return factors;", + "}", + "{{out}}", + "
",
+      "1 : 1",
+      "2 : 2",
+      "3 : 3",
+      "4 : 2 x 2",
+      "5 : 5",
+      "6 : 2 x 3",
+      "7 : 7",
+      "8 : 2 x 2 x 2",
+      "9 : 3 x 3",
+      "10 : 2 x 5",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7df6", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "for(i = 1; i <= 10; i++)\n console.log(i + \" : \" + factor(i).join(\" x \"));\n\nfunction factor(n) {\n var factors = [];\n if (n == 1) return [1];\n for(p = 2; p <= n; ) {\n\tif((n % p) == 0) {\n\t factors[factors.length] = p;\n\t n /= p;\n\t}\n\telse p++;\n }\n return factors;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Cumulative standard deviation", + "type": "Waypoint", + "description": [ + "

Write a stateful function, class, generator or co-routine that takes a series of floating point numbers, one at a time, and returns the running standard deviation of the series.

The task implementation should use the most natural programming style of those listed for the function in the implementation language; the task must state which is being used.

Do not apply Bessel's correction; the returned standard deviation should always be computed as if the sample seen so far is the entire population.

Use this to compute the standard deviation of this demonstration set, $\\{2, 4, 4, 4, 5, 5, 7, 9\\}$, which is $2$.

", + "

Related tasks:

Random numbers", + "


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Imperative===", + "", + "Uses a closure.", + "function running_stddev() {", + " var n = 0;", + " var sum = 0.0;", + " var sum_sq = 0.0;", + " return function(num) {", + " n++;", + " sum += num;", + " sum_sq += num*num;", + " return Math.sqrt( (sum_sq / n) - Math.pow(sum / n, 2) );", + " }", + "}", + "", + "var sd = running_stddev();", + "var nums = [2,4,4,4,5,5,7,9];", + "var stddev = [];", + "for (var i in nums) ", + " stddev.push( sd(nums[i]) );", + "", + "// using WSH", + "WScript.Echo(stddev.join(', ');", + "", + "{{out}}", + "
0, 1, 0.942809041582063, 0.866025403784439, 0.979795897113273, 1, 1.39970842444753, 2
", + "", + "===Functional (ES 5)===", + "", + "Accumulating across a fold", + "", + "(function (xs) {", + " ", + " return xs.reduce(function (a, x, i) {", + " var n = i + 1,", + " sum_ = a.sum + x,", + " squaresSum_ = a.squaresSum + (x * x);", + "", + " return {", + " sum: sum_,", + " squaresSum: squaresSum_,", + " stages: a.stages.concat(", + " Math.sqrt((squaresSum_ / n) - Math.pow((sum_ / n), 2))", + " )", + " };", + "", + " }, {", + " sum: 0,", + " squaresSum: 0,", + " stages: []", + " }).stages", + "", + "})([2, 4, 4, 4, 5, 5, 7, 9]);", + "", + "{{Out}}", + "[0, 1, 0.9428090415820626, 0.8660254037844386, ", + "0.9797958971132716, 1, 1.3997084244475297, 2]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e03", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function running_stddev() {\n var n = 0;\n var sum = 0.0;\n var sum_sq = 0.0;\n return function(num) {\n n++;\n sum += num;\n sum_sq += num*num;\n return Math.sqrt( (sum_sq / n) - Math.pow(sum / n, 2) );\n }\n}\n\nvar sd = running_stddev();\nvar nums = [2,4,4,4,5,5,7,9];\nvar stddev = [];\nfor (var i in nums) \n stddev.push( sd(nums[i]) );\n\n// using WSH\nWScript.Echo(stddev.join(', ');\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Currying", + "type": "Waypoint", + "description": [ + "

Create a simple demonstrative example of Currying in the specific language.

Add any historic details as to how the feature made its way into the language.

", + "

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "====Partial application====", + " function addN(n) {", + " var curry = function(x) {", + " return x + n;", + " };", + " return curry;", + " }", + "", + " add2 = addN(2);", + " alert(add2);", + " alert(add2(7));", + "", + "====Generic currying====", + "", + "Basic case - returning a curried version of a function of two arguments", + "", + "(function () {", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " function curry(f) {", + " return function (a) {", + " return function (b) {", + " return f(a, b);", + " };", + " };", + " }", + "", + "", + " // TESTS", + "", + " // product :: Num -> Num -> Num", + " function product(a, b) {", + " return a * b;", + " }", + "", + " // return typeof curry(product);", + " // --> function", + "", + " // return typeof curry(product)(7)", + " // --> function", + "", + " //return typeof curry(product)(7)(9)", + " // --> number", + "", + " return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", + " .map(curry(product)(7))", + "", + " // [7, 14, 21, 28, 35, 42, 49, 56, 63, 70]", + "", + "})();", + "", + "", + "{{Out}}", + "[7, 14, 21, 28, 35, 42, 49, 56, 63, 70]", + "", + "", + "Functions of arbitrary arity can also be curried:", + "", + "(function () {", + "", + " // (arbitrary arity to fully curried)", + " // extraCurry :: Function -> Function", + " function extraCurry(f) {", + "", + " // Recursive currying", + " function _curry(xs) {", + " return xs.length >= intArgs ? (", + " f.apply(null, xs)", + " ) : function () {", + " return _curry(xs.concat([].slice.apply(arguments)));", + " };", + " }", + "", + " var intArgs = f.length;", + "", + " return _curry([].slice.call(arguments, 1));", + " }", + "", + "", + " // TEST", + "", + " // product3:: Num -> Num -> Num -> Num", + " function product3(a, b, c) {", + " return a * b * c;", + " }", + "", + " return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", + " .map(extraCurry(product3)(7)(2))", + "", + " // [14, 28, 42, 56, 70, 84, 98, 112, 126, 140]", + "", + "})();", + "", + "{{Out}}", + "[14, 28, 42, 56, 70, 84, 98, 112, 126, 140]", + "", + "===ES6===", + "", + "====Y combinator====", + "Using a definition of currying that does not imply partial application, only conversion of a function of multiple arguments, e.g.: (a,b) => expr_using_a_and_binto a function that takes a series of as many function applications as that function took arguments, e.g.:a => b => expr_using_a_and_b", + "", + "One version for functions of a set amount of arguments that takes no rest arguments, and one version for functions with rest argument. The caveat being that if the rest argument would be empty, it still requires a separate application, and multiple rest arguments cannot be curried into multiple applications, since we have to figure out the number of applications from the function signature, not the amount of arguments the user might want to send it.", + "let", + " fix = // This is a variant of the Applicative order Y combinator", + " f => (f => f(f))(g => f((...a) => g(g)(...a))),", + " curry =", + " f => (", + " fix(", + " z => (n,...a) => (", + " n>0", + " ?b => z(n-1,...a,b)", + " :f(...a)))", + " (f.length)),", + " curryrest =", + " f => (", + " fix(", + " z => (n,...a) => (", + " n>0", + " ?b => z(n-1,...a,b)", + " :(...b) => f(...a,...b)))", + " (f.length)),", + " curriedmax=curry(Math.max),", + " curryrestedmax=curryrest(Math.max);", + "print(curriedmax(8)(4),curryrestedmax(8)(4)(),curryrestedmax(8)(4)(9,7,2));", + "// 8,8,9", + "", + "Neither of these handle propagation of the this value for methods, as ECMAScript 2015 (ES6) fat arrow syntax doesn't allow for this value propagation. Versions could easily be written for those cases using an outer regular function expression and use of Function.prototype.call or Function.prototype.apply. Use of Y combinator could also be removed through use of an inner named function expression instead of the anonymous fat arrow function syntax.", + "", + "====Simple 2 and N argument versions====", + "", + "In the most rudimentary form, for example for mapping a two-argument function over an array:", + "", + "(() => {", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " let curry = f => a => b => f(a, b);", + "", + "", + " // TEST", + "", + " // product :: Num -> Num -> Num", + " let product = (a, b) => a * b,", + "", + " // Int -> Int -> Maybe Int -> [Int]", + " range = (m, n, step) => {", + " let d = (step || 1) * (n >= m ? 1 : -1);", + "", + " return Array.from({", + " length: Math.floor((n - m) / d) + 1", + " }, (_, i) => m + (i * d));", + " }", + "", + "", + " return range(1, 10)", + " .map(curry(product)(7))", + "", + " // [7, 14, 21, 28, 35, 42, 49, 56, 63, 70]", + "", + "})();", + "", + "{{Out}}", + "[7, 14, 21, 28, 35, 42, 49, 56, 63, 70]", + "", + "", + "Or, recursively currying functions of arbitrary arity:", + "", + "(() => {", + "", + " // (arbitrary arity to fully curried)", + " // extraCurry :: Function -> Function", + " let extraCurry = (f, ...args) => {", + " let intArgs = f.length;", + "", + " // Recursive currying", + " let _curry = (xs, ...arguments) =>", + " xs.length >= intArgs ? (", + " f.apply(null, xs)", + " ) : function () {", + " return _curry(xs.concat([].slice.apply(arguments)));", + " };", + "", + " return _curry([].slice.call(args, 1));", + " };", + "", + " // TEST", + "", + " // product3:: Num -> Num -> Num -> Num", + " let product3 = (a, b, c) => a * b * c;", + "", + " return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", + " .map(extraCurry(product3)(7)(2))", + "", + " // [14, 28, 42, 56, 70, 84, 98, 112, 126, 140]", + "", + "})();", + "", + "{{Out}}", + "[14, 28, 42, 56, 70, 84, 98, 112, 126, 140]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e04", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + " function addN(n) {\n var curry = function(x) {\n return x + n;\n };\n return curry;\n }\n\n add2 = addN(2);\n alert(add2);\n alert(add2(7));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "CUSIP", + "type": "Waypoint", + "description": [ + "

A CUSIP is a nine-character alphanumeric code that identifies a North American financial security for the purposes of facilitating clearing and settlement of trades. The CUSIP was adopted as an American National Standard under Accredited Standards X9.6.

", + "Task:", + "

Ensure the last digit (i.e., the check digit) of the CUSIP code (the 1st column) is correct, against the following:

", + " 037833100 Apple Incorporated ", + " 17275R102 Cisco Systems ", + " 38259P508 Google Incorporated ", + " 594918104 Microsoft Corporation ", + " 68389X106 Oracle Corporation (incorrect)", + " 68389X105 Oracle Corporation Example pseudo-code below.", + "

algorithm Cusip-Check-Digit(cusip) is

", + "

Input: an 8-character CUSIP

sum := 0

", + "

for 1 ≤ i ≤ 8 do

", + "

c := the ith character of cusip

", + "

if c is a digit then

", + "

v := numeric value of the digit c

", + "

else if c is a letter then

", + "

p := ordinal position of c in the alphabet (A=1, B=2...)

", + "

v := p + 9

", + "

else if c = \"*\" then

", + "

v := 36

", + "

else if c = \"@\" then

", + "

v := 37

", + "

else if' c = \"#\" then

", + "

v := 38

", + "

end if

", + "

if i is even then

", + "

v := v × 2

", + "

end if

sum := sum + int ( v div 10 ) + v mod 10

", + "

repeat

return (10 - (sum mod 10)) mod 10

", + "

end function

See related tasks: ", + "SEDOL", + "ISIN" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e05", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Cut a rectangle", + "type": "Waypoint", + "description": [ + "

A given rectangle is made from m × n squares. If m and n are not both odd, then it is possible to cut a path through the rectangle along the square edges such that the rectangle splits into two connected pieces with the same shape (after rotating one of the pieces by 180°). All such paths for 2 × 2 and 4 × 3 rectangles are shown below.

file:rect-cut.svg

Write a program that calculates the number of different ways to cut an m × n rectangle. Optionally, show each of the cuts.

Possibly related task: Maze generation for depth-first search.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e06", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Deconvolution/2D+", + "type": "Waypoint", + "description": [ + "

This task is a straightforward generalization of Deconvolution/1D to higher dimensions. For example, the one dimensional case would be applicable to audio signals, whereas two dimensions would pertain to images. Define the discrete convolution in $\\mathit d$ dimensions of two functions

$H,F:\\mathbb{Z}^d\\rightarrow\\mathbb{R}$

taking $\\mathit d$-tuples of integers to real numbers as the function

$G:\\mathbb{Z}^d\\rightarrow\\mathbb{R}$

also taking $\\mathit d$-tuples of integers to reals and satisfying

$G(n_0, \\dots, n_{d-1})=\\sum_{m_0=-\\infty}^{\\infty}\\dots\\sum_{m_{d-1}=-\\infty}^{\\infty}F(m_0, \\dots, m_{d-1})H(n_0-m_0, \\dots, n_{d-1}-m_{d-1})$

for all $\\mathit d$-tuples of integers $(n_0, \\dots, n_{d-1})\\in\\mathbb{Z}^d$. Assume

", + "

$\\mathit F$ and $\\mathit H$ (and therefore $\\mathit G$) are non-zero over only a finite domain bounded by the origin, hence possible to represent as finite multi-dimensional arrays or nested lists $\\mathit f$, $\\mathit h$, and $\\mathit g$.

For this task, implement a function (or method, procedure, subroutine, etc.) deconv to perform deconvolution (i.e., the inverse of convolution) by solving for $\\mathit{h}$ given $\\mathit{f}$ and $\\mathit{g}$. (See Deconvolution/1D for details.)

", + "The function should work for $\\mathit{g}$ of arbitrary length in each dimension (i.e., not hard coded or constant) and $\\mathit{f}$ of any length up to that of $\\mathit{g}$ in the corresponding dimension.", + "The deconv function will need to be parameterized by the dimension $\\mathit d$ unless the dimension can be inferred from the data structures representing $\\mathit g$ and $\\mathit f$.", + "There may be more equations than unknowns. If convenient, use a function from a library that finds the best fitting solution to an overdetermined system of linear equations (as in the Multiple regression task). Otherwise, prune the set of equations as needed and solve as in the Reduced row echelon form task.", + "Debug your solution using this test data, of which a portion is shown below. Be sure to verify both that the deconvolution of $\\mathit g$ with $\\mathit f$ is $\\mathit h$ and that the deconvolution of $\\mathit g$ with $\\mathit h$ is $\\mathit f$. Display the results in a human readable form for the three dimensional case only.", + "

dimension 1:

", + "
",
+      "h: [-8, 2, -9, -2, 9, -8, -2]",
+      "f: [ 6, -9, -7, -5]",
+      "g: [-48, 84, -16, 95, 125, -70, 7, 29, 54, 10]",
+      "
", + "

dimension 2:

", + "
",
+      "h: [",
+      "      [-8, 1, -7, -2, -9, 4], ",
+      "      [4, 5, -5, 2, 7, -1], ",
+      "      [-6, -3, -3, -6, 9, 5]]",
+      "f: [",
+      "      [-5, 2, -2, -6, -7], ",
+      "      [9, 7, -6, 5, -7], ",
+      "      [1, -1, 9, 2, -7], ",
+      "      [5, 9, -9, 2, -5], ",
+      "      [-8, 5, -2, 8, 5]]",
+      "g: [",
+      "      [40, -21, 53, 42, 105, 1, 87, 60, 39, -28], ",
+      "      [-92, -64, 19, -167, -71, -47, 128, -109, 40, -21], ",
+      "      [58, 85, -93, 37, 101, -14, 5, 37, -76, -56], ",
+      "      [-90, -135, 60, -125, 68, 53, 223, 4, -36, -48], ",
+      "      [78, 16, 7, -199, 156, -162, 29, 28, -103, -10], ",
+      "      [-62, -89, 69, -61, 66, 193, -61, 71, -8, -30], ",
+      "      [48, -6, 21, -9, -150, -22, -56, 32, 85, 25]]",
+      "
", + "

dimension 3:

", + "
",
+      "h: [",
+      "      -6, -8, -5, 9], [-7, 9, -6, -8], [2, -7, 9, 8, ",
+      "      7, 4, 4, -6], [9, 9, 4, -4], [-3, 7, -2, -3]",
+      "f: [",
+      "      -9, 5, -8], [3, 5, 1, ",
+      "      -1, -7, 2], [-5, -6, 6, ",
+      "      8, 5, 8],[-2, -6, -4]",
+      "g: [",
+      "      [",
+      "         [54, 42, 53, -42, 85, -72], ",
+      "         [45, -170, 94, -36, 48, 73], ",
+      "         [-39, 65, -112, -16, -78, -72], ",
+      "         [6, -11, -6, 62, 49, 8]], ",
+      "      [",
+      "         [-57, 49, -23, 52, -135, 66], ",
+      "         [-23, 127, -58, -5, -118, 64], ",
+      "         [87, -16, 121, 23, -41, -12], ",
+      "         [-19, 29, 35, -148, -11, 45]], ",
+      "      [",
+      "         [-55, -147, -146, -31, 55, 60], ",
+      "         [-88, -45, -28, 46, -26, -144], ",
+      "         [-12, -107, -34, 150, 249, 66], ",
+      "         [11, -15, -34, 27, -78, -50]], ",
+      "      [",
+      "         [56, 67, 108, 4, 2, -48], ",
+      "         [58, 67, 89, 32, 32, -8], ",
+      "         [-42, -31, -103, -30, -23, -8],",
+      "         [6, 4, -26, -10, 26, 12]]]",
+      "
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e0d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Delegates", + "type": "Waypoint", + "description": [ + "

A delegate is a helper object used by another object. The delegator may send the delegate certain messages, and provide a default implementation when there is no delegate or the delegate does not respond to a message. This pattern is heavily used in Cocoa framework on Mac OS X. See also [[wp:Delegation pattern]].

Objects responsibilities:

Delegator:

", + "Keep an optional delegate instance.", + "Implement \"operation\" method, returning the delegate \"thing\" if the delegate respond to \"thing\", or the string \"default implementation\".", + "

Delegate:

", + "Implement \"thing\" and return the string \"delegate implementation\"", + "

Show how objects are created and used. First, without a delegate, then with a delegate that does not implement \"thing\", and last with a delegate that implements \"thing\".

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{trans|Python}}", + "function Delegator() {", + " this.delegate = null ;", + " this.operation = function(){", + " if(this.delegate && typeof(this.delegate.thing) == 'function')", + " return this.delegate.thing() ;", + " return 'default implementation' ;", + " }", + "}", + "", + "function Delegate() {", + " this.thing = function(){", + " return 'Delegate Implementation' ;", + " }", + "}", + "", + "function testDelegator(){", + " var a = new Delegator() ;", + " document.write(a.operation() + \"\\n\") ;", + " ", + " a.delegate = 'A delegate may be any object' ; ", + " document.write(a.operation() + \"\\n\") ;", + " ", + " a.delegate = new Delegate() ;", + " document.write(a.operation() + \"\\n\") ;", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e10", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function Delegator() {\n this.delegate = null ;\n this.operation = function(){\n if(this.delegate && typeof(this.delegate.thing) == 'function')\n return this.delegate.thing() ;\n return 'default implementation' ;\n }\n}\n\nfunction Delegate() {\n this.thing = function(){\n return 'Delegate Implementation' ;\n }\n}\n\nfunction testDelegator(){\n var a = new Delegator() ;\n document.write(a.operation() + \"\\n\") ;\n \n a.delegate = 'A delegate may be any object' ; \n document.write(a.operation() + \"\\n\") ;\n \n a.delegate = new Delegate() ;\n document.write(a.operation() + \"\\n\") ;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Determine if a string is numeric", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a boolean function which takes in a string and tells whether it is a numeric string (floating point and negative numbers included) in the syntax the language uses for numeric literals or numbers converted from strings.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "A far better validator can be found on StackOverflow[http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric]", + "function isNumeric(n) {", + " return !isNaN(parseFloat(n)) && isFinite(n);", + "}", + "var value = \"123.45e7\"; // Assign string literal to value", + "if (isNumeric(value)) {", + " // value is a number", + "}", + "//Or, in web browser in address field:", + "// javascript:function isNumeric(n) {return !isNaN(parseFloat(n)) && isFinite(n);}; value=\"123.45e4\"; if(isNumeric(value)) {alert('numeric')} else {alert('non-numeric')}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e14", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function isNumeric(n) {\n return !isNaN(parseFloat(n)) && isFinite(n);\n}\nvar value = \"123.45e7\"; // Assign string literal to value\nif (isNumeric(value)) {\n // value is a number\n}\n//Or, in web browser in address field:\n// javascript:function isNumeric(n) {return !isNaN(parseFloat(n)) && isFinite(n);}; value=\"123.45e4\"; if(isNumeric(value)) {alert('numeric')} else {alert('non-numeric')}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Digital root", + "type": "Waypoint", + "description": [ + "

The digital root, $X$, of a number, $n$, is calculated:

", + "

find $X$ as the sum of the digits of $n$

", + "

find a new $X$ by summing the digits of $X$, repeating until $X$ has only one digit.

The additive persistence is the number of summations required to obtain the single digit.

The task is to calculate the additive persistence and the digital root of a number, e.g.:

", + "

$627615$ has additive persistence $2$ and digital root of $9$;

", + "

$39390$ has additive persistence $2$ and digital root of $6$;

", + "

$588225$ has additive persistence $2$ and digital root of $3$;

", + "

$393900588225$ has additive persistence $2$ and digital root of $9$;

The digital root may be calculated in bases other than 10.

", + "See:", + "Casting out nines for this wiki's use of this procedure.", + "Digital root/Multiplicative digital root", + "Sum digits of an integer", + "Digital root sequence on OEIS", + "Additive persistence sequence on OEIS", + "Iterated digits squaring" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "null": [ + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [] + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "/// Digital root of 'x' in base 'b'.", + "@return {addpers, digrt}" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e17", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "Digital root of 'x' in base 'b'.", + "@return {addpers, digrt}" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Dinesman's multiple-dwelling problem", + "type": "Waypoint", + "description": [ + "Task", + "

Solve Dinesman's multiple dwelling problem but in a way that most naturally follows the problem statement given below.

Solutions are allowed (but not required) to parse and interpret the problem text, but should remain flexible and should state what changes to the problem text are allowed. Flexibility and ease of expression are valued.

Examples may be be split into \"setup\", \"problem statement\", and \"output\" sections where the ease and naturalness of stating the problem and getting an answer, as well as the ease and flexibility of modifying the problem are the primary concerns.

Example output should be shown here, as well as any comments on the examples flexibility.

", + "The problem", + "

Baker, Cooper, Fletcher, Miller, and Smith live on different floors of an apartment house that contains only five floors.

", + "Baker does not live on the top floor.", + "Cooper does not live on the bottom floor. ", + "Fletcher does not live on either the top or the bottom floor.", + "Miller lives on a higher floor than does Cooper.", + "Smith does not live on a floor adjacent to Fletcher's. ", + "Fletcher does not live on a floor adjacent to Cooper's.Where does everyone live?" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES6===", + "", + "====More flexibility====", + "", + "(Full occupancy and no cohabitation included in the predicate)", + "", + "The generality of nesting '''concatMap''', and returning values enclosed in a list (empty where the test fails, populated otherwise), is the same as that of a using a list comprehension, to which it is formally equivalent. (concatMap is the bind operator for the list monad, and '''(a -> [a])''' is the type of the 'return' function for a list monad. The effect is to define a cartesian product, and apply a predicate to each member of that product. Any empty lists returned where a predicate yields ''false'' are eliminated by the concatenation component of concatMap.", + "", + "The predicates here can be varied, and the depth of concatMap nestings can be adjusted to match the number of unknowns in play, with each concatMap binding one name, and defining the list of its possible values.", + "", + "(() => {", + " 'use strict';", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // and :: [Bool] -> Bool", + " const and = xs => {", + " let i = xs.length;", + " while (i--)", + " if (!xs[i]) return false;", + " return true;", + " }", + "", + " // nubBy :: (a -> a -> Bool) -> [a] -> [a]", + " const nubBy = (p, xs) => {", + " const x = xs.length ? xs[0] : undefined;", + " return x !== undefined ? [x].concat(", + " nubBy(p, xs.slice(1)", + " .filter(y => !p(x, y)))", + " ) : [];", + " }", + "", + " // PROBLEM DECLARATION", + "", + " const floors = range(1, 5);", + "", + " return concatMap(b =>", + " concatMap(c =>", + " concatMap(f =>", + " concatMap(m =>", + " concatMap(s =>", + " and([ // CONDITIONS", + " nubBy((a, b) => a === b, [b, c, f, m, s]) // all floors singly occupied", + " .length === 5,", + " b !== 5, c !== 1, f !== 1, f !== 5,", + " m > c, Math.abs(s - f) > 1, Math.abs(c - f) > 1", + " ]) ? [{", + " Baker: b,", + " Cooper: c,", + " Fletcher: f,", + " Miller: m,", + " Smith: s", + " }] : [],", + " floors), floors), floors), floors), floors);", + "", + " // --> [{\"Baker\":3, \"Cooper\":2, \"Fletcher\":4, \"Miller\":5, \"Smith\":1}]", + "})();", + "", + "{{Out}}", + "[{\"Baker\":3, \"Cooper\":2, \"Fletcher\":4, \"Miller\":5, \"Smith\":1}]", + "", + "====Less flexibility====", + "", + "For a different trade-off between efficiency and generality, we can take full occupancy and no cohabitation out of the predicate, and assume them in the shape of the search space.", + "", + "In the version above, with nested applications of concatMap, the requirement that all apartments are occupied by one person only is included in the test conditions. ", + "Alternatively, we can remove any flexibility about such civic virtues from the predicate, and restrict the universe of conceivable living arrangements, by using concatMap just once, and applying it only to the various permutations of full and distinct occupancy. ", + "", + "ES6 splat assignment allows us to bind all five names in a single application of concatMap. We now also need a '''permutations''' function of some kind.", + "", + "(() => {", + " 'use strict';", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // and :: [Bool] -> Bool", + " const and = xs => {", + " let i = xs.length;", + " while (i--)", + " if (!xs[i]) return false;", + " return true;", + " }", + "", + " // permutations :: [a] -> [[a]]", + " const permutations = xs =>", + " xs.length ? concatMap(x => concatMap(ys => [", + " [x].concat(ys)", + " ],", + " permutations(delete_(x, xs))), xs) : [", + " []", + " ];", + "", + " // delete :: a -> [a] -> [a]", + " const delete_ = (x, xs) =>", + " deleteBy((a, b) => a === b, x, xs);", + "", + " // deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]", + " const deleteBy = (f, x, xs) =>", + " xs.reduce((a, y) => f(x, y) ? a : a.concat(y), []);", + "", + " // PROBLEM DECLARATION", + "", + " const floors = range(1, 5);", + "", + " return concatMap(([c, b, f, m, s]) =>", + " and([ // CONDITIONS (assuming full occupancy, no cohabitation)", + " b !== 5, c !== 1, f !== 1, f !== 5,", + " m > c, Math.abs(s - f) > 1, Math.abs(c - f) > 1", + " ]) ? [{", + " Baker: b,", + " Cooper: c,", + " Fletcher: f,", + " Miller: m,", + " Smith: s", + " }] : [], permutations(floors));", + "", + " // --> [{\"Baker\":3, \"Cooper\":2, \"Fletcher\":4, \"Miller\":5, \"Smith\":1}]", + "})();", + "", + "", + "[{\"Baker\":3, \"Cooper\":2, \"Fletcher\":4, \"Miller\":5, \"Smith\":1}]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e18", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // concatMap :: (a -> [b]) -> [a] -> [b]\n const concatMap = (f, xs) => [].concat.apply([], xs.map(f));\n\n // range :: Int -> Int -> [Int]\n const range = (m, n) =>\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i);\n\n // and :: [Bool] -> Bool\n const and = xs => {\n let i = xs.length;\n while (i--)\n if (!xs[i]) return false;\n return true;\n }\n\n // nubBy :: (a -> a -> Bool) -> [a] -> [a]\n const nubBy = (p, xs) => {\n const x = xs.length ? xs[0] : undefined;\n return x !== undefined ? [x].concat(\n nubBy(p, xs.slice(1)\n .filter(y => !p(x, y)))\n ) : [];\n }\n\n // PROBLEM DECLARATION\n\n const floors = range(1, 5);\n\n return concatMap(b =>\n concatMap(c =>\n concatMap(f =>\n concatMap(m =>\n concatMap(s =>\n and([ // CONDITIONS\n nubBy((a, b) => a === b, [b, c, f, m, s]) // all floors singly occupied\n .length === 5,\n b !== 5, c !== 1, f !== 1, f !== 5,\n m > c, Math.abs(s - f) > 1, Math.abs(c - f) > 1\n ]) ? [{\n Baker: b,\n Cooper: c,\n Fletcher: f,\n Miller: m,\n Smith: s\n }] : [],\n floors), floors), floors), floors), floors);\n\n // --> [{\"Baker\":3, \"Cooper\":2, \"Fletcher\":4, \"Miller\":5, \"Smith\":1}]\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Distributed programming", + "type": "Waypoint", + "description": [ + "

Write two programs (or one program with two modes) which run on networked computers, and send some messages between them.

The protocol used may be language-specific or not, and should be suitable for general distributed programming; that is, the protocol should be generic (not designed just for the particular example application), readily capable of handling the independent communications of many different components of a single application, and the transferring of arbitrary data structures natural for the language.

This task is intended to demonstrate high-level communication facilities beyond just creating sockets.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "{{works with|node.js}}", + "", + "===Server===", + "", + "var net = require('net')", + "", + "var server = net.createServer(function (c){", + " c.write('hello\\r\\n')", + " c.pipe(c) // echo messages back", + "})", + "", + "server.listen(3000, 'localhost')", + "", + "", + "===Client===", + "var net = require('net')", + "", + "conn = net.createConnection(3000, '192.168.1.x')", + "", + "conn.on('connect', function(){", + "\tconsole.log('connected')", + "\tconn.write('test')", + "})", + "", + "conn.on('data', function(msg){", + "\tconsole.log(msg.toString())", + "})", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e1b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var net = require('net')\n\nvar server = net.createServer(function (c){\n c.write('hello\\r\\n')\n c.pipe(c) // echo messages back\n})\n\nserver.listen(3000, 'localhost')\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "DNS query", + "type": "Waypoint", + "description": [ + "

DNS is an internet service that maps domain names, like rosettacode.org, to IP addresses, like 66.220.0.231.

Use DNS to resolve www.kame.net to both IPv4 and IPv6 addresses. Print these addresses.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e1c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Documentation", + "type": "Waypoint", + "description": [ + "

Show how to insert documentation for classes, functions, and/or variables in your language. If this documentation is built-in to the language, note it. If this documentation requires external tools, note them.

", + "See also:", + "Related task: Comments", + "Related task: Here_document" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e1d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Dot product", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a function/use an in-built function, to compute the dot product, also known as the scalar product of two vectors.

If possible, make the vectors of arbitrary length.

", + "

As an example, compute the dot product of the vectors:

", + "

::: [1, 3, -5] and

", + "

::: [4, -2, -1]

", + "

If implementing the dot product of two vectors directly:

", + "

::* each vector must be the same length

", + "

::* multiply corresponding terms from each vector

", + "

::* sum the products (to produce the answer)

", + "Related task:", + " Vector products" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "function dot_product(ary1, ary2) {", + " if (ary1.length != ary2.length)", + " throw \"can't find dot product: arrays have different lengths\";", + " var dotprod = 0;", + " for (var i = 0; i < ary1.length; i++)", + " dotprod += ary1[i] * ary2[i];", + " return dotprod;", + "}", + "", + "print(dot_product([1,3,-5],[4,-2,-1])); // ==> 3", + "print(dot_product([1,3,-5],[4,-2,-1,0])); // ==> exception", + "", + "We could also use map and reduce in lieu of iteration,", + "", + "function dotp(x,y) {", + " function dotp_sum(a,b) { return a + b; }", + " function dotp_times(a,i) { return x[i] * y[i]; }", + " if (x.length != y.length)", + " throw \"can't find dot product: arrays have different lengths\";", + " return x.map(dotp_times).reduce(dotp_sum,0);", + "}", + "", + "dotp([1,3,-5],[4,-2,-1]); // ==> 3", + "dotp([1,3,-5],[4,-2,-1,0]); // ==> exception", + "", + "===ES6===", + "Composing functional primitives into a '''dotProduct()''' which returns '''undefined''' (rather than an error) when the array lengths are unmatched.", + "", + "(() => {", + " 'use strict';", + "", + " // dotProduct :: [Int] -> [Int] -> Int", + " const dotProduct = (xs, ys) => {", + " const sum = xs => xs ? xs.reduce((a, b) => a + b, 0) : undefined;", + "", + " return xs.length === ys.length ? (", + " sum(zipWith((a, b) => a * b, xs, ys))", + " ) : undefined;", + " }", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) => {", + " const ny = ys.length;", + " return (xs.length <= ny ? xs : xs.slice(0, ny))", + " .map((x, i) => f(x, ys[i]));", + " }", + "", + " return dotProduct([1, 3, -5], [4, -2, -1]);", + "})();", + "", + "{{Out}}", + "3", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e1e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function dot_product(ary1, ary2) {\n if (ary1.length != ary2.length)\n throw \"can't find dot product: arrays have different lengths\";\n var dotprod = 0;\n for (var i = 0; i < ary1.length; i++)\n dotprod += ary1[i] * ary2[i];\n return dotprod;\n}\n\nprint(dot_product([1,3,-5],[4,-2,-1])); // ==> 3\nprint(dot_product([1,3,-5],[4,-2,-1,0])); // ==> exception\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Doubly-linked list/Definition", + "type": "Waypoint", + "description": [ + "

Define the data structure for a complete Doubly Linked List.

The structure should support adding elements to the head, tail and middle of the list. ", + "The structure should not allow circular loops" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "See [[Doubly-Linked List (element)#JavaScript]], [[Doubly-Linked List (element insertion)#JavaScript]] and [[Doubly-Linked List (traversal)#JavaScript]]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e1f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["null\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Doubly-linked list/Element definition", + "type": "Waypoint", + "description": [ + "Task:", + "

Define the data structure for a doubly-linked list element.

The element should include a data member to hold its value and pointers to both the next element in the list and the previous element in the list.

The pointers should be mutable.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Inherits from LinkedList (see [[Singly-Linked_List_(element)#JavaScript]])", + "function DoublyLinkedList(value, next, prev) {", + " this._value = value;", + " this._next = next;", + " this._prev = prev;", + "}", + "// from LinkedList, inherit: value(), next(), traverse(), print()", + "DoublyLinkedList.prototype = new LinkedList();", + "", + "DoublyLinkedList.prototype.prev = function() {", + " if (arguments.length == 1) ", + " this._prev = arguments[0];", + " else", + " return this._prev;", + "}", + "", + "function createDoublyLinkedListFromArray(ary) {", + " var node, prev, head = new DoublyLinkedList(ary[0], null, null);", + " prev = head;", + " for (var i = 1; i < ary.length; i++) {", + " node = new DoublyLinkedList(ary[i], null, prev);", + " prev.next(node);", + " prev = node;", + " }", + " return head;", + "}", + "", + "var head = createDoublyLinkedListFromArray([10,20,30,40]);", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e20", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function DoublyLinkedList(value, next, prev) {\n this._value = value;\n this._next = next;\n this._prev = prev;\n}\n// from LinkedList, inherit: value(), next(), traverse(), print()\nDoublyLinkedList.prototype = new LinkedList();\n\nDoublyLinkedList.prototype.prev = function() {\n if (arguments.length == 1) \n this._prev = arguments[0];\n else\n return this._prev;\n}\n\nfunction createDoublyLinkedListFromArray(ary) {\n var node, prev, head = new DoublyLinkedList(ary[0], null, null);\n prev = head;\n for (var i = 1; i < ary.length; i++) {\n node = new DoublyLinkedList(ary[i], null, prev);\n prev.next(node);\n prev = node;\n }\n return head;\n}\n\nvar head = createDoublyLinkedListFromArray([10,20,30,40]);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Doubly-linked list/Element insertion", + "type": "Waypoint", + "description": [ + "

Use the link structure defined in Doubly-Linked List (element) to define a procedure for inserting a link into a doubly-linked list. Call this procedure to insert element C into a list {A,B}, between elements A and B.

This is much like inserting into a Singly-Linked List, but with added assignments so that the backwards-pointing links remain correct.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "See [[Doubly-Linked_List_(element)#JavaScript]]", + "DoublyLinkedList.prototype.insertAfter = function(searchValue, nodeToInsert) {", + " if (this._value == searchValue) {", + " var after = this.next();", + " this.next(nodeToInsert);", + " nodeToInsert.prev(this);", + " nodeToInsert.next(after);", + " after.prev(nodeToInsert);", + " }", + " else if (this.next() == null) ", + " throw new Error(0, \"value '\" + searchValue + \"' not found in linked list.\")", + " else", + " this.next().insertAfter(searchValue, nodeToInsert);", + "}", + "", + "var list = createDoublyLinkedListFromArray(['A','B']);", + "list.insertAfter('A', new DoublyLinkedList('C', null, null));", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e21", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "DoublyLinkedList.prototype.insertAfter = function(searchValue, nodeToInsert) {\n if (this._value == searchValue) {\n var after = this.next();\n this.next(nodeToInsert);\n nodeToInsert.prev(this);\n nodeToInsert.next(after);\n after.prev(nodeToInsert);\n }\n else if (this.next() == null) \n throw new Error(0, \"value '\" + searchValue + \"' not found in linked list.\")\n else\n this.next().insertAfter(searchValue, nodeToInsert);\n}\n\nvar list = createDoublyLinkedListFromArray(['A','B']);\nlist.insertAfter('A', new DoublyLinkedList('C', null, null));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Doubly-linked list/Traversal", + "type": "Waypoint", + "description": [ + "

Traverse from the beginning of a doubly-linked list to the end, and from the end to the beginning.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "See [[Doubly-Linked List (element)#JavaScript]]. The traverse() and print() functions have been inherited from [[Singly-Linked List (traversal)#JavaScript]].", + "DoublyLinkedList.prototype.getTail = function() {", + " var tail;", + " this.traverse(function(node){tail = node;});", + " return tail;", + "} ", + "DoublyLinkedList.prototype.traverseBackward = function(func) {", + " func(this);", + " if (this.prev() != null)", + " this.prev().traverseBackward(func);", + "}", + "DoublyLinkedList.prototype.printBackward = function() {", + " this.traverseBackward( function(node) {print(node.value())} );", + "}", + "", + "var head = createDoublyLinkedListFromArray([10,20,30,40]);", + "head.print();", + "head.getTail().printBackward();", + "", + "outputs:", + "
10",
+      "20",
+      "30",
+      "40",
+      "40",
+      "30",
+      "20",
+      "10
", + "Uses the print() function from [[Rhino]] or [[SpiderMonkey]].", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e22", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "DoublyLinkedList.prototype.getTail = function() {\n var tail;\n this.traverse(function(node){tail = node;});\n return tail;\n} \nDoublyLinkedList.prototype.traverseBackward = function(func) {\n func(this);\n if (this.prev() != null)\n this.prev().traverseBackward(func);\n}\nDoublyLinkedList.prototype.printBackward = function() {\n this.traverseBackward( function(node) {print(node.value())} );\n}\n\nvar head = createDoublyLinkedListFromArray([10,20,30,40]);\nhead.print();\nhead.getTail().printBackward();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Dragon curve", + "type": "Waypoint", + "description": [ + "

Create and display a dragon curve fractal.

(You may either display the curve directly or write it to an image file.)

", + "Algorithms

Here are some brief notes the algorithms used and how they might suit various languages.

Recursively a right curling dragon is a right dragon followed by a left dragon, at 90-degree angle. And a left dragon is a left followed by a right.", + "
*---R----*     expands to     *       *",
+      "                               \\     /",
+      "                                R   L",
+      "                                 \\ /",
+      "                                  *                                  *",
+      "                                 / \\",
+      "                                L   R",
+      "                               /     \\",
+      "---L---*      expands to     *       *
", + "

The co-routines dcl and dcr in various examples do this recursively to a desired expansion level.

The curl direction right or left can be a parameter instead of two separate routines.", + "Recursively, a curl direction can be eliminated by noting the dragon consists of two copies of itself drawn towards a central point at 45-degrees.", + "
*------->*   becomes    *       *     Recursive copies drawn",
+      "                         \\     /      from the ends towards",
+      "                          \\   /       the centre.",
+      "                           v v",
+      "                            *

This can be seen in the SVG example. This is best suited to off-line drawing since the reversal in the second half means the drawing jumps backward and forward (in binary reflected Gray code order) which is not very good for a plotter or for drawing progressively on screen.

Successive approximation repeatedly re-writes each straight line as two new segments at a right angle,", + "
                       *       ",
+      "-----*   becomes     / \\      bend to left                     /   \\     if N odd",
+      "                    *     *                    *     *   ",
+      "-----*   becomes    \\   /     bend to right                        \\ /      if N even ",
+      "                       *

Numbering from the start of the curve built so far, if the segment is at an odd position then the bend introduced is on the right side. If the segment is an even position then on the left. The process is then repeated on the new doubled list of segments. This constructs a full set of line segments before any drawing.

The effect of the splitting is a kind of bottom-up version of the recursions. See the Asymptote example for code doing this.

Iteratively the curve always turns 90-degrees left or right at each point. The direction of the turn is given by the bit above the lowest 1-bit of n. Some bit-twiddling can extract that efficiently.", + "
n = 1010110000",
+      "        ^",
+      "        bit above lowest 1-bit, turn left or right as 0 or 1LowMask = n BITXOR (n-1)   # eg. giving 0000011111",
+      "AboveMask = LowMask + 1    # eg. giving 0000100000",
+      "BitAboveLowestOne = n BITAND AboveMask

The first turn is at n=1, so reckon the curve starting at the origin as n=0 then a straight line segment to position n=1 and turn there.

If you prefer to reckon the first turn as n=0 then take the bit above the lowest 0-bit instead. This works because \"...10000\" minus 1 is \"...01111\" so the lowest 0 in n-1 is where the lowest 1 in n is.

Going by turns suits turtle graphics such as Logo or a plotter drawing with a pen and current direction.

If a language doesn't maintain a \"current direction\" for drawing then you can always keep that separately and apply turns by bit-above-lowest-1.", + "Absolute direction to move at point n can be calculated by the number of bit-transitions in n.", + "
n = 11 00 1111 0 1",
+      "      ^  ^    ^ ^     4 places where change bit value",
+      "                      so direction=4*90degrees=East

This can be calculated by counting the number of 1 bits in \"n XOR (n RIGHTSHIFT 1)\" since such a shift and xor leaves a single 1 bit at each position where two adjacent bits differ.

Absolute X,Y coordinates of a point n can be calculated in complex numbers by some powers (i+1)^k and add/subtract/rotate. This is done in the gnuplot code. This might suit things similar to Gnuplot which want to calculate each point independently.", + "Predicate test for whether a given X,Y point or segment is on the curve can be done. This might suit line-by-line output rather than building an entire image before printing. See M4 for an example of this.", + "

A predicate works by dividing out complex number i+1 until reaching the origin, so it takes roughly a bit at a time from X and Y is thus quite efficient. Why it works is slightly subtle but the calculation is not difficult. (Check segment by applying an offset to move X,Y to an \"even\" position before dividing i+1. Check vertex by whether the segment either East or West is on the curve.)

The number of steps in the predicate corresponds to doublings of the curve, so stopping the check at say 8 steps can limit the curve drawn to 2^8=256 points. The offsets arising in the predicate are bits of n the segment number, so can note those bits to calculate n and limit to an arbitrary desired length or sub-section.

As a Lindenmayer system of expansions. The simplest is two symbols F and S both straight lines, as used by the PGF code.", + "
Axiom F, angle 90 degrees",
+      "F -> F+S",
+      "S -> F-S

This always has F at even positions and S at odd. Eg. after 3 levels F_S_F_S_F_S_F_S. The +/- turns in between bend to the left or right the same as the \"successive approximation\" method above. Read more at for instance Joel Castellanos' L-system page.

Variations are possible if you have only a single symbol for line draw, for example the Icon and Unicon and Xfractint code. The angles can also be broken into 45-degree parts to keep the expansion in a single direction rather than the endpoint rotating around.

The string rewrites can be done recursively without building the whole string, just follow its instructions at the target level. See for example C by IFS Drawing code. The effect is the same as \"recursive with parameter\" above but can draw other curves defined by L-systems.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===Version #1.===", + "{{works with|Chrome 8.0}}", + "I'm sure this can be simplified further, but I have this working [http://kevincantu.org/code/dragon/dragon.html here]!", + "", + "Though there is an impressive SVG example further below, this uses JavaScript to recurse through the expansion and simply displays each line with SVG. It is invoked as a method DRAGON.fractal(...) as described.", + "var DRAGON = (function () {", + " // MATRIX MATH", + " // -----------", + "", + " var matrix = {", + " mult: function ( m, v ) {", + " return [ m[0][0] * v[0] + m[0][1] * v[1],", + " m[1][0] * v[0] + m[1][1] * v[1] ];", + " },", + "", + " minus: function ( a, b ) {", + " return [ a[0]-b[0], a[1]-b[1] ];", + " },", + "", + " plus: function ( a, b ) {", + " return [ a[0]+b[0], a[1]+b[1] ];", + " }", + " };", + "", + "", + " // SVG STUFF", + " // ---------", + "", + " // Turn a pair of points into an SVG path like \"M1 1L2 2\".", + " var toSVGpath = function (a, b) { // type system fail", + " return \"M\" + a[0] + \" \" + a[1] + \"L\" + b[0] + \" \" + b[1];", + " };", + "", + "", + " // DRAGON MAKING", + " // -------------", + "", + " // Make a dragon with a better fractal algorithm", + " var fractalMakeDragon = function (svgid, ptA, ptC, state, lr, interval) {", + "", + " // make a new ", + " var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');", + " path.setAttribute( \"class\", \"dragon\"); ", + " path.setAttribute( \"d\", toSVGpath(ptA, ptC) );", + "", + " // append the new path to the existing ", + " var svg = document.getElementById(svgid); // call could be eliminated", + " svg.appendChild(path);", + "", + " // if we have more iterations to go...", + " if (state > 1) {", + "", + " // make a new point, either to the left or right", + " var growNewPoint = function (ptA, ptC, lr) {", + " var left = [[ 1/2,-1/2 ], ", + " [ 1/2, 1/2 ]]; ", + "", + " var right = [[ 1/2, 1/2 ],", + " [-1/2, 1/2 ]];", + "", + " return matrix.plus(ptA, matrix.mult( lr ? left : right, ", + " matrix.minus(ptC, ptA) ));", + " }; ", + "", + " var ptB = growNewPoint(ptA, ptC, lr, state);", + "", + " // then recurse using each new line, one left, one right", + " var recurse = function () {", + " // when recursing deeper, delete this svg path", + " svg.removeChild(path);", + "", + " // then invoke again for new pair, decrementing the state", + " fractalMakeDragon(svgid, ptB, ptA, state-1, lr, interval);", + " fractalMakeDragon(svgid, ptB, ptC, state-1, lr, interval);", + " };", + "", + " window.setTimeout(recurse, interval);", + " }", + " };", + "", + "", + " // Export these functions", + " // ----------------------", + " return {", + " fractal: fractalMakeDragon", + "", + " // ARGUMENTS", + " // ---------", + " // svgid id of element", + " // ptA first point [x,y] (from top left)", + " // ptC second point [x,y]", + " // state number indicating how many steps to recurse", + " // lr true/false to make new point on left or right", + "", + " // CONFIG", + " // ------", + " // CSS rules should be made for the following", + " // svg#fractal", + " // svg path.dragon", + " };", + "", + "}());", + "", + "My current demo page includes the following to invoke this: ", + "...", + "", + "...", + "
", + " ", + "
", + "", + "...
", + "", + "===Version #2.===", + "{{works with|Chrome}}", + "[[File:DC11.png|200px|right|thumb|Output DC11.png]]", + "[[File:DC19.png|200px|right|thumb|Output DC19.png]]", + "[[File:DC25.png|200px|right|thumb|Output DC25.png]]", + "", + "", + "", + "", + "", + "", + "", + "

Please input order, scale, x-shift, y-shift, color:

", + "", + "", + "", + "", + "", + "", + "

Dragon curve

", + "", + "", + "", + "
", + "'''Testing cases:'''", + "
",
+      "Input parameters:",
+      "",
+      "ord scale x-shift y-shift color   [File name to save]",
+      "-------------------------------------------",
+      "11  7.    -265   -260   red       DC11.png",
+      "15  2.    -205   -230   brown     DC15.png",
+      "17  1.    -135    70    green     DC17.png",
+      "19  0.6    380    440   navy      DC19.png",
+      "21  0.22   1600   800   blue      DC21.png",
+      "23  0.15   1100   800   violet    DC23.png",
+      "25  0.07   2100   5400  darkgreen DC25.png",
+      "===========================================",
+      "
", + "", + "{{Output}} ", + "
",
+      "Page with different plotted Dragon curves. Right-clicking on the canvas you can save each of them",
+      "as a png-file. ",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e23", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var DRAGON = (function () {\n // MATRIX MATH\n // -----------\n\n var matrix = {\n mult: function ( m, v ) {\n return [ m[0][0] * v[0] + m[0][1] * v[1],\n m[1][0] * v[0] + m[1][1] * v[1] ];\n },\n\n minus: function ( a, b ) {\n return [ a[0]-b[0], a[1]-b[1] ];\n },\n\n plus: function ( a, b ) {\n return [ a[0]+b[0], a[1]+b[1] ];\n }\n };\n\n\n // SVG STUFF\n // ---------\n\n // Turn a pair of points into an SVG path like \"M1 1L2 2\".\n var toSVGpath = function (a, b) { // type system fail\n return \"M\" + a[0] + \" \" + a[1] + \"L\" + b[0] + \" \" + b[1];\n };\n\n\n // DRAGON MAKING\n // -------------\n\n // Make a dragon with a better fractal algorithm\n var fractalMakeDragon = function (svgid, ptA, ptC, state, lr, interval) {\n\n // make a new \n var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n path.setAttribute( \"class\", \"dragon\"); \n path.setAttribute( \"d\", toSVGpath(ptA, ptC) );\n\n // append the new path to the existing \n var svg = document.getElementById(svgid); // call could be eliminated\n svg.appendChild(path);\n\n // if we have more iterations to go...\n if (state > 1) {\n\n // make a new point, either to the left or right\n var growNewPoint = function (ptA, ptC, lr) {\n var left = [[ 1/2,-1/2 ], \n [ 1/2, 1/2 ]]; \n\n var right = [[ 1/2, 1/2 ],\n [-1/2, 1/2 ]];\n\n return matrix.plus(ptA, matrix.mult( lr ? left : right, \n matrix.minus(ptC, ptA) ));\n }; \n\n var ptB = growNewPoint(ptA, ptC, lr, state);\n\n // then recurse using each new line, one left, one right\n var recurse = function () {\n // when recursing deeper, delete this svg path\n svg.removeChild(path);\n\n // then invoke again for new pair, decrementing the state\n fractalMakeDragon(svgid, ptB, ptA, state-1, lr, interval);\n fractalMakeDragon(svgid, ptB, ptC, state-1, lr, interval);\n };\n\n window.setTimeout(recurse, interval);\n }\n };\n\n\n // Export these functions\n // ----------------------\n return {\n fractal: fractalMakeDragon\n\n // ARGUMENTS\n // ---------\n // svgid id of element\n // ptA first point [x,y] (from top left)\n // ptC second point [x,y]\n // state number indicating how many steps to recurse\n // lr true/false to make new point on left or right\n\n // CONFIG\n // ------\n // CSS rules should be made for the following\n // svg#fractal\n // svg path.dragon\n };\n\n}());\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Draw a clock", + "type": "Waypoint", + "description": [ + "Task:", + "

Draw a clock.

", + "

More specific:

", + "Draw a time keeping device. It can be a stopwatch, hourglass, sundial, a mouth counting \"one thousand and one\", anything. Only showing the seconds is required, e.g.: a watch with just a second hand will suffice. However, it must clearly change every second, and the change must cycle every so often (one minute, 30 seconds, etc.) It must be drawn; printing a string of numbers to your terminal doesn't qualify. Both text-based and graphical drawing are OK.", + "The clock is unlikely to be used to control space flights, so it needs not be hyper-accurate, but it should be usable, meaning if one can read the seconds off the clock, it must agree with the system clock.", + "A clock is rarely (never?) a major application: don't be a CPU hog and poll the system timer every microsecond, use a proper timer/signal/event from your system or language instead. For a bad example, many OpenGL programs update the frame-buffer in a busy loop even if no redraw is needed, which is very undesirable for this task.", + "A clock is rarely (never?) a major application: try to keep your code simple and to the point. Don't write something too elaborate or convoluted, instead do whatever is natural, concise and clear in your language.", + "Key points", + "animate simple object", + "timed event ", + "polling system resources ", + "code clarity" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Tested on Gecko. Put the following in a <script> tag somewhere, and call init_clock() after body load.", + "var sec_old = 0;", + "function update_clock() {", + "\tvar t = new Date();", + "\tvar arms = [t.getHours(), t.getMinutes(), t.getSeconds()];", + "\tif (arms[2] == sec_old) return;", + "\tsec_old = arms[2];", + "", + "\tvar c = document.getElementById('clock');", + "\tvar ctx = c.getContext('2d');", + "\tctx.fillStyle = \"rgb(0,200,200)\";", + "\tctx.fillRect(0, 0, c.width, c.height);", + "\tctx.fillStyle = \"white\";", + "\tctx.fillRect(3, 3, c.width - 6, c.height - 6);", + "\tctx.lineCap = 'round';", + "", + "\tvar orig = { x: c.width / 2, y: c.height / 2 };", + "\tarms[1] += arms[2] / 60;", + "\tarms[0] += arms[1] / 60;", + "\tdraw_arm(ctx, orig, arms[0] * 30, c.width/2.5 - 15, c.width / 20, \"green\");", + "\tdraw_arm(ctx, orig, arms[1] * 6, c.width/2.2 - 10, c.width / 30, \"navy\");", + "\tdraw_arm(ctx, orig, arms[2] * 6, c.width/2.0 - 6, c.width / 100, \"maroon\");", + "}", + "", + "function draw_arm(ctx, orig, deg, len, w, style)", + "{", + "\tctx.save();", + "\tctx.lineWidth = w;", + "\tctx.lineCap = 'round';", + "\tctx.translate(orig.x, orig.y);", + "\tctx.rotate((deg - 90) * Math.PI / 180);", + "\tctx.strokeStyle = style;", + "\tctx.beginPath();", + "\tctx.moveTo(-len / 10, 0);", + "\tctx.lineTo(len, 0);", + "\tctx.stroke();", + "\tctx.restore();", + "}", + "", + "function init_clock() {", + "\tvar clock = document.createElement('canvas');", + "\tclock.width = 100;", + "\tclock.height = 100;", + "\tclock.id = \"clock\";", + "\tdocument.body.appendChild(clock);", + "", + "\twindow.setInterval(update_clock, 200);", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e24", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var sec_old = 0;\nfunction update_clock() {\n\tvar t = new Date();\n\tvar arms = [t.getHours(), t.getMinutes(), t.getSeconds()];\n\tif (arms[2] == sec_old) return;\n\tsec_old = arms[2];\n\n\tvar c = document.getElementById('clock');\n\tvar ctx = c.getContext('2d');\n\tctx.fillStyle = \"rgb(0,200,200)\";\n\tctx.fillRect(0, 0, c.width, c.height);\n\tctx.fillStyle = \"white\";\n\tctx.fillRect(3, 3, c.width - 6, c.height - 6);\n\tctx.lineCap = 'round';\n\n\tvar orig = { x: c.width / 2, y: c.height / 2 };\n\tarms[1] += arms[2] / 60;\n\tarms[0] += arms[1] / 60;\n\tdraw_arm(ctx, orig, arms[0] * 30, c.width/2.5 - 15, c.width / 20, \"green\");\n\tdraw_arm(ctx, orig, arms[1] * 6, c.width/2.2 - 10, c.width / 30, \"navy\");\n\tdraw_arm(ctx, orig, arms[2] * 6, c.width/2.0 - 6, c.width / 100, \"maroon\");\n}\n\nfunction draw_arm(ctx, orig, deg, len, w, style)\n{\n\tctx.save();\n\tctx.lineWidth = w;\n\tctx.lineCap = 'round';\n\tctx.translate(orig.x, orig.y);\n\tctx.rotate((deg - 90) * Math.PI / 180);\n\tctx.strokeStyle = style;\n\tctx.beginPath();\n\tctx.moveTo(-len / 10, 0);\n\tctx.lineTo(len, 0);\n\tctx.stroke();\n\tctx.restore();\n}\n\nfunction init_clock() {\n\tvar clock = document.createElement('canvas');\n\tclock.width = 100;\n\tclock.height = 100;\n\tclock.id = \"clock\";\n\tdocument.body.appendChild(clock);\n\n\twindow.setInterval(update_clock, 200);\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Draw a cuboid", + "type": "Waypoint", + "description": [ + "Task:", + "

Draw a cuboid with relative dimensions of 2x3x4. The cuboid can be represented graphically, or in ASCII art, depending on the language capabilities. To fulfill the criteria of being a cuboid, three faces must be visible.

Either static or rotational projection is acceptable for this task.

", + "Related tasks", + "Draw a rotating cube" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e25", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Draw a rotating cube", + "type": "Waypoint", + "description": [ + "Task", + "

Draw a rotating cube.

It should be oriented with one vertex pointing straight up, and its opposite vertex on the main diagonal (the one farthest away) straight down. It can be solid or wire-frame, and you can use ASCII art if your language doesn't have graphical capabilities. Perspective is optional.

", + "Related tasks", + "Draw a cuboid" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e26", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Draw a sphere", + "type": "Waypoint", + "description": [ + "Task:", + "

Draw a sphere.

The sphere can be represented graphically, or in ASCII art, depending on the language capabilities.

Either static or rotational projection is acceptable for this task.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "{{trans|C}}", + "", + "This Javascript entry uses an HTML wrapper to offer easy running and some interactivity. It is made as such, though, that the entire HTML wrapper can be removed (except for a canvas with id c) and still work. If you remove the HTML, call the draw_sphere function to draw the thing.", + "", + "", + "", + "", + "", + "Draw a sphere", + "", + "", + "", + "R=", + "
", + "k=", + "
", + "ambient=", + "
", + "Unsupportive browser...
", + "", + "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e27", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n\n\n\nDraw a sphere\n\n\n\nR=\n
\nk=\n
\nambient=\n
\nUnsupportive browser...
\n\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Dutch national flag problem", + "type": "Waypoint", + "description": [ + "

The Dutch national flag is composed of three coloured bands in the order red then white and lastly blue. The problem posed by Edsger Dijkstra is:

", + "

Given a number of red, blue and white balls in random order, arrange them in the order of the colours Dutch national flag.

", + "

When the problem was first posed, Dijkstra then went on to successively refine a solution, minimising the number of swaps and the number of times the colour of a ball needed to determined and restricting the balls to end in an array, ...

Task", + "Generate a randomized order of balls ensuring that they are not in the order of the Dutch national flag.", + "Sort the balls in a way idiomatic to your language.", + "Check the sorted balls are in the order of the Dutch national flag.C.f.:", + "Dutch national flag problem", + "Probabilistic analysis of algorithms for the Dutch national flag problem by Wei-Mei Chen. (pdf)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e28", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Dynamic variable names", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a variable with a user-defined name.

The variable name should not be written in the program text, but should be taken from the user dynamically.

", + "See also", + " Eval in environment is a similar task." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var varname = 'foo'; // pretend a user input that", + "var value = 42;", + "eval('var ' + varname + '=' + value);", + "Alternatively, without using eval:", + "var varname = prompt('Variable name:');", + "var value = 42;", + "this[varname] = value;", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e29", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var varname = 'foo'; // pretend a user input that\nvar value = 42;\neval('var ' + varname + '=' + value);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Euler's sum of powers conjecture", + "type": "Waypoint", + "description": [ + "

There is a conjecture in mathematics that held for over two hundred years before it was disproved by the finding of a counterexample in 1966 by Lander and Parkin.

", + "Euler's (disproved) sum of powers conjecture:", + "

At least k positive kth powers are required to sum to a kth power,

", + "

except for the trivial case of one kth power: yk = yk

Lander and Parkin are known to have used a brute-force search on a CDC 6600 computer restricting numbers to those less than 250.

", + "Task:", + "

Write a program to search for an integer solution for:

", + "

", + "

x05 + x15 + x25 + x35 == y5

", + "
", + "

Where all xi's and y are distinct integers between 0 and 250 (exclusive).

Show an answer here.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "var eulers_sum_of_powers = function (iMaxN) {", + "", + " var aPow5 = [];", + " var oPow5ToN = {};", + "", + " for (var iP = 0; iP <= iMaxN; iP++) {", + " var iPow5 = Math.pow(iP, 5);", + " aPow5.push(iPow5);", + " oPow5ToN[iPow5] = iP;", + " }", + "", + " for (var i0 = 1; i0 <= iMaxN; i0++) {", + " for (var i1 = 1; i1 <= i0; i1++) {", + " for (var i2 = 1; i2 <= i1; i2++) {", + " for (var i3 = 1; i3 <= i2; i3++) {", + " var iPow5Sum = aPow5[i0] + aPow5[i1] + aPow5[i2] + aPow5[i3];", + " if (typeof oPow5ToN[iPow5Sum] != 'undefined') {", + " return {", + " i0: i0,", + " i1: i1,", + " i2: i2,", + " i3: i3,", + " iSum: oPow5ToN[iPow5Sum]", + " };", + " }", + " }", + " }", + " }", + " }", + "", + "};", + "", + "var oResult = eulers_sum_of_powers(250);", + "", + "console.log(oResult.i0 + '^5 + ' + oResult.i1 + '^5 + ' + oResult.i2 +", + " '^5 + ' + oResult.i3 + '^5 = ' + oResult.iSum + '^5');", + "", + "{{Out}}", + " 133^5 + 110^5 + 84^5 + 27^5 = 144^5", + "'''This'''{{trans|D}} that verify: a^5 + b^5 + c^5 + d^5 = x^5", + "var N=1000, first=false", + "var ns={}, npv=[]", + "for (var n=0; n<=N; n++) {", + "\tvar np=Math.pow(n,5); ns[np]=n; npv.push(np)", + "}", + "loop:", + "for (var a=1; a<=N; a+=1) ", + "for (var b=a+1; b<=N; b+=1)", + "for (var c=b+1; c<=N; c+=1)", + "for (var d=c+1; d<=N; d+=1) {", + "\tvar x = ns[ npv[a]+npv[b]+npv[c]+npv[d] ]", + "\tif (!x) continue", + "\tprint( [a, b, c, d, x] )", + "\tif (first) break loop", + "}", + "function print(c) {", + "\tvar e='5', ep=e+' + '", + "\tdocument.write(c[0], ep, c[1], ep, c[2], ep, c[3], e, ' = ', c[4], e, '
')", + "}
", + "'''Or this'''{{trans|C}} that verify: a^5 + b^5 + c^5 + d^5 = x^5", + "var N=1000, first=false", + "var npv=[], M=30 // x^5 == x modulo M (=2*3*5) ", + "for (var n=0; n<=N; n+=1) npv[n]=Math.pow(n, 5)", + "var mx=1+npv[N]; while(n<=N+M) npv[n++]=mx", + "", + "loop:", + "for (var a=1; a<=N; a+=1)", + "for (var b=a+1; b<=N; b+=1)", + "for (var c=b+1; c<=N; c+=1)", + "for (var t=npv[a]+npv[b]+npv[c], d=c+1, x=t%M+d; (n=t+npv[d])d", + "\tif (npv[x] != n) continue", + "\tprint( [a, b, c, d, x] )", + "\tif (first) break loop;", + "}", + "function print(c) {", + "\tvar e='5', ep=e+' + '", + "\tdocument.write(c[0], ep, c[1], ep, c[2], ep, c[3], e, ' = ', c[4], e, '
')", + "}
", + "'''Or this'''{{trans|EchoLisp}} that verify: a^5 + b^5 + c^5 = x^5 - d^5", + "var N=1000, first=false", + "var dxs={}, pow=Math.pow ", + "for (var d=1; d<=N; d+=1)", + "\tfor (var dp=pow(d,5), x=d+1; x<=N; x+=1)", + "\t\tdxs[pow(x,5)-dp]=[d,x]", + "loop:", + "for (var a=1; a= dx[0]) continue", + "\tprint( [a, b, c].concat( dx ) ) ", + "\tif (first) break loop", + "}", + "function print(c) {", + "\tvar e='5', ep=e+' + '", + "\tdocument.write(c[0], ep, c[1], ep, c[2], ep, c[3], e, ' = ', c[4], e, '
')", + "}
", + "'''Or this'''{{trans|Python}} that verify: a^5 + b^5 = x^5 - (c^5 + d^5)", + "var N=1000, first=false", + "var is={}, ipv=[], ijs={}, ijpv=[], pow=Math.pow", + "for (var i=1; i<=N; i+=1) {", + "\tvar ip=pow(i,5); is[ip]=i; ipv.push(ip)", + "\tfor (var j=i+1; j<=N; j+=1) {", + "\t\tvar ijp=ip+pow(j,5); ijs[ijp]=[i,j]; ijpv.push(ijp)", + "\t} ", + "}", + "ijpv.sort( function (a,b) {return a - b } )", + "loop:", + "for (var i=0, ei=ipv.length; i= xp) break", + "\tvar cd = ijs[xp-cdp]", + "\tif (!cd) continue", + "\tvar ab = ijs[cdp]", + "\tif (ab[1] >= cd[0]) continue", + "\tprint( [].concat(ab, cd, is[xp]) )", + "\tif (first) break loop", + "}", + "function print(c) {", + "\tvar e='5', ep=e+' + '", + "\tdocument.write(c[0], ep, c[1], ep, c[2], ep, c[3], e, ' = ', c[4], e, '
')", + "}
", + "{{output}}", + " 275 + 845 + 1105 + 133 = 1445", + " 545 + 1685 + 2205 + 266 = 2885", + " 815 + 2525 + 3305 + 399 = 4325", + " 1085 + 3365 + 4405 + 532 = 5765", + " 1355 + 4205 + 5505 + 665 = 7205", + " 1625 + 5045 + 6605 + 798 = 8645", + "", + "===ES6===", + "(() => {", + " 'use strict';", + "", + " const eulersSumOfPowers = intMax => {", + " const", + " pow = Math.pow,", + " xs = range(0, intMax)", + " .map(x => pow(x, 5)),", + " dct = xs.reduce((a, x, i) =>", + " (a[x] = i,", + " a", + " ), {});", + "", + " for (let a = 1; a <= intMax; a++) {", + " for (let b = 2; b <= a; b++) {", + " for (let c = 3; c <= b; c++) {", + " for (let d = 4; d <= c; d++) {", + " const sumOfPower = dct[xs[a] + xs[b] + xs[c] + xs[d]];", + " if (sumOfPower !== undefined) {", + " return [a, b, c, d, sumOfPower];", + " }", + " }", + " }", + " }", + " }", + " return undefined;", + " };", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // TEST", + " const soln = eulersSumOfPowers(250);", + " return soln ? soln.slice(0, 4)", + " .map(x => `${x}^5`)", + " .join(' + ') + ` = ${soln[4]}^5` : 'No solution found.'", + "", + "})();", + "{{Out}}", + "
133^5 + 110^5 + 84^5 + 27^5 = 144^5
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e38", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var eulers_sum_of_powers = function (iMaxN) {\n\n var aPow5 = [];\n var oPow5ToN = {};\n\n for (var iP = 0; iP <= iMaxN; iP++) {\n var iPow5 = Math.pow(iP, 5);\n aPow5.push(iPow5);\n oPow5ToN[iPow5] = iP;\n }\n\n for (var i0 = 1; i0 <= iMaxN; i0++) {\n for (var i1 = 1; i1 <= i0; i1++) {\n for (var i2 = 1; i2 <= i1; i2++) {\n for (var i3 = 1; i3 <= i2; i3++) {\n var iPow5Sum = aPow5[i0] + aPow5[i1] + aPow5[i2] + aPow5[i3];\n if (typeof oPow5ToN[iPow5Sum] != 'undefined') {\n return {\n i0: i0,\n i1: i1,\n i2: i2,\n i3: i3,\n iSum: oPow5ToN[iPow5Sum]\n };\n }\n }\n }\n }\n }\n\n};\n\nvar oResult = eulers_sum_of_powers(250);\n\nconsole.log(oResult.i0 + '^5 + ' + oResult.i1 + '^5 + ' + oResult.i2 +\n '^5 + ' + oResult.i3 + '^5 = ' + oResult.iSum + '^5');\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Evolutionary algorithm", + "type": "Waypoint", + "description": [ + "

Starting with:

", + "The target string: \"METHINKS IT IS LIKE A WEASEL\".", + "An array of random characters chosen from the set of upper-case letters together with the space, and of the same length as the target string. (Call it the parent).", + "A fitness function that computes the ‘closeness’ of its argument to the target string.", + "A mutate function that given a string and a mutation rate returns a copy of the string, with some characters probably mutated.", + "While the parent is not yet the target:* copy the parent C times, each time allowing some random probability that another character might be substituted using mutate.", + "

* Assess the fitness of the parent and all the copies to the target and make the most fit string the new parent, discarding the others.

", + "

* repeat until the parent converges, (hopefully), to the target.

", + "See also:", + " Weasel algorithm.", + " Evolutionary algorithm.", + "

Note: to aid comparison, try and ensure the variables and functions mentioned in the task description appear in solutions

", + "

A cursory examination of a few of the solutions reveals that the instructions have not been followed rigorously in some solutions. Specifically,

", + "While the parent is not yet the target:* copy the parent C times, each time allowing some random probability that another character might be substituted using mutate.

Note that some of the the solutions given retain characters in the mutated string that are correct in the target string. However, the instruction above does not state to retain any of the characters while performing the mutation. Although some may believe to do so is implied from the use of \"converges\"

(:* repeat until the parent converges, (hopefully), to the target.

Strictly speaking, the new parent should be selected from the new pool of mutations, and then the new parent used to generate the next set of mutations with parent characters getting retained only by not being mutated. It then becomes possible that the new set of mutations has no member that is fitter than the parent!

As illustration of this error, the code for 8th has the following remark.

Create a new string based on the TOS, '''changing randomly any characters which

", + "

don't already match the target''':

NOTE: this has been changed, the 8th version is completely random now

Clearly, this algo will be applying the mutation function only to the parent characters that don't match to the target characters!

To ensure that the new parent is never less fit than the prior parent, both the parent and all of the latest mutations are subjected to the fitness test to select the next parent.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Using cross-browser techniques to support Array.reduce and Array.map", + "", + "// ------------------------------------- Cross-browser Compatibility -------------------------------------", + "", + "/* Compatibility code to reduce an array", + " * Source: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce", + " */", + "if (!Array.prototype.reduce) {", + " Array.prototype.reduce = function (fun /*, initialValue */ ) {", + " \"use strict\";", + "", + " if (this === void 0 || this === null) throw new TypeError();", + "", + " var t = Object(this);", + " var len = t.length >>> 0;", + " if (typeof fun !== \"function\") throw new TypeError();", + "", + " // no value to return if no initial value and an empty array", + " if (len == 0 && arguments.length == 1) throw new TypeError();", + "", + " var k = 0;", + " var accumulator;", + " if (arguments.length >= 2) {", + " accumulator = arguments[1];", + " } else {", + " do {", + " if (k in t) {", + " accumulator = t[k++];", + " break;", + " }", + "", + " // if array contains no values, no initial value to return", + " if (++k >= len) throw new TypeError();", + " }", + " while (true);", + " }", + "", + " while (k < len) {", + " if (k in t) accumulator = fun.call(undefined, accumulator, t[k], k, t);", + " k++;", + " }", + "", + " return accumulator;", + " };", + "}", + "", + "/* Compatibility code to map an array", + " * Source: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Map", + " */", + "if (!Array.prototype.map) {", + " Array.prototype.map = function (fun /*, thisp */ ) {", + " \"use strict\";", + "", + " if (this === void 0 || this === null) throw new TypeError();", + "", + " var t = Object(this);", + " var len = t.length >>> 0;", + " if (typeof fun !== \"function\") throw new TypeError();", + "", + " var res = new Array(len);", + " var thisp = arguments[1];", + " for (var i = 0; i < len; i++) {", + " if (i in t) res[i] = fun.call(thisp, t[i], i, t);", + " }", + "", + " return res;", + " };", + "}", + "", + "/* ------------------------------------- Generator -------------------------------------", + " * Generates a fixed length gene sequence via a gene strategy object.", + " * The gene strategy object must have two functions:", + " *\t- \"create\": returns create a new gene ", + " *\t- \"mutate(existingGene)\": returns mutation of an existing gene ", + " */", + "function Generator(length, mutationRate, geneStrategy) {", + " this.size = length;", + " this.mutationRate = mutationRate;", + " this.geneStrategy = geneStrategy;", + "}", + "", + "Generator.prototype.spawn = function () {", + " var genes = [],", + " x;", + " for (x = 0; x < this.size; x += 1) {", + " genes.push(this.geneStrategy.create());", + " }", + " return genes;", + "};", + "", + "Generator.prototype.mutate = function (parent) {", + " return parent.map(function (char) {", + " if (Math.random() > this.mutationRate) {", + " return char;", + " }", + " return this.geneStrategy.mutate(char);", + " }, this);", + "};", + "", + "/* ------------------------------------- Population -------------------------------------", + " * Helper class that holds and spawns a new population.", + " */", + "function Population(size, generator) {", + " this.size = size;", + " this.generator = generator;", + "", + " this.population = [];", + " // Build initial popuation;", + " for (var x = 0; x < this.size; x += 1) {", + " this.population.push(this.generator.spawn());", + " }", + "}", + "", + "Population.prototype.spawn = function (parent) {", + " this.population = [];", + " for (var x = 0; x < this.size; x += 1) {", + " this.population.push(this.generator.mutate(parent));", + " }", + "};", + "", + "/* ------------------------------------- Evolver -------------------------------------", + " * Attempts to converge a population based a fitness strategy object.", + " * The fitness strategy object must have three function ", + " *\t- \"score(individual)\": returns a score for an individual.", + " *\t- \"compare(scoreA, scoreB)\": return true if scoreA is better (ie more fit) then scoreB", + " *\t- \"done( score )\": return true if score is acceptable (ie we have successfully converged). ", + " */", + "function Evolver(size, generator, fitness) {", + " this.done = false;", + " this.fitness = fitness;", + " this.population = new Population(size, generator);", + "}", + "", + "Evolver.prototype.getFittest = function () {", + " return this.population.population.reduce(function (best, individual) {", + " var currentScore = this.fitness.score(individual);", + " if (best === null || this.fitness.compare(currentScore, best.score)) {", + " return {", + " score: currentScore,", + " individual: individual", + " };", + " } else {", + " return best;", + " }", + " }, null);", + "};", + "", + "Evolver.prototype.doGeneration = function () {", + " this.fittest = this.getFittest();", + " this.done = this.fitness.done(this.fittest.score);", + " if (!this.done) {", + " this.population.spawn(this.fittest.individual);", + " }", + "};", + "", + "Evolver.prototype.run = function (onCheckpoint, checkPointFrequency) {", + " checkPointFrequency = checkPointFrequency || 10; // Default to Checkpoints every 10 generations", + " var generation = 0;", + " while (!this.done) {", + " this.doGeneration();", + " if (generation % checkPointFrequency === 0) {", + " onCheckpoint(generation, this.fittest);", + " }", + " generation += 1;", + " }", + " onCheckpoint(generation, this.fittest);", + " return this.fittest;", + "};", + "", + "// ------------------------------------- Exports -------------------------------------", + "window.Generator = Generator;", + "window.Evolver = Evolver;", + "", + "", + "// helper utitlity to combine elements of two arrays.", + "Array.prototype.zip = function (b, func) {", + " var result = [],", + " max = Math.max(this.length, b.length),", + " x;", + " for (x = 0; x < max; x += 1) {", + " result.push(func(this[x], b[x]));", + " }", + " return result;", + "};", + "", + "var target = \"METHINKS IT IS LIKE A WEASEL\", geneStrategy, fitness, target, generator, evolver, result;", + " ", + "geneStrategy = {", + " // The allowed character set (as an array) ", + " characterSet: \"ABCDEFGHIJKLMNOPQRSTUVWXYZ \".split(\"\"),", + "", + " /*", + " Pick a random character from the characterSet", + " */", + " create: function getRandomGene() {", + " var randomNumber = Math.floor(Math.random() * this.characterSet.length);", + " return this.characterSet[randomNumber];", + " }", + "};", + "geneStrategy.mutate = geneStrategy.create; // Our mutation stragtegy is to simply get a random gene", + "fitness = {", + " // The target (as an array of characters)", + " target: target.split(\"\"),", + " equal: function (geneA, geneB) {", + " return (geneA === geneB ? 0 : 1);", + " },", + " sum: function (runningTotal, value) {", + " return runningTotal + value;", + " },", + "", + " /*", + " We give one point to for each corect letter", + " */", + " score: function (genes) {", + " var diff = genes.zip(this.target, this.equal); // create an array of ones and zeros ", + " return diff.reduce(this.sum, 0); // Sum the array values together.", + " },", + " compare: function (scoreA, scoreB) {", + " return scoreA <= scoreB; // Lower scores are better", + " },", + " done: function (score) {", + " return score === 0; // We have matched the target string.", + " }", + "};", + "", + "generator = new Generator(target.length, 0.05, geneStrategy);", + "evolver = new Evolver(100, generator, fitness);", + "", + "function showProgress(generation, fittest) {", + " document.write(\"Generation: \" + generation + \", Best: \" + fittest.individual.join(\"\") + \", fitness:\" + fittest.score + \"
\");", + "}", + "result = evolver.run(showProgress);
", + "Output:", + "
",
+      "Generation: 0, Best: KSTFOKJC XZYLWCLLGYZJNXYEGHE, fitness:25",
+      "Generation: 10, Best: KOTFINJC XX LS LIGYZT WEPSHL, fitness:14",
+      "Generation: 20, Best: KBTHINKS BT LS LIGNZA WEPSEL, fitness:8",
+      "Generation: 30, Best: KETHINKS IT BS LISNZA WEASEL, fitness:5",
+      "Generation: 40, Best: KETHINKS IT IS LIKEZA WEASEL, fitness:2",
+      "Generation: 50, Best: METHINKS IT IS LIKEZA WEASEL, fitness:1",
+      "Generation: 52, Best: METHINKS IT IS LIKE A WEASEL, fitness:0",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e3c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// ------------------------------------- Cross-browser Compatibility -------------------------------------\n\n/* Compatibility code to reduce an array\n * Source: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce\n */\nif (!Array.prototype.reduce) {\n Array.prototype.reduce = function (fun /*, initialValue */ ) {\n \"use strict\";\n\n if (this === void 0 || this === null) throw new TypeError();\n\n var t = Object(this);\n var len = t.length >>> 0;\n if (typeof fun !== \"function\") throw new TypeError();\n\n // no value to return if no initial value and an empty array\n if (len == 0 && arguments.length == 1) throw new TypeError();\n\n var k = 0;\n var accumulator;\n if (arguments.length >= 2) {\n accumulator = arguments[1];\n } else {\n do {\n if (k in t) {\n accumulator = t[k++];\n break;\n }\n\n // if array contains no values, no initial value to return\n if (++k >= len) throw new TypeError();\n }\n while (true);\n }\n\n while (k < len) {\n if (k in t) accumulator = fun.call(undefined, accumulator, t[k], k, t);\n k++;\n }\n\n return accumulator;\n };\n}\n\n/* Compatibility code to map an array\n * Source: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Map\n */\nif (!Array.prototype.map) {\n Array.prototype.map = function (fun /*, thisp */ ) {\n \"use strict\";\n\n if (this === void 0 || this === null) throw new TypeError();\n\n var t = Object(this);\n var len = t.length >>> 0;\n if (typeof fun !== \"function\") throw new TypeError();\n\n var res = new Array(len);\n var thisp = arguments[1];\n for (var i = 0; i < len; i++) {\n if (i in t) res[i] = fun.call(thisp, t[i], i, t);\n }\n\n return res;\n };\n}\n\n/* ------------------------------------- Generator -------------------------------------\n * Generates a fixed length gene sequence via a gene strategy object.\n * The gene strategy object must have two functions:\n *\t- \"create\": returns create a new gene \n *\t- \"mutate(existingGene)\": returns mutation of an existing gene \n */\nfunction Generator(length, mutationRate, geneStrategy) {\n this.size = length;\n this.mutationRate = mutationRate;\n this.geneStrategy = geneStrategy;\n}\n\nGenerator.prototype.spawn = function () {\n var genes = [],\n x;\n for (x = 0; x < this.size; x += 1) {\n genes.push(this.geneStrategy.create());\n }\n return genes;\n};\n\nGenerator.prototype.mutate = function (parent) {\n return parent.map(function (char) {\n if (Math.random() > this.mutationRate) {\n return char;\n }\n return this.geneStrategy.mutate(char);\n }, this);\n};\n\n/* ------------------------------------- Population -------------------------------------\n * Helper class that holds and spawns a new population.\n */\nfunction Population(size, generator) {\n this.size = size;\n this.generator = generator;\n\n this.population = [];\n // Build initial popuation;\n for (var x = 0; x < this.size; x += 1) {\n this.population.push(this.generator.spawn());\n }\n}\n\nPopulation.prototype.spawn = function (parent) {\n this.population = [];\n for (var x = 0; x < this.size; x += 1) {\n this.population.push(this.generator.mutate(parent));\n }\n};\n\n/* ------------------------------------- Evolver -------------------------------------\n * Attempts to converge a population based a fitness strategy object.\n * The fitness strategy object must have three function \n *\t- \"score(individual)\": returns a score for an individual.\n *\t- \"compare(scoreA, scoreB)\": return true if scoreA is better (ie more fit) then scoreB\n *\t- \"done( score )\": return true if score is acceptable (ie we have successfully converged). \n */\nfunction Evolver(size, generator, fitness) {\n this.done = false;\n this.fitness = fitness;\n this.population = new Population(size, generator);\n}\n\nEvolver.prototype.getFittest = function () {\n return this.population.population.reduce(function (best, individual) {\n var currentScore = this.fitness.score(individual);\n if (best === null || this.fitness.compare(currentScore, best.score)) {\n return {\n score: currentScore,\n individual: individual\n };\n } else {\n return best;\n }\n }, null);\n};\n\nEvolver.prototype.doGeneration = function () {\n this.fittest = this.getFittest();\n this.done = this.fitness.done(this.fittest.score);\n if (!this.done) {\n this.population.spawn(this.fittest.individual);\n }\n};\n\nEvolver.prototype.run = function (onCheckpoint, checkPointFrequency) {\n checkPointFrequency = checkPointFrequency || 10; // Default to Checkpoints every 10 generations\n var generation = 0;\n while (!this.done) {\n this.doGeneration();\n if (generation % checkPointFrequency === 0) {\n onCheckpoint(generation, this.fittest);\n }\n generation += 1;\n }\n onCheckpoint(generation, this.fittest);\n return this.fittest;\n};\n\n// ------------------------------------- Exports -------------------------------------\nwindow.Generator = Generator;\nwindow.Evolver = Evolver;\n\n\n// helper utitlity to combine elements of two arrays.\nArray.prototype.zip = function (b, func) {\n var result = [],\n max = Math.max(this.length, b.length),\n x;\n for (x = 0; x < max; x += 1) {\n result.push(func(this[x], b[x]));\n }\n return result;\n};\n\nvar target = \"METHINKS IT IS LIKE A WEASEL\", geneStrategy, fitness, target, generator, evolver, result;\n \ngeneStrategy = {\n // The allowed character set (as an array) \n characterSet: \"ABCDEFGHIJKLMNOPQRSTUVWXYZ \".split(\"\"),\n\n /*\n Pick a random character from the characterSet\n */\n create: function getRandomGene() {\n var randomNumber = Math.floor(Math.random() * this.characterSet.length);\n return this.characterSet[randomNumber];\n }\n};\ngeneStrategy.mutate = geneStrategy.create; // Our mutation stragtegy is to simply get a random gene\nfitness = {\n // The target (as an array of characters)\n target: target.split(\"\"),\n equal: function (geneA, geneB) {\n return (geneA === geneB ? 0 : 1);\n },\n sum: function (runningTotal, value) {\n return runningTotal + value;\n },\n\n /*\n We give one point to for each corect letter\n */\n score: function (genes) {\n var diff = genes.zip(this.target, this.equal); // create an array of ones and zeros \n return diff.reduce(this.sum, 0); // Sum the array values together.\n },\n compare: function (scoreA, scoreB) {\n return scoreA <= scoreB; // Lower scores are better\n },\n done: function (score) {\n return score === 0; // We have matched the target string.\n }\n};\n\ngenerator = new Generator(target.length, 0.05, geneStrategy);\nevolver = new Evolver(100, generator, fitness);\n\nfunction showProgress(generation, fittest) {\n document.write(\"Generation: \" + generation + \", Best: \" + fittest.individual.join(\"\") + \", fitness:\" + fittest.score + \"
\");\n}\nresult = evolver.run(showProgress);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Execute HQ9+", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement a HQ9+ interpreter or compiler.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "The function below executes a HQ9+ program and returns the program output as a string.", + "function hq9plus(code) {", + " var out = '';", + " var acc = 0;", + " ", + " for (var i=0; i1; j--) {", + " out += j + \" bottles of beer on the wall, \" + j + \" bottles of beer.\\n\";", + " out += \"Take one down and pass it around, \" + (j-1) + \" bottles of beer.\\n\\n\";", + " }", + " out += \"1 bottle of beer on the wall, 1 bottle of beer.\\n\" +", + " \"Take one down and pass it around, no more bottles of beer on the wall.\\n\\n\" +", + " \"No more bottles of beer on the wall, no more bottles of beer.\\n\" +", + " \"Go to the store and buy some more, 99 bottles of beer on the wall.\\n\";", + " break;", + " case '+': acc++; break;", + " }", + " }", + " return out;", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e43", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function hq9plus(code) {\n var out = '';\n var acc = 0;\n \n for (var i=0; i1; j--) {\n out += j + \" bottles of beer on the wall, \" + j + \" bottles of beer.\\n\";\n out += \"Take one down and pass it around, \" + (j-1) + \" bottles of beer.\\n\\n\";\n }\n out += \"1 bottle of beer on the wall, 1 bottle of beer.\\n\" +\n \"Take one down and pass it around, no more bottles of beer on the wall.\\n\\n\" +\n \"No more bottles of beer on the wall, no more bottles of beer.\\n\" +\n \"Go to the store and buy some more, 99 bottles of beer on the wall.\\n\";\n break;\n case '+': acc++; break;\n }\n }\n return out;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Execute SNUSP", + "type": "Waypoint", + "description": [ + "

RCSNUSP is a set of SNUSP compilers and interpreters written for Rosetta Code in a variety of languages. Below are links to each of the versions of RCSNUSP.

An implementation need only properly implement the Core SNUSP instructions ('$', '\\', '/', '+', '-', '<', '>', ',', '.', '!', and '?'). Modular SNUSP ('#', '@') and Bloated SNUSP (':', ';', '%', and '&') are also allowed, but not required. Any extra characters that you implement should be noted in the description of your implementation. Any cell size is allowed, EOF support is optional, as is whether you have bounded or unbounded memory.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "See [[RCSNUSP/JavaScript]].", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e44", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["null\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "FASTA format", + "type": "Waypoint", + "description": [ + "

In bioinformatics, long character strings are often encoded in a format called FASTA.

A FASTA file can contain several strings, each identified by a name marked by a > (greater than) character at the beginning of the line.

", + "Task:", + "

Write a program that reads a FASTA file such as:

", + "
",
+      ">Rosetta_Example_1",
+      "THERECANBENOSPACE",
+      ">Rosetta_Example_2",
+      "THERECANBESEVERAL",
+      "LINESBUTTHEYALLMUST",
+      "BECONCATENATED",
+      "
",
+      "Rosetta_Example_1: THERECANBENOSPACE",
+      "Rosetta_Example_2: THERECANBESEVERALLINESBUTTHEYALLMUSTBECONCATENATED",
+      "
", + "

Note that a high-quality implementation will not hold the entire file in memory at once; real FASTA files can be multiple gigabytes in size.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e4e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Fast Fourier transform", + "type": "Waypoint", + "description": [ + "Task:", + "

Calculate the FFT (Fast Fourier Transform) of an input sequence.

The most general case allows for complex numbers at the input

", + "

and results in a sequence of equal length, again of complex numbers.

", + "

If you need to restrict yourself to real numbers, the output should

", + "

be the magnitude (i.e. sqrt(re²+im²)) of the complex result.

The classic version is the recursive Cooley–Tukey FFT. Wikipedia has pseudo-code for that.

", + "

Further optimizations are possible but not required.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Complex fourier transform & it's inverse reimplemented from the C++ & Python", + "variants on this page.", + "", + "/*", + "complex fast fourier transform and inverse from", + "http://rosettacode.org/wiki/Fast_Fourier_transform#C.2B.2B", + "*/", + "function icfft(amplitudes)", + "{", + "\tvar N = amplitudes.length;", + "\tvar iN = 1 / N;", + "\t", + "\t//conjugate if imaginary part is not 0", + "\tfor(var i = 0 ; i < N; ++i)", + "\t\tif(amplitudes[i] instanceof Complex)", + "\t\t\tamplitudes[i].im = -amplitudes[i].im;", + "\t\t\t", + "\t//apply fourier transform", + "\tamplitudes = cfft(amplitudes)", + "\t", + "\tfor(var i = 0 ; i < N; ++i)", + "\t{", + "\t\t//conjugate again", + "\t\tamplitudes[i].im = -amplitudes[i].im;", + "\t\t//scale", + "\t\tamplitudes[i].re *= iN;", + "\t\tamplitudes[i].im *= iN;", + "\t}", + "\treturn amplitudes;", + "}", + "", + "function cfft(amplitudes)", + "{", + "\tvar N = amplitudes.length;", + "\tif( N <= 1 )", + "\t\treturn amplitudes;", + "\t", + "\tvar hN = N / 2;", + "\tvar even = [];", + "\tvar odd = [];", + "\teven.length = hN;", + "\todd.length = hN;", + "\tfor(var i = 0; i < hN; ++i)", + "\t{", + "\t\teven[i] = amplitudes[i*2];", + "\t\todd[i] = amplitudes[i*2+1];", + "\t}", + "\teven = cfft(even);", + "\todd = cfft(odd);", + "\t", + "\tvar a = -2*Math.PI;", + "\tfor(var k = 0; k < hN; ++k)", + "\t{", + "\t\tif(!(even[k] instanceof Complex))", + "\t\t\teven[k] = new Complex(even[k], 0);", + "\t\tif(!(odd[k] instanceof Complex))", + "\t\t\todd[k] = new Complex(odd[k], 0);", + "\t\tvar p = k/N;", + "\t\tvar t = new Complex(0, a * p);", + "\t\tt.cexp(t).mul(odd[k], t);", + "\t\tamplitudes[k] = even[k].add(t, odd[k]);", + "\t\tamplitudes[k + hN] = even[k].sub(t, even[k]);", + "\t}", + "\treturn amplitudes;", + "}", + "", + "//test code", + "//console.log( cfft([1,1,1,1,0,0,0,0]) );", + "//console.log( icfft(cfft([1,1,1,1,0,0,0,0])) );", + "Very very basic Complex number that provides only the components", + "required by the code above.", + "/*", + "basic complex number arithmetic from ", + "http://rosettacode.org/wiki/Fast_Fourier_transform#Scala", + "*/", + "function Complex(re, im) ", + "{", + "\tthis.re = re;", + "\tthis.im = im || 0.0;", + "}", + "Complex.prototype.add = function(other, dst)", + "{", + "\tdst.re = this.re + other.re;", + "\tdst.im = this.im + other.im;", + "\treturn dst;", + "}", + "Complex.prototype.sub = function(other, dst)", + "{", + "\tdst.re = this.re - other.re;", + "\tdst.im = this.im - other.im;", + "\treturn dst;", + "}", + "Complex.prototype.mul = function(other, dst)", + "{", + "\t//cache re in case dst === this", + "\tvar r = this.re * other.re - this.im * other.im;", + "\tdst.im = this.re * other.im + this.im * other.re;", + "\tdst.re = r;", + "\treturn dst;", + "}", + "Complex.prototype.cexp = function(dst)", + "{", + "\tvar er = Math.exp(this.re);", + "\tdst.re = er * Math.cos(this.im);", + "\tdst.im = er * Math.sin(this.im);", + "\treturn dst;", + "}", + "Complex.prototype.log = function()", + "{", + "\t/*", + "\talthough 'It's just a matter of separating out the real and imaginary parts of jw.' is not a helpful quote", + "\tthe actual formula I found here and the rest was just fiddling / testing and comparing with correct results.", + "\thttp://cboard.cprogramming.com/c-programming/89116-how-implement-complex-exponential-functions-c.html#post637921", + "\t*/", + "\tif( !this.re )", + "\t\tconsole.log(this.im.toString()+'j');", + "\telse if( this.im < 0 )", + "\t\tconsole.log(this.re.toString()+this.im.toString()+'j');", + "\telse", + "\t\tconsole.log(this.re.toString()+'+'+this.im.toString()+'j');", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e4f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "/*\ncomplex fast fourier transform and inverse from\nhttp://rosettacode.org/wiki/Fast_Fourier_transform#C.2B.2B\n*/\nfunction icfft(amplitudes)\n{\n\tvar N = amplitudes.length;\n\tvar iN = 1 / N;\n\t\n\t//conjugate if imaginary part is not 0\n\tfor(var i = 0 ; i < N; ++i)\n\t\tif(amplitudes[i] instanceof Complex)\n\t\t\tamplitudes[i].im = -amplitudes[i].im;\n\t\t\t\n\t//apply fourier transform\n\tamplitudes = cfft(amplitudes)\n\t\n\tfor(var i = 0 ; i < N; ++i)\n\t{\n\t\t//conjugate again\n\t\tamplitudes[i].im = -amplitudes[i].im;\n\t\t//scale\n\t\tamplitudes[i].re *= iN;\n\t\tamplitudes[i].im *= iN;\n\t}\n\treturn amplitudes;\n}\n\nfunction cfft(amplitudes)\n{\n\tvar N = amplitudes.length;\n\tif( N <= 1 )\n\t\treturn amplitudes;\n\t\n\tvar hN = N / 2;\n\tvar even = [];\n\tvar odd = [];\n\teven.length = hN;\n\todd.length = hN;\n\tfor(var i = 0; i < hN; ++i)\n\t{\n\t\teven[i] = amplitudes[i*2];\n\t\todd[i] = amplitudes[i*2+1];\n\t}\n\teven = cfft(even);\n\todd = cfft(odd);\n\t\n\tvar a = -2*Math.PI;\n\tfor(var k = 0; k < hN; ++k)\n\t{\n\t\tif(!(even[k] instanceof Complex))\n\t\t\teven[k] = new Complex(even[k], 0);\n\t\tif(!(odd[k] instanceof Complex))\n\t\t\todd[k] = new Complex(odd[k], 0);\n\t\tvar p = k/N;\n\t\tvar t = new Complex(0, a * p);\n\t\tt.cexp(t).mul(odd[k], t);\n\t\tamplitudes[k] = even[k].add(t, odd[k]);\n\t\tamplitudes[k + hN] = even[k].sub(t, even[k]);\n\t}\n\treturn amplitudes;\n}\n\n//test code\n//console.log( cfft([1,1,1,1,0,0,0,0]) );\n//console.log( icfft(cfft([1,1,1,1,0,0,0,0])) );\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Filter", + "type": "Waypoint", + "description": [ + "Task:", + "

Select certain elements from an Array into a new Array in a generic way.

", + "

To demonstrate, select all even numbers from an Array.

As an option, give a second solution which filters destructively,

", + "

by modifying the original Array rather than creating a new Array.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "The standard way is to use the [https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/filter Array.prototype.filter] function ({{works with|JavaScript|1.6}}):", + "var arr = [1,2,3,4,5];", + "var evens = arr.filter(function(a) {return a % 2 == 0});", + "", + "Other ways:", + "var arr = [1,2,3,4,5];", + "var evens = [];", + "for (var i=0, ilen=arr.length; i", + "", + "{{works with|Firefox|2.0}}", + "", + "var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];", + "var evens = [i for (i in numbers) if (i % 2 == 0)];", + "", + "function range(limit) {", + " for(var i = 0; i < limit; i++) {", + " yield i;", + " }", + "}", + "", + "var evens2 = [i for (i in range(100)) if (i % 2 == 0)];", + "", + "{{libheader|Functional}}", + "Functional.select(\"+1&1\", [1,2,3,4]) // [2, 4]", + "", + "===ES6===", + "", + "(() => {", + " 'use strict';", + "", + " // isEven :: Int -> Bool", + " const isEven = n => n % 2 === 0;", + "", + "", + " // TEST", + " ", + " return [1,2,3,4,5,6,7,8,9]", + " .filter(isEven);", + "", + " // [2, 4, 6, 8]", + "})();", + "", + "{{Out}}", + "[2, 4, 6, 8]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e57", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var arr = [1,2,3,4,5];\nvar evens = arr.filter(function(a) {return a % 2 == 0});\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Find common directory path", + "type": "Waypoint", + "description": [ + "

Create a routine that, given a set of strings representing directory paths and a single character directory separator, will return a string representing that part of the directory tree that is common to all the directories.

Test your routine using the forward slash '/' character as the directory separator and the following three strings as input paths:

", + "

'/home/user1/tmp/coverage/test'

", + "

'/home/user1/tmp/covert/operator'

", + "

'/home/user1/tmp/coven/members'

Note: The resultant path should be the valid directory '/home/user1/tmp' and not the longest common string '/home/user1/tmp/cove'.

", + "

If your language has a routine that performs this function (even if it does not have a changeable separator character), then mention it as part of the task.

", + "Related tasks", + "Longest common prefix" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e58", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Find largest left truncatable prime in a given base", + "type": "Waypoint", + "description": [ + "

A truncatable prime is one where all non-empty substrings that finish at the end of the number (right-substrings) are also primes when understood as numbers in a particular base. The largest such prime in a given (integer) base is therefore computable, provided the base is larger than 2.

Let's consider what happens in base 10. Obviously the right most digit must be prime, so in base 10 candidates are 2,3,5,7. Putting a digit in the range 1 to base-1 in front of each candidate must result in a prime. So 2 and 5, like the whale and the petunias in The Hitchhiker's Guide to the Galaxy, come into existence only to be extinguished before they have time to realize it, because 2 and 5 preceded by any digit in the range 1 to base-1 is not prime. Some numbers formed by preceding 3 or 7 by a digit in the range 1 to base-1 are prime. So 13,17,23,37,43,47,53,67,73,83,97 are candidates. Again, putting a digit in the range 1 to base-1 in front of each candidate must be a prime. Repeating until there are no larger candidates finds the largest left truncatable prime.

Let's work base 3 by hand:

0 and 1 are not prime so the last digit must be 2. 123 = 510 which is prime, 223 = 810 which is not so 123 is the only candidate. 1123 = 1410 which is not prime, 2123 = 2310 which is, so 2123 is the only candidate. 12123 = 5010 which is not prime, 22123 = 7710 which also is not prime. So there are no more candidates, therefore 23 is the largest left truncatable prime in base 3.

The task is to reconstruct as much, and possibly more, of the table in the OEIS as you are able.

Related Tasks:

", + "Miller-Rabin primality test" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e59", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Find palindromic numbers in both binary and ternary bases", + "type": "Waypoint", + "description": [ + "The task:

Find and show (in decimal) the first six numbers (non-negative integers) that are palindromes in both base 2 and base 3.

Use zero (0) as the first number found, even though some other definitions ignore it.

Optionally, show the decimal number found in its binary and ternary form.

It's permissible to assume the first two numbers and simply list them.

", + "See also", + " Sequence A60792, numbers that are palindromic in bases 2 and 3 on The On-Line Encyclopedia of Integer Sequences." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // compose :: (b -> c) -> (a -> b) -> (a -> c)", + " const compose = (f, g) => x => f(g(x));", + "", + " // listApply :: [(a -> b)] -> [a] -> [b]", + " const listApply = (fs, xs) =>", + " [].concat.apply([], fs.map(f =>", + " [].concat.apply([], xs.map(x => [f(x)]))));", + "", + " // pure :: a -> [a]", + " const pure = x => [x];", + "", + " // curry :: Function -> Function", + " const curry = (f, ...args) => {", + " const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :", + " function () {", + " return go(xs.concat([].slice.apply(arguments)));", + " };", + " return go([].slice.call(args, 1));", + " };", + "", + " // transpose :: [[a]] -> [[a]]", + " const transpose = xs =>", + " xs[0].map((_, iCol) => xs.map(row => row[iCol]));", + "", + " // reverse :: [a] -> [a]", + " const reverse = xs =>", + " typeof xs === 'string' ? (", + " xs.split('')", + " .reverse()", + " .join('')", + " ) : xs.slice(0)", + " .reverse();", + "", + " // take :: Int -> [a] -> [a]", + " const take = (n, xs) => xs.slice(0, n);", + "", + " // drop :: Int -> [a] -> [a]", + " const drop = (n, xs) => xs.slice(n);", + "", + " // maximum :: [a] -> a", + " const maximum = xs =>", + " xs.reduce((a, x) => (x > a || a === undefined ? x : a), undefined);", + "", + " // quotRem :: Integral a => a -> a -> (a, a)", + " const quotRem = (m, n) => [Math.floor(m / n), m % n];", + "", + " // length :: [a] -> Int", + " const length = xs => xs.length;", + "", + " // justifyLeft :: Int -> Char -> Text -> Text", + " const justifyLeft = (n, cFiller, strText) =>", + " n > strText.length ? (", + " (strText + cFiller.repeat(n))", + " .substr(0, n)", + " ) : strText;", + "", + " // unwords :: [String] -> String", + " const unwords = xs => xs.join(' ');", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + "", + " // BASES AND PALINDROMES", + "", + " // show, showBinary, showTernary :: Int -> String", + " const show = n => n.toString(10);", + " const showBinary = n => n.toString(2);", + " const showTernary = n => n.toString(3);", + "", + " // readBase3 :: String -> Int", + " const readBase3 = s => parseInt(s, 3);", + "", + " // base3Palindrome :: Int -> String", + " const base3Palindrome = n => {", + " const s = showTernary(n);", + " return s + '1' + reverse(s);", + " };", + "", + " // isBinPal :: Int -> Bool", + " const isBinPal = n => {", + " const", + " s = showBinary(n),", + " [q, r] = quotRem(s.length, 2);", + " return (r !== 0) && drop(q + 1, s) === reverse(take(q, s));", + " };", + "", + " // solutions :: [Int]", + " const solutions = [0, 1].concat(range(1, 10E5)", + " .map(compose(readBase3, base3Palindrome))", + " .filter(isBinPal));", + "", + " // TABULATION", + "", + " // cols :: [[Int]]", + " const cols = transpose(", + " [", + " ['Decimal', 'Ternary', 'Binary']", + " ].concat(", + " solutions.map(", + " compose(", + " xs => listApply([show, showTernary, showBinary], xs),", + " pure", + " )", + " )", + " )", + " );", + "", + " return unlines(", + " transpose(cols.map(col => col.map(", + " curry(justifyLeft)(maximum(col.map(length)) + 1, ' ')", + " )))", + " .map(unwords));", + "})();", + "{{Out}}", + "
Decimal      Ternary                  Binary                                ",
+      "0            0                        0                                     ",
+      "1            1                        1                                     ",
+      "6643         100010001                1100111110011                         ",
+      "1422773      2200021200022            101011011010110110101                 ",
+      "5415589      101012010210101          10100101010001010100101               ",
+      "90396755477  22122022220102222022122  1010100001100000100010000011000010101 
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e5b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // GENERIC FUNCTIONS\n\n // range :: Int -> Int -> [Int]\n const range = (m, n) =>\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i);\n\n // compose :: (b -> c) -> (a -> b) -> (a -> c)\n const compose = (f, g) => x => f(g(x));\n\n // listApply :: [(a -> b)] -> [a] -> [b]\n const listApply = (fs, xs) =>\n [].concat.apply([], fs.map(f =>\n [].concat.apply([], xs.map(x => [f(x)]))));\n\n // pure :: a -> [a]\n const pure = x => [x];\n\n // curry :: Function -> Function\n const curry = (f, ...args) => {\n const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :\n function () {\n return go(xs.concat([].slice.apply(arguments)));\n };\n return go([].slice.call(args, 1));\n };\n\n // transpose :: [[a]] -> [[a]]\n const transpose = xs =>\n xs[0].map((_, iCol) => xs.map(row => row[iCol]));\n\n // reverse :: [a] -> [a]\n const reverse = xs =>\n typeof xs === 'string' ? (\n xs.split('')\n .reverse()\n .join('')\n ) : xs.slice(0)\n .reverse();\n\n // take :: Int -> [a] -> [a]\n const take = (n, xs) => xs.slice(0, n);\n\n // drop :: Int -> [a] -> [a]\n const drop = (n, xs) => xs.slice(n);\n\n // maximum :: [a] -> a\n const maximum = xs =>\n xs.reduce((a, x) => (x > a || a === undefined ? x : a), undefined);\n\n // quotRem :: Integral a => a -> a -> (a, a)\n const quotRem = (m, n) => [Math.floor(m / n), m % n];\n\n // length :: [a] -> Int\n const length = xs => xs.length;\n\n // justifyLeft :: Int -> Char -> Text -> Text\n const justifyLeft = (n, cFiller, strText) =>\n n > strText.length ? (\n (strText + cFiller.repeat(n))\n .substr(0, n)\n ) : strText;\n\n // unwords :: [String] -> String\n const unwords = xs => xs.join(' ');\n\n // unlines :: [String] -> String\n const unlines = xs => xs.join('\\n');\n\n\n // BASES AND PALINDROMES\n\n // show, showBinary, showTernary :: Int -> String\n const show = n => n.toString(10);\n const showBinary = n => n.toString(2);\n const showTernary = n => n.toString(3);\n\n // readBase3 :: String -> Int\n const readBase3 = s => parseInt(s, 3);\n\n // base3Palindrome :: Int -> String\n const base3Palindrome = n => {\n const s = showTernary(n);\n return s + '1' + reverse(s);\n };\n\n // isBinPal :: Int -> Bool\n const isBinPal = n => {\n const\n s = showBinary(n),\n [q, r] = quotRem(s.length, 2);\n return (r !== 0) && drop(q + 1, s) === reverse(take(q, s));\n };\n\n // solutions :: [Int]\n const solutions = [0, 1].concat(range(1, 10E5)\n .map(compose(readBase3, base3Palindrome))\n .filter(isBinPal));\n\n // TABULATION\n\n // cols :: [[Int]]\n const cols = transpose(\n [\n ['Decimal', 'Ternary', 'Binary']\n ].concat(\n solutions.map(\n compose(\n xs => listApply([show, showTernary, showBinary], xs),\n pure\n )\n )\n )\n );\n\n return unlines(\n transpose(cols.map(col => col.map(\n curry(justifyLeft)(maximum(col.map(length)) + 1, ' ')\n )))\n .map(unwords));\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Find the last Sunday of each month", + "type": "Waypoint", + "description": [ + "

Write a program or a script that returns the last Sundays of each month of a given year. The year may be given through any simple input method in your language (command line, std in, etc).

Example of an expected output:

./last_sundays 2013",
+      "2013-01-27",
+      "2013-02-24",
+      "2013-03-31",
+      "2013-04-28",
+      "2013-05-26",
+      "2013-06-30",
+      "2013-07-28",
+      "2013-08-25",
+      "2013-09-29",
+      "2013-10-27",
+      "2013-11-24",
+      "2013-12-29
", + "Related tasks", + "Day of the week", + "Five weekends", + "Last Friday of each month" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Iteration====", + "function lastSundayOfEachMonths(year) {", + "\tvar lastDay = [31,28,31,30,31,30,31,31,30,31,30,31]", + "\tif (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) lastDay[2] = 29", + "\tfor (var date = new Date(), month=0; month<12; month+=1) {", + "\t\tdate.setFullYear(year, month, lastDay[month])", + "\t\tdate.setDate(date.getDate()-date.getDay())", + "\t\tdocument.write(date.toISOString().substring(0,10), '
')", + "\t} ", + "}", + "\t", + "lastSundayOfEachMonths(2013)
", + "{{output}}", + "
2013-01-27",
+      "2013-02-24",
+      "2013-03-31",
+      "2013-04-28",
+      "2013-05-26",
+      "2013-06-30",
+      "2013-07-28",
+      "2013-08-25",
+      "2013-09-29",
+      "2013-10-27",
+      "2013-11-24",
+      "2013-12-29
", + "", + "====Functional composition====", + "(function () {", + " 'use strict';", + "", + " // lastSundaysOfYear :: Int -> [Date]", + " function lastSundaysOfYear(y) {", + " return lastWeekDaysOfYear(y, days.sunday);", + " }", + "", + " // lastWeekDaysOfYear :: Int -> Int -> [Date]", + " function lastWeekDaysOfYear(y, iWeekDay) {", + " return [", + " 31,", + " 0 === y % 4 && 0 !== y % 100 || 0 === y % 400 ? 29 : 28,", + " 31, 30, 31, 30, 31, 31, 30, 31, 30, 31", + " ]", + " .map(function (d, m) {", + " var dte = new Date(Date.UTC(y, m, d));", + "", + " return new Date(Date.UTC(", + " y, m, d - (", + " (dte.getDay() + (7 - iWeekDay)) % 7", + " )", + " ));", + " });", + " }", + "", + " // isoDateString :: Date -> String", + " function isoDateString(dte) {", + " return dte.toISOString()", + " .substr(0, 10);", + " }", + "", + " // range :: Int -> Int -> [Int]", + " function range(m, n) {", + " return Array.apply(null, Array(n - m + 1))", + " .map(function (x, i) {", + " return m + i;", + " });", + " }", + "", + " // transpose :: [[a]] -> [[a]]", + " function transpose(lst) {", + " return lst[0].map(function (_, iCol) {", + " return lst.map(function (row) {", + " return row[iCol];", + " });", + " });", + " }", + "", + " var days = {", + " sunday: 0,", + " monday: 1,", + " tuesday: 2,", + " wednesday: 3,", + " thursday: 4,", + " friday: 5,", + " saturday: 6", + " }", + "", + " // TEST", + "", + " return transpose(", + " range(2012, 2016)", + " .map(lastSundaysOfYear)", + " )", + " .map(function (row) {", + " return row", + " .map(isoDateString)", + " .join('\\t');", + " })", + " .join('\\n');", + "", + "})();", + "", + "{{Out}}", + "
2013-01-27\t2014-01-26\t2015-01-25\t2016-01-31\t2017-01-29",
+      "2013-02-24\t2014-02-23\t2015-02-22\t2016-02-28\t2017-02-26",
+      "2013-03-31\t2014-03-30\t2015-03-29\t2016-03-27\t2017-03-26",
+      "2013-04-28\t2014-04-27\t2015-04-26\t2016-04-24\t2017-04-30",
+      "2013-05-26\t2014-05-25\t2015-05-31\t2016-05-29\t2017-05-28",
+      "2013-06-30\t2014-06-29\t2015-06-28\t2016-06-26\t2017-06-25",
+      "2013-07-28\t2014-07-27\t2015-07-26\t2016-07-31\t2017-07-30",
+      "2013-08-25\t2014-08-31\t2015-08-30\t2016-08-28\t2017-08-27",
+      "2013-09-29\t2014-09-28\t2015-09-27\t2016-09-25\t2017-09-24",
+      "2013-10-27\t2014-10-26\t2015-10-25\t2016-10-30\t2017-10-29",
+      "2013-11-24\t2014-11-30\t2015-11-29\t2016-11-27\t2017-11-26",
+      "2013-12-29\t2014-12-28\t2015-12-27\t2016-12-25\t2017-12-31
", + "", + "===ES6===", + "(() => {", + " 'use strict'", + "", + " // lastWeekDaysOfYear :: Int -> Int -> [Date]", + " const lastWeekDaysOfYear = (iWeekDay, y) => [", + " 31,", + " 0 === y % 4 && 0 !== y % 100 || 0 === y % 400 ? 29 : 28,", + " 31, 30, 31, 30, 31, 31, 30, 31, 30, 31", + " ]", + " .map((d, m) =>", + " new Date(Date.UTC(", + " y, m, d - ((new Date(Date.UTC(y, m, d))", + " .getDay() + (7 - iWeekDay)) % 7))));", + "", + " const days = {", + " sunday: 0,", + " monday: 1,", + " tuesday: 2,", + " wednesday: 3,", + " thursday: 4,", + " friday: 5,", + " saturday: 6", + " };", + "", + " // GENERIC FUNCTIONS", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " const curry = f => a => b => f(a, b);", + "", + " // isoDateString :: Date -> String", + " const isoDateString = dte =>", + " dte.toISOString()", + " .substr(0, 10);", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // transpose :: [[a]] -> [[a]]", + " const transpose = lst =>", + " lst[0].map((_, iCol) =>", + " lst.map(row => row[iCol]));", + "", + " // TEST", + " return transpose(", + " range(2015, 2019)", + " .map(curry(lastWeekDaysOfYear)(days.sunday))", + " )", + " .map(row => row", + " .map(isoDateString)", + " .join('\\t'))", + " .join('\\n');", + "})();", + "{{Out}}", + "
2015-01-25    2016-01-31    2017-01-29    2018-01-28    2019-01-27",
+      "2015-02-22    2016-02-28    2017-02-26    2018-02-25    2019-02-24",
+      "2015-03-29    2016-03-27    2017-03-26    2018-03-25    2019-03-31",
+      "2015-04-26    2016-04-24    2017-04-30    2018-04-29    2019-04-28",
+      "2015-05-31    2016-05-29    2017-05-28    2018-05-27    2019-05-26",
+      "2015-06-28    2016-06-26    2017-06-25    2018-06-24    2019-06-30",
+      "2015-07-26    2016-07-31    2017-07-30    2018-07-29    2019-07-28",
+      "2015-08-30    2016-08-28    2017-08-27    2018-08-26    2019-08-25",
+      "2015-09-27    2016-09-25    2017-09-24    2018-09-30    2019-09-29",
+      "2015-10-25    2016-10-30    2017-10-29    2018-10-28    2019-10-27",
+      "2015-11-29    2016-11-27    2017-11-26    2018-11-25    2019-11-24",
+      "2015-12-27    2016-12-25    2017-12-31    2018-12-30    2019-12-29
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e5c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function lastSundayOfEachMonths(year) {\n\tvar lastDay = [31,28,31,30,31,30,31,31,30,31,30,31]\n\tif (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) lastDay[2] = 29\n\tfor (var date = new Date(), month=0; month<12; month+=1) {\n\t\tdate.setFullYear(year, month, lastDay[month])\n\t\tdate.setDate(date.getDate()-date.getDay())\n\t\tdocument.write(date.toISOString().substring(0,10), '
')\n\t} \n}\n\t\nlastSundayOfEachMonths(2013)\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Find the missing permutation", + "type": "Waypoint", + "description": [ + "
",
+      "ABCD",
+      "CABD",
+      "ACDB",
+      "DACB",
+      "BCDA",
+      "ACBD",
+      "ADCB",
+      "CDAB",
+      "DABC",
+      "BCAD",
+      "CADB",
+      "CDBA",
+      "CBAD",
+      "ABDC",
+      "ADBC",
+      "BDCA",
+      "DCBA",
+      "BACD",
+      "BADC",
+      "BDAC",
+      "CBDA",
+      "DBCA",
+      "DCAB",
+      "
", + "

Listed above are all of the permutations of the symbols A, B, C, and D, except for one permutation that's not listed.

", + "Task:", + "

Find that missing permutation.

", + "Methods:", + "Obvious method: enumerate all permutations of A, B, C, and D, ", + "

and then look for the missing permutation.

alternate method: Hint: if all permutations were shown above, how many ", + "

times would A appear in each position?

", + "

What is the parity of this number?

another alternate method: Hint: if you add up the letter values of each column, ", + "

does a missing letter A, B, C, and D from each

", + "

column cause the total value for each column to be unique?

", + "Related task:", + " Permutations)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "====Imperative====", + "", + "The permute() function taken from http://snippets.dzone.com/posts/show/1032 ", + "permute = function(v, m){ //v1.0", + " for(var p = -1, j, k, f, r, l = v.length, q = 1, i = l + 1; --i; q *= i);", + " for(x = [new Array(l), new Array(l), new Array(l), new Array(l)], j = q, k = l + 1, i = -1;", + " ++i < l; x[2][i] = i, x[1][i] = x[0][i] = j /= --k);", + " for(r = new Array(q); ++p < q;)", + " for(r[p] = new Array(l), i = -1; ++i < l; !--x[1][i] && (x[1][i] = x[0][i],", + " x[2][i] = (x[2][i] + 1) % l), r[p][i] = m ? x[3][i] : v[x[3][i]])", + " for(x[3][i] = x[2][i], f = 0; !f; f = !f)", + " for(j = i; j; x[3][--j] == x[2][i] && (x[3][i] = x[2][i] = (x[2][i] + 1) % l, f = 1));", + " return r;", + "};", + "", + "list = [ 'ABCD', 'CABD', 'ACDB', 'DACB', 'BCDA', 'ACBD', 'ADCB', 'CDAB',", + " 'DABC', 'BCAD', 'CADB', 'CDBA', 'CBAD', 'ABDC', 'ADBC', 'BDCA',", + " 'DCBA', 'BACD', 'BADC', 'BDAC', 'CBDA', 'DBCA', 'DCAB'];", + "", + "all = permute(list[0].split('')).map(function(elem) {return elem.join('')});", + "", + "missing = all.filter(function(elem) {return list.indexOf(elem) == -1});", + "print(missing); // ==> DBAC", + "", + "====Functional====", + "", + "(function (strList) {", + "", + " // [a] -> [[a]]", + " function permutations(xs) {", + " return xs.length ? (", + " chain(xs, function (x) {", + " return chain(permutations(deleted(x, xs)), function (ys) {", + " return [[x].concat(ys).join('')];", + " })", + " })) : [[]];", + " }", + "", + " // Monadic bind/chain for lists", + " // [a] -> (a -> b) -> [b]", + " function chain(xs, f) {", + " return [].concat.apply([], xs.map(f));", + " }", + "", + " // a -> [a] -> [a]", + " function deleted(x, xs) {", + " return xs.length ? (", + " x === xs[0] ? xs.slice(1) : [xs[0]].concat(", + " deleted(x, xs.slice(1))", + " )", + " ) : [];", + " }", + "", + " // Provided subset", + " var lstSubSet = strList.split('\\n');", + "", + " // Any missing permutations", + " // (we can use fold/reduce, filter, or chain (concat map) here)", + " return chain(permutations('ABCD'.split('')), function (x) {", + " return lstSubSet.indexOf(x) === -1 ? [x] : [];", + " });", + "", + "})(", + " 'ABCD\\nCABD\\nACDB\\nDACB\\nBCDA\\nACBD\\nADCB\\nCDAB\\nDABC\\nBCAD\\nCADB\\n\\", + "CDBA\\nCBAD\\nABDC\\nADBC\\nBDCA\\nDCBA\\nBACD\\nBADC\\nBDAC\\nCBDA\\nDBCA\\nDCAB'", + ");", + "", + "{{Out}}", + "", + "[\"DBAC\"]", + "", + "===ES6===", + "====Statistical====", + "=====Using a dictionary=====", + "(() => {", + " 'use strict';", + "", + " // transpose :: [[a]] -> [[a]]", + " let transpose = xs =>", + " xs[0].map((_, iCol) => xs", + " .map((row) => row[iCol]));", + "", + "", + " let xs = 'ABCD CABD ACDB DACB BCDA ACBD ADCB CDAB' +", + " ' DABC BCAD CADB CDBA CBAD ABDC ADBC BDCA DCBA' +", + " ' BACD BADC BDAC CBDA DBCA DCAB'", + "", + " return transpose(xs.split(' ')", + " .map(x => x.split('')))", + " .map(col => col.reduce((a, x) => ( // count of each character in each column", + " a[x] = (a[x] || 0) + 1,", + " a", + " ), {}))", + " .map(dct => { // character with frequency below mean of distribution ?", + " let ks = Object.keys(dct),", + " xs = ks.map(k => dct[k]),", + " mean = xs.reduce((a, b) => a + b, 0) / xs.length;", + "", + " return ks.reduce(", + " (a, k) => a ? a : (dct[k] < mean ? k : undefined),", + " undefined", + " );", + " })", + " .join(''); // 4 chars as single string", + "", + " // --> 'DBAC'", + "})();", + "", + "{{Out}}", + "
DBAC
", + "", + "", + "=====Composing functional primitives=====", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // MISSING PERMUTATION ---------------------------------------------------", + "", + " // missingPermutation :: [String] -> String", + " const missingPermutation = xs =>", + " map(", + " // Rarest letter,", + " compose([", + " sort,", + " group,", + " curry(minimumBy)(comparing(length)),", + " head", + " ]),", + "", + " // in each column.", + " transpose(map(stringChars, xs))", + " )", + " .join('');", + "", + "", + " // GENERIC FUNCTIONAL PRIMITIVES -----------------------------------------", + "", + " // transpose :: [[a]] -> [[a]]", + " const transpose = xs =>", + " xs[0].map((_, iCol) => xs.map(row => row[iCol]));", + "", + " // sort :: Ord a => [a] -> [a]", + " const sort = xs => xs.sort();", + "", + " // group :: Eq a => [a] -> [[a]]", + " const group = xs => groupBy((a, b) => a === b, xs);", + "", + " // groupBy :: (a -> a -> Bool) -> [a] -> [[a]]", + " const groupBy = (f, xs) => {", + " const dct = xs.slice(1)", + " .reduce((a, x) => {", + " const", + " h = a.active.length > 0 ? a.active[0] : undefined,", + " blnGroup = h !== undefined && f(h, x);", + "", + " return {", + " active: blnGroup ? a.active.concat(x) : [x],", + " sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])", + " };", + " }, {", + " active: xs.length > 0 ? [xs[0]] : [],", + " sofar: []", + " });", + " return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);", + " };", + "", + " // length :: [a] -> Int", + " const length = xs => xs.length;", + "", + " // comparing :: (a -> b) -> (a -> a -> Ordering)", + " const comparing = f =>", + " (x, y) => {", + " const", + " a = f(x),", + " b = f(y);", + " return a < b ? -1 : a > b ? 1 : 0", + " };", + "", + " // minimumBy :: (a -> a -> Ordering) -> [a] -> a", + " const minimumBy = (f, xs) =>", + " xs.reduce((a, x) => a === undefined ? x : (", + " f(x, a) < 0 ? x : a", + " ), undefined);", + "", + " // head :: [a] -> a", + " const head = xs => xs.length ? xs[0] : undefined;", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f)", + "", + " // compose :: [(a -> a)] -> (a -> a)", + " const compose = fs => x => fs.reduce((a, f) => f(a), x);", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " const curry = f => a => b => f(a, b);", + "", + " // stringChars :: String -> [Char]", + " const stringChars = s => s.split('');", + "", + "", + " // TEST ------------------------------------------------------------------", + "", + " return missingPermutation([\"ABCD\", \"CABD\", \"ACDB\", \"DACB\", \"BCDA\", \"ACBD\",", + " \"ADCB\", \"CDAB\", \"DABC\", \"BCAD\", \"CADB\", \"CDBA\", \"CBAD\", \"ABDC\", \"ADBC\",", + " \"BDCA\", \"DCBA\", \"BACD\", \"BADC\", \"BDAC\", \"CBDA\", \"DBCA\", \"DCAB\"", + " ]);", + "", + " // -> \"DBAC\"", + "})();", + "{{Out}}", + "
DBAC
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e5d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "permute = function(v, m){ //v1.0\n for(var p = -1, j, k, f, r, l = v.length, q = 1, i = l + 1; --i; q *= i);\n for(x = [new Array(l), new Array(l), new Array(l), new Array(l)], j = q, k = l + 1, i = -1;\n ++i < l; x[2][i] = i, x[1][i] = x[0][i] = j /= --k);\n for(r = new Array(q); ++p < q;)\n for(r[p] = new Array(l), i = -1; ++i < l; !--x[1][i] && (x[1][i] = x[0][i],\n x[2][i] = (x[2][i] + 1) % l), r[p][i] = m ? x[3][i] : v[x[3][i]])\n for(x[3][i] = x[2][i], f = 0; !f; f = !f)\n for(j = i; j; x[3][--j] == x[2][i] && (x[3][i] = x[2][i] = (x[2][i] + 1) % l, f = 1));\n return r;\n};\n\nlist = [ 'ABCD', 'CABD', 'ACDB', 'DACB', 'BCDA', 'ACBD', 'ADCB', 'CDAB',\n 'DABC', 'BCAD', 'CADB', 'CDBA', 'CBAD', 'ABDC', 'ADBC', 'BDCA',\n 'DCBA', 'BACD', 'BADC', 'BDAC', 'CBDA', 'DBCA', 'DCAB'];\n\nall = permute(list[0].split('')).map(function(elem) {return elem.join('')});\n\nmissing = all.filter(function(elem) {return list.indexOf(elem) == -1});\nprint(missing); // ==> DBAC\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "First class environments", + "type": "Waypoint", + "description": [ + "

According to Wikipedia, \"In computing, a first-class object ... is an entity that can be constructed at run-time, passed as a parameter, returned from a subroutine, or assigned into a variable\".

Often this term is used in the context of \"first class functions\". In an analogous way, a programming language may support \"first class environments\".

The environment is minimally, the set of variables accessable to a statement being executed. Change the environments and the same statement could produce different results when executed.

Often an environment is captured in a closure, which encapsulates a function together with an environment. That environment, however, is not first-class, as it cannot be created, passed etc. independently from the function's code.

Therefore, a first class environment is a set of variable bindings which can be constructed at run-time, passed as a parameter, returned from a subroutine, or assigned into a variable. It is like a closure without code. A statement must be able to be executed within a stored first class environment and act according to the environment variable values stored within.

The task: Build a dozen environments, and a single piece of code to be run repeatedly in each of these envionments.

Each environment contains the bindings for two variables: A value in the Hailstone sequence, and a count which is incremented until the value drops to 1. The initial hailstone values are 1 through 12, and the count in each environment is zero.

When the code runs, it calculates the next hailstone step in the current environment (unless the value is already 1) and counts the steps. Then it prints the current value in a tabular form.

When all hailstone values dropped to 1, processing stops, and the total number of hailstone steps for each environment is printed.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e5e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "First-class functions", + "type": "Waypoint", + "description": [ + "

A language has first-class functions if it can do each of the following without recursively invoking a compiler or interpreter or otherwise metaprogramming:

Create new functions from preexisting functions at run-time", + "Store functions in collections", + "Use functions as arguments to other functions", + "Use functions as return values of other functions", + "Task:", + "

Write a program to create an ordered collection A of functions of a real number. At least one function should be built-in and at least one should be user-defined; try using the sine, cosine, and cubing functions. Fill another collection B with the inverse of each function in A. Implement function composition as in Functional Composition. Finally, demonstrate that the result of applying the composition of each function in A and its inverse in B to a value, is the original value. (Within the limits of computational accuracy).

(A solution need not actually call the collections \"A\" and \"B\". These names are only used in the preceding paragraph for clarity.)

", + "Related task: ", + "

First-class Numbers

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "// Functions as values of a variable", + "var cube = function (x) {", + " return Math.pow(x, 3);", + "};", + "var cuberoot = function (x) {", + " return Math.pow(x, 1 / 3);", + "};", + "", + "// Higher order function", + "var compose = function (f, g) {", + " return function (x) {", + " return f(g(x));", + " };", + "};", + "", + "// Storing functions in a array", + "var fun = [Math.sin, Math.cos, cube];", + "var inv = [Math.asin, Math.acos, cuberoot];", + "", + "for (var i = 0; i < 3; i++) {", + " // Applying the composition to 0.5", + " console.log(compose(inv[i], fun[i])(0.5));", + "}", + "", + "===ES6===", + "// Functions as values of a variable", + "var cube = x => Math.pow(x, 3);", + "", + "var cuberoot = x => Math.pow(x, 1 / 3);", + "", + "", + "// Higher order function", + "var compose = (f, g) => (x => f(g(x)));", + "", + "// Storing functions in a array", + "var fun = [ Math.sin, Math.cos, cube ];", + "var inv = [ Math.asin, Math.acos, cuberoot ];", + "", + "for (var i = 0; i < 3; i++) {", + " // Applying the composition to 0.5", + " console.log(compose(inv[i], fun[i])(0.5));", + "}", + "", + "", + "Result is always: ", + "
0.5",
+      "0.4999999999999999",
+      "0.5
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e5f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// Functions as values of a variable\nvar cube = function (x) {\n return Math.pow(x, 3);\n};\nvar cuberoot = function (x) {\n return Math.pow(x, 1 / 3);\n};\n\n// Higher order function\nvar compose = function (f, g) {\n return function (x) {\n return f(g(x));\n };\n};\n\n// Storing functions in a array\nvar fun = [Math.sin, Math.cos, cube];\nvar inv = [Math.asin, Math.acos, cuberoot];\n\nfor (var i = 0; i < 3; i++) {\n // Applying the composition to 0.5\n console.log(compose(inv[i], fun[i])(0.5));\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "First-class functions/Use numbers analogously", + "type": "Waypoint", + "description": [ + "

In First-class functions, a language is showing how its manipulation of functions is similar to its manipulation of other types.

This tasks aim is to compare and contrast a language's implementation of first class functions, with its normal handling of numbers.

", + "

Write a program to create an ordered collection of a mixture of literally typed and expressions producing a real number, together with another ordered collection of their multiplicative inverses. Try and use the following pseudo-code to generate the numbers for the ordered collections:

", + "

x = 2.0

", + "

xi = 0.5

", + "

y = 4.0

", + "

yi = 0.25

", + "

z = x + y

", + "

zi = 1.0 / ( x + y )

Create a function multiplier, that given two numbers as arguments returns a function that when called with one argument, returns the result of multiplying the two arguments to the call to multiplier that created it and the argument in the call:

", + "

new_function = multiplier(n1,n2)

", + "

# where new_function(m) returns the result of n1 * n2 * m

Applying the multiplier of a number and its inverse from the two ordered collections of numbers in pairs, show that the result in each case is one.

", + "

Compare and contrast the resultant program with the corresponding entry in First-class functions. They should be close.

To paraphrase the task description: Do what was done before, but with numbers rather than functions

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e60", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Five weekends", + "type": "Waypoint", + "description": [ + "

The month of October in 2010 has five Fridays, five Saturdays, and five Sundays.

", + "Task:", + "Write a program to show all months that have this same characteristic of five full weekends from the year 1900 through 2100 (Gregorian calendar). ", + "Show the number of months with this property (there should be 201).", + "Show at least the first and last five dates, in order.

Algorithm suggestions

", + "Count the number of Fridays, Saturdays, and Sundays in every month.", + "Find all of the 31-day months that begin on Friday.

Extra credit

Count and/or show all of the years which do not have at least one five-weekend month (there should be 29).

", + "Related tasks", + "Day of the week", + "Last Friday of each month", + "Find last sunday of each month" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Imperative====", + "function startsOnFriday(month, year)", + "{", + " // 0 is Sunday, 1 is Monday, ... 5 is Friday, 6 is Saturday", + " return new Date(year, month, 1).getDay() === 5;", + "}", + "function has31Days(month, year)", + "{", + " return new Date(year, month, 31).getDate() === 31;", + "}", + "function checkMonths(year)", + "{", + " var month, count = 0;", + " for (month = 0; month < 12; month += 1)", + " {", + " if (startsOnFriday(month, year) && has31Days(month, year))", + " {", + " count += 1;", + " document.write(year + ' ' + month + '
');", + " }", + " }", + " return count;", + "}", + "function fiveWeekends()", + "{", + " var", + " startYear = 1900,", + " endYear = 2100,", + " year,", + " monthTotal = 0,", + " yearsWithoutFiveWeekends = [],", + " total = 0;", + " for (year = startYear; year <= endYear; year += 1)", + " {", + " monthTotal = checkMonths(year);", + " total += monthTotal;", + " // extra credit", + " if (monthTotal === 0)", + " yearsWithoutFiveWeekends.push(year);", + " }", + " document.write('Total number of months: ' + total + '
');", + " document.write('
');", + " document.write(yearsWithoutFiveWeekends + '
');", + " document.write('Years with no five-weekend months: ' + yearsWithoutFiveWeekends.length + '
');", + "}", + "fiveWeekends();
", + "", + "{{out|Sample output}}", + "
1901 2",
+      "1902 7",
+      "1903 4",
+      "1904 0",
+      "1904 6",
+      "...",
+      "2097 2",
+      "2098 7",
+      "2099 4",
+      "2100 0",
+      "2100 9",
+      "Total number of months: 201",
+      "",
+      "1900,1906,1917,1923,1928,1934,1945,1951,1956,1962,1973,1979,1984,1990,2001,2007,2012,2018,2029,2035,2040,2046,2057,2063,2068,2074,2085,2091,2096",
+      "Years with no five-weekend months: 29
", + "", + "", + "Here is an alternative solution that uses the offset between the first day of every month, generating the same solution but without relying on the Date object.", + "var Months = [", + " 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',", + " 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'", + "];", + "", + "var leap = 0,", + " // Relative offsets between first day of each month", + " offset = [3,0,3,2,3,2,3,3,2,3,2,3],", + "", + " // Months that contain 31 days", + " longMonths = [1,3,5,7,8,10,12],", + "", + " startYear = 1900,", + " year = startYear,", + " endYear = 2100,", + "", + " // Jan 1, 1900 starts on a Monday", + " day = 1,", + "", + " totalPerYear = 0,", + " total = 0,", + " without = 0;", + "", + "for (; year < endYear + 1; year++) {", + " leap = totalPerYear = 0;", + "", + " if (year % 4 === 0) {", + " if (year % 100 === 0) {", + " if (year % 400 === 0) {", + " leap = 1;", + " }", + " } else {", + " leap = 1;", + " }", + " }", + "", + " for (var i = 0; i < offset.length; i++) {", + " for (var j = 0; day === 5 && j < longMonths.length; j++) {", + " if (i + 1 === longMonths[j]) {", + " console.log(year + '-' + Months[i]);", + " totalPerYear++;", + " total++;", + " break;", + " }", + " }", + "", + " // February -- if leap year, then +1 day", + " if (i == 1) {", + " day = (day + leap) % 7; ", + " } else {", + " day = (day + offset[i]) % 7;", + " }", + " }", + "", + " if (totalPerYear === 0) {", + " without++;", + " }", + "}", + "", + "console.log('Number of months that have five full weekends from 1900 to 2100: ' + total);", + "console.log('Number of years without any five full weekend months: ' + without);", + "{{out}}", + "
1901-Mar",
+      "1902-Aug",
+      "1903-May",
+      "1904-Jan",
+      "1904-Jul",
+      "...",
+      "2097-Mar",
+      "2098-Aug",
+      "2099-May",
+      "2100-Jan",
+      "2100-Oct",
+      "Number of months that have five full weekends from 1900 to 2100: 201",
+      "Number of years without any five full weekend months: 29
", + "", + "====Functional====", + "(function () {", + " 'use strict';", + "", + " // longMonthsStartingFriday :: Int -> Int", + " function longMonthsStartingFriday(y) {", + " return [0, 2, 4, 6, 7, 9, 11]", + " .filter(function (m) {", + " return (new Date(Date.UTC(y, m, 1)))", + " .getDay() === 5;", + " });", + " }", + "", + " // range :: Int -> Int -> [Int]", + " function range(m, n) {", + " return Array.apply(null, Array(n - m + 1))", + " .map(function (x, i) {", + " return m + i;", + " });", + " }", + "", + " var lstNames = [", + " 'January', '', 'March', '', 'May', '',", + " 'July', 'August', '', 'October', '', 'December'", + " ],", + "", + " lstYears = range(1900, 2100),", + "", + " lstFullMonths = lstYears", + " .reduce(function (a, y) {", + " var strYear = y.toString();", + "", + " return a.concat(", + " longMonthsStartingFriday(y)", + " .map(function (m) {", + " return strYear + ' ' + lstNames[m];", + " })", + " );", + " }, []),", + "", + " lstLeanYears = lstYears", + " .filter(function (y) {", + " return longMonthsStartingFriday(y)", + " .length === 0;", + " });", + "", + " return JSON.stringify({", + " number: lstFullMonths.length,", + " firstFive: lstFullMonths.slice(0, 5),", + " lastFive: lstFullMonths.slice(-5),", + " leanYearCount: lstLeanYears.length", + " },", + " null, 2", + " );", + "})();", + "{{Out}}", + "
{",
+      "  \"number\": 201,",
+      "  \"firstFive\": [",
+      "    \"1901 March\",",
+      "    \"1902 August\",",
+      "    \"1903 May\",",
+      "    \"1904 January\",",
+      "    \"1904 July\"",
+      "  ],",
+      "  \"lastFive\": [",
+      "    \"2097 March\",",
+      "    \"2098 August\",",
+      "    \"2099 May\",",
+      "    \"2100 January\",",
+      "    \"2100 October\"",
+      "  ],",
+      "  \"leanYearCount\": 29",
+      "}
", + "", + "===ES6===", + "(() => {", + " // longMonthsStartingFriday :: Int -> [Int]", + " const longMonthsStartingFriday = y =>", + " filter(m => (new Date(Date.UTC(y, m, 1)))", + " .getDay() === 5, [0, 2, 4, 6, 7, 9, 11]);", + "", + " // Years -> YearMonths", + " // fullMonths :: [Int] -> [String]", + " const fullMonths = xs =>", + " foldl((a, y) => a.concat(", + " map(m => `${y.toString()} ${[", + " 'January', '', 'March', '', 'May', '',", + " 'July', 'August', '', 'October', '', 'December'", + " ][m]}`, longMonthsStartingFriday(y))", + " ), [], xs);", + "", + " // leanYears :: [Int] -> [Int]", + " const leanYears = years =>", + " filter(y => longMonthsStartingFriday(y)", + " .length === 0, years);", + "", + " // GENERIC ----------------------------------------------------------------", + "", + " // A list of functions applied to a list of arguments", + " // <*> :: [(a -> b)] -> [a] -> [b]", + " const ap = (fs, xs) => //", + " [].concat.apply([], fs.map(f => //", + " [].concat.apply([], xs.map(x => [f(x)]))));", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " const enumFromTo = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // filter :: (a -> Bool) -> [a] -> [a]", + " const filter = (f, xs) => xs.filter(f);", + "", + " // foldl :: (b -> a -> b) -> b -> [a] -> b", + " const foldl = (f, a, xs) => xs.reduce(f, a);", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x, null, 2);", + "", + "", + " // TEST -------------------------------------------------------------------", + " const [lstFullMonths, lstLeanYears] = ap(", + " [fullMonths, leanYears], [enumFromTo(1900, 2100)]", + " );", + "", + " return show({", + " number: lstFullMonths.length,", + " firstFive: lstFullMonths.slice(0, 5),", + " lastFive: lstFullMonths.slice(-5),", + " leanYearCount: lstLeanYears.length", + " });", + "})();", + "{{Out}}", + "
{",
+      "  \"number\": 201,",
+      "  \"firstFive\": [",
+      "    \"1901 March\",",
+      "    \"1902 August\",",
+      "    \"1903 May\",",
+      "    \"1904 January\",",
+      "    \"1904 July\"",
+      "  ],",
+      "  \"lastFive\": [",
+      "    \"2097 March\",",
+      "    \"2098 August\",",
+      "    \"2099 May\",",
+      "    \"2100 January\",",
+      "    \"2100 October\"",
+      "  ],",
+      "  \"leanYearCount\": 29",
+      "}
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e61", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function startsOnFriday(month, year)\n{\n // 0 is Sunday, 1 is Monday, ... 5 is Friday, 6 is Saturday\n return new Date(year, month, 1).getDay() === 5;\n}\nfunction has31Days(month, year)\n{\n return new Date(year, month, 31).getDate() === 31;\n}\nfunction checkMonths(year)\n{\n var month, count = 0;\n for (month = 0; month < 12; month += 1)\n {\n if (startsOnFriday(month, year) && has31Days(month, year))\n {\n count += 1;\n document.write(year + ' ' + month + '
');\n }\n }\n return count;\n}\nfunction fiveWeekends()\n{\n var\n startYear = 1900,\n endYear = 2100,\n year,\n monthTotal = 0,\n yearsWithoutFiveWeekends = [],\n total = 0;\n for (year = startYear; year <= endYear; year += 1)\n {\n monthTotal = checkMonths(year);\n total += monthTotal;\n // extra credit\n if (monthTotal === 0)\n yearsWithoutFiveWeekends.push(year);\n }\n document.write('Total number of months: ' + total + '
');\n document.write('
');\n document.write(yearsWithoutFiveWeekends + '
');\n document.write('Years with no five-weekend months: ' + yearsWithoutFiveWeekends.length + '
');\n}\nfiveWeekends();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "FizzBuzz", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a program that prints the integers from 1 to 100 (inclusive).

", + "

But:

", + "

* for multiples of three, print Fizz (instead of the number)

", + "

* for multiples of five, print Buzz (instead of the number)

", + "

* for multiples of both three and five, print FizzBuzz (instead of the number)

", + "

The FizzBuzz problem was presented as the lowest level of comprehension required to illustrate adequacy.

", + "Also see:", + " (a blog) dont-overthink-fizzbuzz", + " (a blog) fizzbuzz-the-programmers-stairway-to-heaven" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "var fizzBuzz = function () {", + " var i, output;", + " for (i = 1; i < 101; i += 1) {", + " output = '';", + " if (!(i % 3)) { output += 'Fizz'; }", + " if (!(i % 5)) { output += 'Buzz'; }", + " console.log(output || i);//empty string is false, so we short-circuit", + " }", + "};", + "", + "Alternate version with ghetto pattern matching", + "for (var i = 1; i <= 100; i++) {", + " console.log({", + " truefalse: 'Fizz', ", + " falsetrue: 'Buzz', ", + " truetrue: 'FizzBuzz'", + " }[(i%3==0) + '' + (i%5==0)] || i)", + "}", + "", + "Or very tersely:", + "for(i=1;i<101;i++)console.log((x=(i%3?'':'Fizz')+(i%5?'':'Buzz'))?x:i);", + "", + "Or with even less characters:", + "for(i=1;i<101;i++)console.log((i%3?'':'Fizz')+(i%5?'':'Buzz')||i)", + "", + "Or, in a more functional style, without mutations", + "(function rng(i) {", + " return i ? rng(i - 1).concat(i) : []", + "})(100).map(", + " function (n) {", + " return n % 3 ? (", + " n % 5 ? n : \"Buzz\"", + " ) : (", + " n % 5 ? \"Fizz\" : \"FizzBuzz\"", + " )", + " }", + ").join(' ')", + "", + "===ES6===", + "", + "(() => {", + "", + " // fizzBuzz :: Int -> String", + " const fizzBuzz = n =>", + " caseOf(n, [", + " [x => x % 15 === 0, \"FizzBuzz\"],", + " [x => x % 3 === 0, \"Fizz\"],", + " [x => x % 5 === 0, \"Buzz\"]", + " ], n.toString());", + "", + "", + "", + " // GENERIC -------------------------------------------------", + "", + " // caseOf :: a -> [(a -> Bool, b)] -> b -> b", + " const caseOf = (e, pvs, otherwise) =>", + " pvs.reduce((a, [p, v]) =>", + " a !== otherwise ? a : (p(e) ? v : a), otherwise);", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + "", + " // TEST ----------------------------------------------------", + " return range(1, 100)", + " .map(fizzBuzz)", + " .join('\\n');", + "})();", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e62", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var fizzBuzz = function () {\n var i, output;\n for (i = 1; i < 101; i += 1) {\n output = '';\n if (!(i % 3)) { output += 'Fizz'; }\n if (!(i % 5)) { output += 'Buzz'; }\n console.log(output || i);//empty string is false, so we short-circuit\n }\n};\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Flatten a list", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a function to flatten the nesting in an arbitrary list of values.

", + "

Your program should work on the equivalent of this list:

", + "

1], 2, [[3, 4], 5], [[[], [6], 7, 8, []]

", + "

Where the correct result would be the list:

", + "

[1, 2, 3, 4, 5, 6, 7, 8]

", + "Related task:", + " Tree traversal" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "function flatten(list) {", + " return list.reduce(function (acc, val) {", + " return acc.concat(val.constructor === Array ? flatten(val) : val);", + " }, []);", + "}", + "", + "", + "Or, expressed in terms of the more generic '''concatMap''' function:", + "", + "(function () {", + " 'use strict';", + "", + " // flatten :: Tree a -> [a]", + " function flatten(t) {", + " return (t instanceof Array ? concatMap(flatten, t) : t);", + " }", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " function concatMap(f, xs) {", + " return [].concat.apply([], xs.map(f));", + " }", + "", + " return flatten(", + " [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]", + " );", + "", + "})();", + "", + "", + "From fusion of ''flatten'' with ''concatMap'' we can then derive:", + "", + " // flatten :: Tree a -> [a]", + " function flatten(a) {", + " return a instanceof Array ? [].concat.apply([], a.map(flatten)) : a;", + " }", + "", + "For example:", + "", + "(function () {", + " 'use strict';", + "", + " // flatten :: Tree a -> [a]", + " function flatten(a) {", + " return a instanceof Array ? [].concat.apply([], a.map(flatten)) : a;", + " }", + "", + " return flatten(", + " [[1], 2, [[3, 4], 5], [[[]]], [[[6]]], 7, 8, []]", + " );", + "", + "})();", + "", + "{{Out}}", + "", + "
[1, 2, 3, 4, 5, 6, 7, 8]
", + "", + "===ES6===", + "====Recursive====", + "let flatten = list => list.reduce(", + " (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []", + ");", + "", + "====Iterative====", + "function flatten(list) {", + " for (let i = 0; i < list.length; i++) {", + " while (true) {", + " if (Array.isArray(list[i])) {", + " \tlist.splice(i, 1, ...list[i]);", + " } else {", + " \tbreak;", + " }", + " }", + " }", + " return list;", + "}", + "", + "Result is always: ", + "
[1, 2, 3, 4, 5, 6, 7, 8]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e63", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function flatten(list) {\n return list.reduce(function (acc, val) {\n return acc.concat(val.constructor === Array ? flatten(val) : val);\n }, []);\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Floyd's triangle", + "type": "Waypoint", + "description": [ + "

Floyd's triangle lists the natural numbers in a right triangle aligned to the left where

", + "the first row is 1 (unity)", + "successive rows start towards the left with the next number followed by successive naturals listing one more number than the line above.

The first few lines of a Floyd triangle looks like this:

", + "
",
+      " 1",
+      " 2  3",
+      " 4  5  6",
+      " 7  8  9 10",
+      "11 12 13 14 15",
+      "
", + "Task:", + "

# Write a program to generate and display here the first n lines of a Floyd triangle. (Use n=5 and n=14 rows).

", + "

# Ensure that when displayed in a mono-space font, the numbers line up in vertical columns as shown and that only one space separates numbers of the last row.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "=== ES5 ===", + "(In a functional idiom of JavaScript)", + "", + "Two main functions:", + ":#An expression of the Floyd triangle as a list of lists (a function of the number of rows),", + ":#and a mapping of that expression to a formatted string.", + "", + "(function () {", + " 'use strict';", + "", + " // FLOYD's TRIANGLE -------------------------------------------------------", + "", + " // floyd :: Int -> [[Int]]", + " function floyd(n) {", + " return snd(mapAccumL(function (start, row) {", + " return [start + row + 1, enumFromTo(start, start + row)];", + " }, 1, enumFromTo(0, n - 1)));", + " };", + "", + " // showFloyd :: [[Int]] -> String", + " function showFloyd(xss) {", + " var ws = map(compose([succ, length, show]), last(xss));", + " return unlines(map(function (xs) {", + " return concat(zipWith(function (w, x) {", + " return justifyRight(w, ' ', show(x));", + " }, ws, xs));", + " }, xss));", + " };", + "", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // compose :: [(a -> a)] -> (a -> a)", + " function compose(fs) {", + " return function (x) {", + " return fs.reduceRight(function (a, f) {", + " return f(a);", + " }, x);", + " };", + " };", + "", + " // concat :: [[a]] -> [a] | [String] -> String", + " function concat(xs) {", + " if (xs.length > 0) {", + " var unit = typeof xs[0] === 'string' ? '' : [];", + " return unit.concat.apply(unit, xs);", + " } else return [];", + " };", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " function enumFromTo(m, n) {", + " return Array.from({", + " length: Math.floor(n - m) + 1", + " }, function (_, i) {", + " return m + i;", + " });", + " };", + "", + " // justifyRight :: Int -> Char -> Text -> Text", + " function justifyRight(n, cFiller, strText) {", + " return n > strText.length ? (cFiller.repeat(n) + strText)", + " .slice(-n) : strText;", + " };", + "", + " // last :: [a] -> a", + " function last(xs) {", + " return xs.length ? xs.slice(-1)[0] : undefined;", + " };", + "", + " // length :: [a] -> Int", + " function length(xs) {", + " return xs.length;", + " };", + "", + " // map :: (a -> b) -> [a] -> [b]", + " function map(f, xs) {", + " return xs.map(f);", + " };", + "", + " // 'The mapAccumL function behaves like a combination of map and foldl;", + " // it applies a function to each element of a list, passing an accumulating", + " // parameter from left to right, and returning a final value of this", + " // accumulator together with the new list.' (See hoogle )", + "", + " // mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])", + " function mapAccumL(f, acc, xs) {", + " return xs.reduce(function (a, x) {", + " var pair = f(a[0], x);", + "", + " return [pair[0], a[1].concat([pair[1]])];", + " }, [acc, []]);", + " };", + "", + " // show ::", + " // (a -> String) f, Num n =>", + " // a -> maybe f -> maybe n -> String", + " var show = JSON.stringify;", + "", + " // snd :: (a, b) -> b", + " function snd(tpl) {", + " return Array.isArray(tpl) ? tpl[1] : undefined;", + " };", + "", + " // succ :: Int -> Int", + " function succ(x) {", + " return x + 1;", + " };", + "", + " // unlines :: [String] -> String", + " function unlines(xs) {", + " return xs.join('\\n');", + " };", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " function zipWith(f, xs, ys) {", + " var ny = ys.length;", + " return (xs.length <= ny ? xs : xs.slice(0, ny))", + " .map(function (x, i) {", + " return f(x, ys[i]);", + " });", + " };", + "", + " // TEST ( n=5 and n=14 rows ) ---------------------------------------------", + "", + " return unlines(map(function (n) {", + " return showFloyd(floyd(n)) + '\\n';", + " }, [5, 14]));", + "})();", + "{{Out}}", + "
  1",
+      "  2  3",
+      "  4  5  6",
+      "  7  8  9 10",
+      " 11 12 13 14 15",
+      "",
+      "  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 53  54  55",
+      " 56 57 58 59 60 61 62 63  64  65  66",
+      " 67 68 69 70 71 72 73 74  75  76  77  78",
+      " 79 80 81 82 83 84 85 86  87  88  89  90  91",
+      " 92 93 94 95 96 97 98 99 100 101 102 103 104 105
", + "", + "===ES6===", + "{{Trans|Haskell}} (mapAccumL version)", + "(() => {", + " 'use strict';", + "", + " // FLOYD's TRIANGLE -------------------------------------------------------", + "", + " // floyd :: Int -> [[Int]]", + " const floyd = n => snd(mapAccumL(", + " (start, row) => [start + row + 1, enumFromTo(start, start + row)],", + " 1, enumFromTo(0, n - 1)", + " ));", + "", + " // showFloyd :: [[Int]] -> String", + " const showFloyd = xss => {", + " const ws = map(compose([succ, length, show]), last(xss));", + " return unlines(", + " map(xs => concat(zipWith(", + " (w, x) => justifyRight(w, ' ', show(x)), ws, xs", + " )),", + " xss", + " )", + " );", + " };", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // compose :: [(a -> a)] -> (a -> a)", + " const compose = fs => x => fs.reduceRight((a, f) => f(a), x);", + "", + " // concat :: [[a]] -> [a] | [String] -> String", + " const concat = xs => {", + " if (xs.length > 0) {", + " const unit = typeof xs[0] === 'string' ? '' : [];", + " return unit.concat.apply(unit, xs);", + " } else return [];", + " };", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " const enumFromTo = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // justifyRight :: Int -> Char -> Text -> Text", + " const justifyRight = (n, cFiller, strText) =>", + " n > strText.length ? (", + " (cFiller.repeat(n) + strText)", + " .slice(-n)", + " ) : strText;", + "", + " // last :: [a] -> a", + " const last = xs => xs.length ? xs.slice(-1)[0] : undefined;", + "", + " // length :: [a] -> Int", + " const length = xs => xs.length;", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f)", + "", + " // 'The mapAccumL function behaves like a combination of map and foldl;", + " // it applies a function to each element of a list, passing an accumulating", + " // parameter from left to right, and returning a final value of this", + " // accumulator together with the new list.' (See hoogle )", + "", + " // mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])", + " const mapAccumL = (f, acc, xs) =>", + " xs.reduce((a, x) => {", + " const pair = f(a[0], x);", + "", + " return [pair[0], a[1].concat([pair[1]])];", + " }, [acc, []]);", + "", + " // show ::", + " // (a -> String) f, Num n =>", + " // a -> maybe f -> maybe n -> String", + " const show = JSON.stringify;", + "", + " // snd :: (a, b) -> b", + " const snd = tpl => Array.isArray(tpl) ? tpl[1] : undefined;", + "", + " // succ :: Int -> Int", + " const succ = x => x + 1", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) => {", + " const ny = ys.length;", + " return (xs.length <= ny ? xs : xs.slice(0, ny))", + " .map((x, i) => f(x, ys[i]));", + " };", + "", + " // TEST ( n=5 and n=14 rows ) ---------------------------------------------", + "", + " return unlines(map(n => showFloyd(floyd(n)) + '\\n', [5, 14]))", + "})();", + "{{Out}}", + "
  1",
+      "  2  3",
+      "  4  5  6",
+      "  7  8  9 10",
+      " 11 12 13 14 15",
+      "",
+      "  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 53  54  55",
+      " 56 57 58 59 60 61 62 63  64  65  66",
+      " 67 68 69 70 71 72 73 74  75  76  77  78",
+      " 79 80 81 82 83 84 85 86  87  88  89  90  91",
+      " 92 93 94 95 96 97 98 99 100 101 102 103 104 105
", + "", + "=== Spidermonkey ===", + "", + "(Used TCL example as a starting point.)", + "", + "#!/usr/bin/env js", + "", + "function main() {", + " print('Floyd 5:');", + " floyd(5);", + " print('\\nFloyd 14:');", + " floyd(14);", + "}", + "", + "", + "function padLeft(s, w) {", + " for (s = String(s); s.length < w; s = ' ' + s);", + " return s;", + "}", + "", + "", + "function floyd(nRows) {", + " var lowerLeft = nRows * (nRows - 1) / 2 + 1;", + " var lowerRight = nRows * (nRows + 1) / 2;", + " ", + " var colWidths = [];", + " for (var col = lowerLeft; col <= lowerRight; col++) {", + " colWidths.push(String(col).length);", + " }", + "", + " var num = 1;", + " for (var row = 0; row < nRows; row++) {", + " var line = [];", + " for (var col = 0; col <= row; col++, num++) {", + " line.push(padLeft(num, colWidths[col]));", + " }", + " print(line.join(' '));", + " }", + "}", + "", + "main();", + "", + "{{out}}", + "
 Floyd 5:",
+      "  1",
+      "  2  3",
+      "  4  5  6",
+      "  7  8  9 10",
+      " 11 12 13 14 15",
+      " ",
+      " Floyd 14:",
+      "  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 53  54  55",
+      " 56 57 58 59 60 61 62 63  64  65  66",
+      " 67 68 69 70 71 72 73 74  75  76  77  78",
+      " 79 80 81 82 83 84 85 86  87  88  89  90  91",
+      " 92 93 94 95 96 97 98 99 100 101 102 103 104 105
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e66", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function () {\n 'use strict';\n\n // FLOYD's TRIANGLE -------------------------------------------------------\n\n // floyd :: Int -> [[Int]]\n function floyd(n) {\n return snd(mapAccumL(function (start, row) {\n return [start + row + 1, enumFromTo(start, start + row)];\n }, 1, enumFromTo(0, n - 1)));\n };\n\n // showFloyd :: [[Int]] -> String\n function showFloyd(xss) {\n var ws = map(compose([succ, length, show]), last(xss));\n return unlines(map(function (xs) {\n return concat(zipWith(function (w, x) {\n return justifyRight(w, ' ', show(x));\n }, ws, xs));\n }, xss));\n };\n\n\n // GENERIC FUNCTIONS ------------------------------------------------------\n\n // compose :: [(a -> a)] -> (a -> a)\n function compose(fs) {\n return function (x) {\n return fs.reduceRight(function (a, f) {\n return f(a);\n }, x);\n };\n };\n\n // concat :: [[a]] -> [a] | [String] -> String\n function concat(xs) {\n if (xs.length > 0) {\n var unit = typeof xs[0] === 'string' ? '' : [];\n return unit.concat.apply(unit, xs);\n } else return [];\n };\n\n // enumFromTo :: Int -> Int -> [Int]\n function enumFromTo(m, n) {\n return Array.from({\n length: Math.floor(n - m) + 1\n }, function (_, i) {\n return m + i;\n });\n };\n\n // justifyRight :: Int -> Char -> Text -> Text\n function justifyRight(n, cFiller, strText) {\n return n > strText.length ? (cFiller.repeat(n) + strText)\n .slice(-n) : strText;\n };\n\n // last :: [a] -> a\n function last(xs) {\n return xs.length ? xs.slice(-1)[0] : undefined;\n };\n\n // length :: [a] -> Int\n function length(xs) {\n return xs.length;\n };\n\n // map :: (a -> b) -> [a] -> [b]\n function map(f, xs) {\n return xs.map(f);\n };\n\n // 'The mapAccumL function behaves like a combination of map and foldl;\n // it applies a function to each element of a list, passing an accumulating\n // parameter from left to right, and returning a final value of this\n // accumulator together with the new list.' (See hoogle )\n\n // mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])\n function mapAccumL(f, acc, xs) {\n return xs.reduce(function (a, x) {\n var pair = f(a[0], x);\n\n return [pair[0], a[1].concat([pair[1]])];\n }, [acc, []]);\n };\n\n // show ::\n // (a -> String) f, Num n =>\n // a -> maybe f -> maybe n -> String\n var show = JSON.stringify;\n\n // snd :: (a, b) -> b\n function snd(tpl) {\n return Array.isArray(tpl) ? tpl[1] : undefined;\n };\n\n // succ :: Int -> Int\n function succ(x) {\n return x + 1;\n };\n\n // unlines :: [String] -> String\n function unlines(xs) {\n return xs.join('\\n');\n };\n\n // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]\n function zipWith(f, xs, ys) {\n var ny = ys.length;\n return (xs.length <= ny ? xs : xs.slice(0, ny))\n .map(function (x, i) {\n return f(x, ys[i]);\n });\n };\n\n // TEST ( n=5 and n=14 rows ) ---------------------------------------------\n\n return unlines(map(function (n) {\n return showFloyd(floyd(n)) + '\\n';\n }, [5, 14]));\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Floyd-Warshall algorithm", + "type": "Waypoint", + "description": [ + "

The Floyd–Warshall algorithm is an algorithm for finding shortest paths in a weighted graph with positive or negative edge weights.

", + "Task", + "

Find the lengths of the shortest paths between all pairs of vertices of the given directed graph. Your code may assume that the input has already been checked for loops, parallel edges and negative cycles.

", + "

Print the pair, the distance and (optionally) the path.

", + "Example", + "
pair     dist    path",
+      "1 -> 2    -1     1 -> 3 -> 4 -> 2",
+      "1 -> 3    -2     1 -> 3",
+      "1 -> 4     0     1 -> 3 -> 4",
+      "2 -> 1     4     2 -> 1",
+      "2 -> 3     2     2 -> 1 -> 3",
+      "2 -> 4     4     2 -> 1 -> 3 -> 4",
+      "3 -> 1     5     3 -> 4 -> 2 -> 1",
+      "3 -> 2     1     3 -> 4 -> 2",
+      "3 -> 4     2     3 -> 4",
+      "4 -> 1     3     4 -> 2 -> 1",
+      "4 -> 2    -1     4 -> 2",
+      "4 -> 3     1     4 -> 2 -> 1 -> 3
", + "See also", + "Floyd-Warshall Algorithm - step by step guide (youtube)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var graph = [];", + "for (i = 0; i < 10; ++i) {", + " graph.push([]);", + " for (j = 0; j < 10; ++j)", + " graph[i].push(i == j ? 0 : 9999999);", + "}", + "", + "for (i = 1; i < 10; ++i) {", + " graph[0][i] = graph[i][0] = parseInt(Math.random() * 9 + 1);", + "}", + "", + "for (k = 0; k < 10; ++k) {", + " for (i = 0; i < 10; ++i) {", + " for (j = 0; j < 10; ++j) {", + " if (graph[i][j] > graph[i][k] + graph[k][j])", + " graph[i][j] = graph[i][k] + graph[k][j]", + " }", + " }", + "}", + "", + "console.log(graph);", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e67", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var graph = [];\nfor (i = 0; i < 10; ++i) {\n graph.push([]);\n for (j = 0; j < 10; ++j)\n graph[i].push(i == j ? 0 : 9999999);\n}\n\nfor (i = 1; i < 10; ++i) {\n graph[0][i] = graph[i][0] = parseInt(Math.random() * 9 + 1);\n}\n\nfor (k = 0; k < 10; ++k) {\n for (i = 0; i < 10; ++i) {\n for (j = 0; j < 10; ++j) {\n if (graph[i][j] > graph[i][k] + graph[k][j])\n graph[i][j] = graph[i][k] + graph[k][j]\n }\n }\n}\n\nconsole.log(graph);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Formal power series", + "type": "Waypoint", + "description": [ + "

A power series is an infinite sum of the form

$a_0 + a_1 \\cdot x + a_2 \\cdot x^2 + a_3 \\cdot x^3 + \\cdots$

The ai are called the coefficients of the series. Such sums can be added, multiplied etc., where the new coefficients of the powers of x are calculated according to the usual rules.

If one is not interested in evaluating such a series for particular values of x, or in other words, if convergence doesn't play a role, then such a collection of coefficients is called formal power series. It can be treated like a new kind of number.

Task: Implement formal power series as a numeric type. Operations should at least include addition, multiplication, division and additionally non-numeric operations like differentiation and integration (with an integration constant of zero). Take care that your implementation deals with the potentially infinite number of coefficients.

As an example, define the power series of sine and cosine in terms of each other using integration, as in

$\\sin x = \\int_0^x \\cos t\\, dt$

$\\cos x = 1 - \\int_0^x \\sin t\\, dt$

Goals: Demonstrate how the language handles new numeric types and delayed (or lazy) evaluation.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e6a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Formatted numeric output", + "type": "Waypoint", + "description": [ + "Task:", + "

Express a number in decimal as a fixed-length string with leading zeros.

", + "

For example, the number 7.125 could be expressed as 00007.125.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var n = 123;", + "var str = (\"00000\" + n).slice(-5);", + "alert(str);", + "", + "or, put in browser URL: javascript:n=123;alert((\"00000\"+n).slice(-5));", + "", + "Also, a 60-line implementation of sprintf can be found [http://code.google.com/p/sprintf/ here].", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e6b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var n = 123;\nvar str = (\"00000\" + n).slice(-5);\nalert(str);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Forward difference", + "type": "Waypoint", + "description": [ + "Task:", + "

Provide code that produces a list of numbers which is the nth order forward difference, given a non-negative integer (specifying the order) and a list of numbers.

", + "

The first-order forward difference of a list of numbers A is a new list B, where Bn = An+1 - An.

List B should have one fewer element as a result.

The second-order forward difference of A will be:

", + "
",
+      "tdefmodule Diff do",
+      "\tdef forward(arr,i\\\\1) do",
+      "\t\tforward(arr,[],i)",
+      "\tend\tdef forward([_|[]],diffs,i) do",
+      "\t\tif i == 1 do",
+      "\t\t\tIO.inspect diffs",
+      "\t\telse ",
+      "\t\t\tforward(diffs,[],i-1)",
+      "\t\tend",
+      "\tend\tdef forward([val1|[val2|vals]],diffs,i) do",
+      "\t\tforward([val2|vals],diffs++[val2-val1],i) ",
+      "\tend",
+      "end ",
+      "
", + "

The same as the first-order forward difference of B.

That new list will have two fewer elements than A and one less than B.

The goal of this task is to repeat this process up to the desired order.

For a more formal description, see the related Mathworld article.

", + "Algorithmic options:", + "Iterate through all previous forward differences and re-calculate a new array each time.", + "Use this formula (from Wikipedia):", + "

:: $\\Delta^n [f](x)= \\sum_{k=0}^n {n \\choose k} (-1)^{n-k} f(x+k)$

", + "
", + "

:: (Pascal's Triangle may be useful for this option.)

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES6===", + "", + "(() => {", + " 'use strict';", + "", + " // forwardDifference :: [Int] -> [Int]", + " const forwardDifference = (n, xs) => {", + " const fd = xs => zipWith((a, b) => a - b, tail(xs), xs);", + " return until(", + " m => m.index < 1,", + " m => ({", + " index: m.index - 1,", + " list: fd(m.list)", + " }), {", + " index: n,", + " list: xs", + " }", + " )", + " .list;", + " };", + "", + "", + " // GENERIC FUNCTIONS ---------------------------------------", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) => {", + " const ny = ys.length;", + " return (xs.length <= ny ? xs : xs.slice(0, ny))", + " .map((x, i) => f(x, ys[i]));", + " };", + "", + " // until :: (a -> Bool) -> (a -> a) -> a -> a", + " const until = (p, f, x) => {", + " const go = x => p(x) ? x : go(f(x));", + " return go(x);", + " };", + "", + " // tail :: [a] -> [a]", + " const tail = xs => xs.length ? xs.slice(1) : undefined;", + "", + "", + " // TEST ----------------------------------------------------", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x);", + "", + " // Sample", + " const test = [90, 47, 58, 29, 22, 32, 55, 5, 55, 73];", + "", + " return range(1, 9)", + " .map(x => `${x} ${show(forwardDifference(x, test))}`)", + " .join('\\n');", + "})();", + "", + "{{Out}}", + "
1    [-43,11,-29,-7,10,23,-50,50,18]",
+      "2    [54,-40,22,17,13,-73,100,-32]",
+      "3    [-94,62,-5,-4,-86,173,-132]",
+      "4    [156,-67,1,-82,259,-305]",
+      "5    [-223,68,-83,341,-564]",
+      "6    [291,-151,424,-905]",
+      "7    [-442,575,-1329]",
+      "8    [1017,-1904]",
+      "9    [-2921]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e6c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // forwardDifference :: [Int] -> [Int]\n const forwardDifference = (n, xs) => {\n const fd = xs => zipWith((a, b) => a - b, tail(xs), xs);\n return until(\n m => m.index < 1,\n m => ({\n index: m.index - 1,\n list: fd(m.list)\n }), {\n index: n,\n list: xs\n }\n )\n .list;\n };\n\n\n // GENERIC FUNCTIONS ---------------------------------------\n\n // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]\n const zipWith = (f, xs, ys) => {\n const ny = ys.length;\n return (xs.length <= ny ? xs : xs.slice(0, ny))\n .map((x, i) => f(x, ys[i]));\n };\n\n // until :: (a -> Bool) -> (a -> a) -> a -> a\n const until = (p, f, x) => {\n const go = x => p(x) ? x : go(f(x));\n return go(x);\n };\n\n // tail :: [a] -> [a]\n const tail = xs => xs.length ? xs.slice(1) : undefined;\n\n\n // TEST ----------------------------------------------------\n\n // range :: Int -> Int -> [Int]\n const range = (m, n) =>\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i);\n\n // show :: a -> String\n const show = x => JSON.stringify(x);\n\n // Sample\n const test = [90, 47, 58, 29, 22, 32, 55, 5, 55, 73];\n\n return range(1, 9)\n .map(x => `${x} ${show(forwardDifference(x, test))}`)\n .join('\\n');\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Four bit adder", + "type": "Waypoint", + "description": [ + "Task:", + "

\"Simulate\" a four-bit adder \"chip\".

This \"chip\" can be realized using four 1-bit full adders.

", + "

Each of these 1-bit full adders can be built with two half adders and an or gate. Finally a half adder can be made using a xor gate and an and gate.

", + "

The xor gate can be made using two nots, two ands and one or.

Not, or and and, the only allowed \"gates\" for the task, can be \"imitated\" by using the bitwise operators of your language.

", + "

If there is not a bit type in your language, to be sure that the not does not \"invert\" all the other bits of the basic type (e.g. a byte) we are not interested in, you can use an extra nand (and then not) with the constant 1 on one input.

Instead of optimizing and reducing the number of gates used for the final 4-bit adder, build it in the most straightforward way, connecting the other \"constructive blocks\", in turn made of \"simpler\" and \"smaller\" ones.

{|

", + "

|+Schematics of the \"constructive blocks\"

", + "

!Xor gate done with ands, ors and nots

", + "

!A half adder

", + "

!A full adder

", + "

!A 4-bit adder

", + "

|-

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|}

Solutions should try to be as descriptive as possible, making it as easy as possible to identify \"connections\" between higher-order \"blocks\".

", + "

It is not mandatory to replicate the syntax of higher-order blocks in the atomic \"gate\" blocks, i.e. basic \"gate\" operations can be performed as usual bitwise operations, or they can be \"wrapped\" in a block in order to expose the same syntax of higher-order blocks, at implementers' choice.

To test the implementation, show the sum of two four-bit numbers (in binary).

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Error Handling===", + "In order to keep the binary-ness obvious, all operations will occur on ", + "0s and 1s. To enforce this, we'll first create a couple of helper functions.", + "", + "", + "function acceptedBinFormat(bin) {", + " if (bin == 1 || bin === 0 || bin === '0')", + " return true;", + " else", + " return bin;", + "}", + "", + "function arePseudoBin() {", + " var args = [].slice.call(arguments), len = args.length;", + " while(len--)", + " if (acceptedBinFormat(args[len]) !== true)", + " throw new Error('argument must be 0, \\'0\\', 1, or \\'1\\', argument ' + len + ' was ' + args[len]);", + " return true;", + "}", + "", + "", + "===Implementation===", + "Now we build up the gates, starting with 'not' and 'and' as building blocks.", + "Those allow us to construct 'nand', 'or', and 'xor' then a half and full adders", + "and, finally, the four bit adder.", + "", + "", + "// basic building blocks allowed by the rules are ~, &, and |, we'll fake these", + "// in a way that makes what they do (at least when you use them) more obvious ", + "// than the other available options do.", + "", + "function not(a) {", + " if (arePseudoBin(a))", + " return a == 1 ? 0 : 1;", + "}", + "", + "function and(a, b) {", + " if (arePseudoBin(a, b))", + " return a + b < 2 ? 0 : 1;", + "}", + "", + "function nand(a, b) {", + " if (arePseudoBin(a, b))", + " return not(and(a, b));", + "}", + "", + "function or(a, b) {", + " if (arePseudoBin(a, b))", + " return nand(nand(a,a), nand(b,b));", + "}", + "", + "function xor(a, b) {", + " if (arePseudoBin(a, b))", + " return nand(nand(nand(a,b), a), nand(nand(a,b), b));", + "}", + "", + "function halfAdder(a, b) {", + " if (arePseudoBin(a, b))", + " return { carry: and(a, b), sum: xor(a, b) };", + "}", + "", + "function fullAdder(a, b, c) {", + " if (arePseudoBin(a, b, c)) {", + " var h0 = halfAdder(a, b), ", + " h1 = halfAdder(h0.sum, c);", + " return {carry: or(h0.carry, h1.carry), sum: h1.sum };", + " }", + "}", + "", + "function fourBitAdder(a, b) {", + " if (typeof a.length == 'undefined' || typeof b.length == 'undefined')", + " throw new Error('bad values');", + " // not sure if the rules allow this, but we need to pad the values ", + " // if they're too short and trim them if they're too long", + " var inA = Array(4), ", + " inB = Array(4), ", + " out = Array(4), ", + " i = 4, ", + " pass;", + " ", + " while (i--) {", + " inA[i] = a[i] != 1 ? 0 : 1;", + " inB[i] = b[i] != 1 ? 0 : 1;", + " }", + "", + " // now we can start adding... I'd prefer to do this in a loop, ", + " // but that wouldn't be \"connecting the other 'constructive blocks', ", + " // in turn made of 'simpler' and 'smaller' ones\"", + " ", + " pass = halfAdder(inA[3], inB[3]);", + " out[3] = pass.sum;", + " pass = fullAdder(inA[2], inB[2], pass.carry);", + " out[2] = pass.sum;", + " pass = fullAdder(inA[1], inB[1], pass.carry);", + " out[1] = pass.sum;", + " pass = fullAdder(inA[0], inB[0], pass.carry);", + " out[0] = pass.sum;", + " return out.join('');", + "}", + "", + "===Example Use===", + "fourBitAdder('1010', '0101'); // 1111 (15)", + "", + "all results:", + "", + "", + "// run this in your browsers console", + "var outer = inner = 16, a, b;", + "", + "while(outer--) {", + " a = (8|outer).toString(2);", + " while(inner--) {", + " b = (8|inner).toString(2);", + " console.log(a + ' + ' + b + ' = ' + fourBitAdder(a, b));", + " }", + " inner = outer;", + "}", + "", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e6d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nfunction acceptedBinFormat(bin) {\n if (bin == 1 || bin === 0 || bin === '0')\n return true;\n else\n return bin;\n}\n\nfunction arePseudoBin() {\n var args = [].slice.call(arguments), len = args.length;\n while(len--)\n if (acceptedBinFormat(args[len]) !== true)\n throw new Error('argument must be 0, \\'0\\', 1, or \\'1\\', argument ' + len + ' was ' + args[len]);\n return true;\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Fractran", + "type": "Waypoint", + "description": [ + "

FRACTRAN is a Turing-complete esoteric programming language invented by the mathematician John Horton Conway.

A FRACTRAN program is an ordered list of positive fractions $P = (f_1, f_2, \\ldots, f_m)$, together with an initial positive integer input $n$.

", + "

The program is run by updating the integer $n$ as follows:

for the first fraction, $f_i$, in the list for which $nf_i$ is an integer, replace $n$ with $nf_i$ ;", + "repeat this rule until no fraction in the list produces an integer when multiplied by $n$, then halt.", + "

Conway gave a program for primes in FRACTRAN:

$17/91$, $78/85$, $19/51$, $23/38$, $29/33$, $77/29$, $95/23$, $77/19$, $1/17$, $11/13$, $13/11$, $15/14$, $15/2$, $55/1$

Starting with $n=2$, this FRACTRAN program will change $n$ to $15=2\\times (15/2)$, then $825=15\\times (55/1)$, generating the following sequence of integers:

$2$, $15$, $825$, $725$, $1925$, $2275$, $425$, $390$, $330$, $290$, $770$, $\\ldots$

After 2, this sequence contains the following powers of 2:

$2^2=4$, $2^3=8$, $2^5=32$, $2^7=128$, $2^{11}=2048$, $2^{13}=8192$, $2^{17}=131072$, $2^{19}=524288$, $\\ldots$

which are the prime powers of 2.

", + "Task:", + "

Write a program that reads a list of fractions in a natural format from the keyboard or from a string,

", + "

to parse it into a sequence of fractions (i.e. two integers),

", + "

and runs the FRACTRAN starting from a provided integer, writing the result at each step.

", + "

It is also required that the number of step is limited (by a parameter easy to find).

", + "Extra credit:", + "

Use this program to derive the first 20 or so prime numbers.

", + "See also:", + "

For more on how to program FRACTRAN as a universal programming language, see:

", + "J. H. Conway (1987). Fractran: A Simple Universal Programming Language for Arithmetic. In: Open Problems in Communication and Computation, pages 4–26. Springer.", + "J. H. Conway (2010). \"FRACTRAN: A simple universal programming language for arithmetic\". In Jeffrey C. Lagarias. The Ultimate Challenge: the 3x+1 problem. American Mathematical Society. pp. 249–264. ISBN 978-0-8218-4940-8. Zbl 1216.68068.", + "Number Pathology: Fractran by Mark C. Chu-Carroll; October 27, 2006." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "var num = new Array();", + "var den = new Array();", + "var val ;", + "", + "function compile(prog){", + " var regex = /\\s*(\\d*)\\s*\\/\\s*(\\d*)\\s*(.*)/m;", + " while(regex.test(prog)){", + " num.push(regex.exec(prog)[1]);", + " den.push(regex.exec(prog)[2]);", + " prog = regex.exec(prog)[3];", + " }", + "}", + "", + "function dump(prog){", + " for(var i=0; i\";", + "}", + "", + "function step(val){", + " var i=0;", + " while(i\";", + " val = step(val);", + " i ++;", + " }", + "}", + "", + "// Main", + "compile(\"17/91 78/85 19/51 23/38 29/33 77/29 95/23 77/19 1/17 11/13 13/11 15/14 15/2 55/1\");", + "dump(); ", + "var limit = 15;", + "exec(2);", + "", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e6f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nvar num = new Array();\nvar den = new Array();\nvar val ;\n\nfunction compile(prog){\n var regex = /\\s*(\\d*)\\s*\\/\\s*(\\d*)\\s*(.*)/m;\n while(regex.test(prog)){\n num.push(regex.exec(prog)[1]);\n den.push(regex.exec(prog)[2]);\n prog = regex.exec(prog)[3];\n }\n}\n\nfunction dump(prog){\n for(var i=0; i\";\n}\n\nfunction step(val){\n var i=0;\n while(i\";\n val = step(val);\n i ++;\n }\n}\n\n// Main\ncompile(\"17/91 78/85 19/51 23/38 29/33 77/29 95/23 77/19 1/17 11/13 13/11 15/14 15/2 55/1\");\ndump(); \nvar limit = 15;\nexec(2);\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Gamma function", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement one algorithm (or more) to compute the Gamma ($\\Gamma$) function (in the real field only).

If your language has the function as built-in or you know a library which has it, compare your implementation's results with the results of the built-in/library function.

The Gamma function can be defined as:

::::: $\\Gamma(x) = \\displaystyle\\int_0^\\infty t^{x-1}e^{-t} dt$

This suggests a straightforward (but inefficient) way of computing the $\\Gamma$ through numerical integration.

", + "

Better suggested methods:

", + "Lanczos approximation", + "Stirling's approximation" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Implementation of Lanczos approximation.", + "function gamma(x) {", + " var p = [0.99999999999980993, 676.5203681218851, -1259.1392167224028,", + " 771.32342877765313, -176.61502916214059, 12.507343278686905,", + " -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7", + " ];", + "", + " var g = 7;", + " if (x < 0.5) {", + " return Math.PI / (Math.sin(Math.PI * x) * gamma(1 - x));", + " }", + "", + " x -= 1;", + " var a = p[0];", + " var t = x + g + 0.5;", + " for (var i = 1; i < p.length; i++) {", + " a += p[i] / (x + i);", + " }", + "", + " return Math.sqrt(2 * Math.PI) * Math.pow(t, x + 0.5) * Math.exp(-t) * a;", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e76", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function gamma(x) {\n var p = [0.99999999999980993, 676.5203681218851, -1259.1392167224028,\n 771.32342877765313, -176.61502916214059, 12.507343278686905,\n -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7\n ];\n\n var g = 7;\n if (x < 0.5) {\n return Math.PI / (Math.sin(Math.PI * x) * gamma(1 - x));\n }\n\n x -= 1;\n var a = p[0];\n var t = x + g + 0.5;\n for (var i = 1; i < p.length; i++) {\n a += p[i] / (x + i);\n }\n\n return Math.sqrt(2 * Math.PI) * Math.pow(t, x + 0.5) * Math.exp(-t) * a;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Gaussian elimination", + "type": "Waypoint", + "description": [ + "

Problem: Solve Ax=b using Gaussian elimination then backwards substitution. A being an n by n matrix. Also, x and b are n by 1 vectors. To improve accuracy, please use partial pivoting and scaling.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "From Numerical Recipes in C:", + "// Lower Upper Solver", + "function lusolve(A, b, update) {", + "\tvar lu = ludcmp(A, update)", + "\tif (lu === undefined) return // Singular Matrix!", + "\treturn lubksb(lu, b, update)", + "}", + "", + "// Lower Upper Decomposition", + "function ludcmp(A, update) {", + "\t// A is a matrix that we want to decompose into Lower and Upper matrices.", + "\tvar d = true", + "\tvar n = A.length", + "\tvar idx = new Array(n) // Output vector with row permutations from partial pivoting", + "\tvar vv = new Array(n) // Scaling information", + "", + "\tfor (var i=0; i max) max = temp", + "\t\t}", + "\t\tif (max == 0) return // Singular Matrix!", + "\t\tvv[i] = 1 / max // Scaling", + "\t}", + "\t", + "\tif (!update) { // make a copy of A ", + "\t\tvar Acpy = new Array(n)", + "\t\tfor (var i=0; i= max) {", + "\t\t\t\tmax = temp", + "\t\t\t\tjmax = j", + "\t\t\t}", + "\t\t}", + "\t\tif (i <= jmax) {", + "\t\t\tfor (var j=0; j -1)", + "\t\t\tfor (var j=ii; j=0; i--) {", + "\t\tvar sum = b[i]", + "\t\tfor (var j=i+1; j", + "", + "{{output}}", + "
-0.01000000000000004, 1.6027903945021095, -1.6132030599055475, 1.2454941213714232, -0.4909897195846526, 0.06576069617523138
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e77", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// Lower Upper Solver\nfunction lusolve(A, b, update) {\n\tvar lu = ludcmp(A, update)\n\tif (lu === undefined) return // Singular Matrix!\n\treturn lubksb(lu, b, update)\n}\n\n// Lower Upper Decomposition\nfunction ludcmp(A, update) {\n\t// A is a matrix that we want to decompose into Lower and Upper matrices.\n\tvar d = true\n\tvar n = A.length\n\tvar idx = new Array(n) // Output vector with row permutations from partial pivoting\n\tvar vv = new Array(n) // Scaling information\n\n\tfor (var i=0; i max) max = temp\n\t\t}\n\t\tif (max == 0) return // Singular Matrix!\n\t\tvv[i] = 1 / max // Scaling\n\t}\n\t\n\tif (!update) { // make a copy of A \n\t\tvar Acpy = new Array(n)\n\t\tfor (var i=0; i= max) {\n\t\t\t\tmax = temp\n\t\t\t\tjmax = j\n\t\t\t}\n\t\t}\n\t\tif (i <= jmax) {\n\t\t\tfor (var j=0; j -1)\n\t\t\tfor (var j=ii; j=0; i--) {\n\t\tvar sum = b[i]\n\t\tfor (var j=i+1; jreplaceMe is a function.');" + ] + }, + { + "title": "General FizzBuzz", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a generalized version of FizzBuzz that works for any list of factors, along with their words.

This is basically a \"fizzbuzz\" implementation where the user supplies the parameters.

The user will enter the max number, then they will enter the factors to be calculated along with the corresponding word to be printed.

For simplicity's sake, assume the user will input an integer as the max number and 3 factors, each with a word associated with them.

", + "

For example, given:

", + "
",
+      ">20      #This is the maximum number, supplied by the user",
+      ">3 Fizz  #The user now enters the starting factor (3) and the word they want associated with it (Fizz)",
+      ">5 Buzz  #The user now enters the next factor (5) and the word they want associated with it (Buzz)",
+      ">7 Baxx  #The user now enters the next factor (7) and the word they want associated with it (Baxx)",
+      "

In other words: For this example, print the numbers 1 through 20, replacing every multiple of 3 with \"Fizz\", every multiple of 5 with \"Buzz\", and every multiple of 7 with \"Baxx\".

In the case where a number is a multiple of at least two factors, print each of the words associated with those factors in the order of least to greatest factor.

For instance, the number 15 is a multiple of both 3 and 5; print \"FizzBuzz\".

If the max number was 105 instead of 20, you would print \"FizzBuzzBaxx\" because it's a multiple of 3, 5, and 7.

", + "
",
+      "1",
+      "2",
+      "Fizz",
+      "4",
+      "Buzz",
+      "Fizz",
+      "Baxx",
+      "8",
+      "Fizz",
+      "Buzz",
+      "11",
+      "Fizz",
+      "13",
+      "Baxx",
+      "FizzBuzz",
+      "16",
+      "17",
+      "Fizz",
+      "19",
+      "Buzz",
+      "
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "In a functional style of JavaScript, with two nested ''reduce'' folds – one through the integer series,", + "and one through the series of rules.", + "", + "First as compacted by Google's Closure compiler:", + "function fizz(d, e) {", + " return function b(a) {", + " return a ? b(a - 1).concat(a) : [];", + " }(e).reduce(function (b, a) {", + " return b + (d.reduce(function (b, c) {", + " return b + (a % c[0] ? \"\" : c[1]);", + " }, \"\") || a.toString()) + \"\\n\";", + " }, \"\");", + "}", + "", + "and then in the original expanded form, for better legibility:", + "", + "function fizz(lstRules, lngMax) {", + "", + " return (", + " function rng(i) {", + " return i ? rng(i - 1).concat(i) : []", + " }", + " )(lngMax).reduce(", + " function (strSeries, n) {", + "", + " // The next member of the series of lines:", + " // a word string or a number string", + " return strSeries + (", + " lstRules.reduce(", + " function (str, tplNumWord) {", + " return str + (", + " n % tplNumWord[0] ? '' : tplNumWord[1]", + " )", + " }, ''", + " ) || n.toString()", + " ) + '\\n';", + " ", + " }, ''", + " );", + "}", + "", + "fizz([[3, 'Fizz'], [5, 'Buzz'], [7, 'Baxx']], 20);", + "", + "{{out}}", + "
1",
+      "2",
+      "Fizz",
+      "4",
+      "Buzz",
+      "Fizz",
+      "Baxx",
+      "8",
+      "Fizz",
+      "Buzz",
+      "11",
+      "Fizz",
+      "13",
+      "Baxx",
+      "FizzBuzz",
+      "16",
+      "17",
+      "Fizz",
+      "19",
+      "Buzz
", + "", + "", + "===ES6===", + "", + "(() => {", + "", + " // fizz :: [[Int, String]] -> Int -> String", + " const fizz = (lstRules, lngMax) => range(1, lngMax)", + " .reduce((strSeries, n) =>", + "", + " // The next member of the series of lines:", + " // a word string or a number string", + " strSeries + (", + " lstRules", + " .reduce((str, tplNumWord) =>", + " str + (", + " n % tplNumWord[0] ? '' : tplNumWord[1]", + " ),", + " ''", + " ) || n.toString()", + " ) + '\\n', ''", + " );", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + "", + " return fizz([", + " [3, 'Fizz'],", + " [5, 'Buzz'],", + " [7, 'Baxx']", + " ], 20);", + "", + "})();", + "", + "", + "{{Out}}", + "
1",
+      "2",
+      "Fizz",
+      "4",
+      "Buzz",
+      "Fizz",
+      "Baxx",
+      "8",
+      "Fizz",
+      "Buzz",
+      "11",
+      "Fizz",
+      "13",
+      "Baxx",
+      "FizzBuzz",
+      "16",
+      "17",
+      "Fizz",
+      "19",
+      "Buzz",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e78", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function fizz(d, e) {\n return function b(a) {\n return a ? b(a - 1).concat(a) : [];\n }(e).reduce(function (b, a) {\n return b + (d.reduce(function (b, c) {\n return b + (a % c[0] ? \"\" : c[1]);\n }, \"\") || a.toString()) + \"\\n\";\n }, \"\");\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Generate Chess960 starting position", + "type": "Waypoint", + "description": [ + "

Chess960 is a variant of chess created by world champion Bobby Fischer. Unlike other variants of the game, Chess960 does not require a different material, but instead relies on a random initial position, with a few constraints:

as in the standard chess game, all eight white pawns must be placed on the second rank.", + "White pieces must stand on the first rank as in the standard game, in random column order but with the two following constraints:", + "* the bishops must be placed on opposite color squares (i.e. they must be an odd number of spaces apart or there must be an even number of spaces between them)", + "* the King must be between two rooks (with any number of other pieces between them all)", + "Black pawns and pieces must be placed respectively on the seventh and eighth ranks, mirroring the white pawns and pieces, just as in the standard game. (That is, their positions are not independently randomized.)", + "

With those constraints there are 960 possible starting positions, thus the name of the variant.

", + "Task:", + "

The purpose of this task is to write a program that can randomly generate any one of the 960 Chess960 initial positions. You will show the result as the first rank displayed with Chess symbols in Unicode: ♔♕♖♗♘ or with the letters King Queen Rook Bishop kNight.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "This conforms to Altendörfer's single die method[https://en.wikipedia.org/wiki/Chess960_starting_position#Single_die_method], though the die will give no \"needless\" numbers.", + "function ch960startPos() {", + " var rank = new Array(8),", + " // randomizer (our die)", + " d = function(num) { return Math.floor(Math.random() * ++num) },", + " emptySquares = function() {", + " var arr = [];", + " for (var i = 0; i < 8; i++) if (rank[i] == undefined) arr.push(i);", + " return arr;", + " };", + " // place one bishop on any black square", + " rank[d(2) * 2] = \"♗\";", + " // place the other bishop on any white square", + " rank[d(2) * 2 + 1] = \"♗\";", + " // place the queen on any empty square", + " rank[emptySquares()[d(5)]] = \"♕\";", + " // place one knight on any empty square", + " rank[emptySquares()[d(4)]] = \"♘\";", + " // place the other knight on any empty square", + " rank[emptySquares()[d(3)]] = \"♘\";", + " // place the rooks and the king on the squares left, king in the middle", + " for (var x = 1; x <= 3; x++) rank[emptySquares()[0]] = x==2 ? \"♔\" : \"♖\";", + " return rank;", + "}", + "", + "// testing (10 times)", + "for (var x = 1; x <= 10; x++) console.log(ch960startPos().join(\" | \"));", + "{{out}}", + "

The test-output (exemplary each):

", + "♖ | ♗ | ♗ | ♔ | ♘ | ♖ | ♘ | ♕
", + "♗ | ♗ | ♕ | ♖ | ♔ | ♘ | ♘ | ♖
", + "♖ | ♕ | ♘ | ♗ | ♗ | ♔ | ♘ | ♖
", + "♖ | ♗ | ♔ | ♘ | ♗ | ♕ | ♘ | ♖
", + "♗ | ♖ | ♕ | ♔ | ♘ | ♗ | ♘ | ♖
", + "♖ | ♗ | ♗ | ♕ | ♔ | ♘ | ♖ | ♘
", + "♗ | ♘ | ♖ | ♗ | ♔ | ♘ | ♕ | ♖
", + "♕ | ♘ | ♗ | ♖ | ♔ | ♗ | ♖ | ♘
", + "♗ | ♘ | ♖ | ♘ | ♕ | ♗ | ♔ | ♖
", + "♘ | ♗ | ♖ | ♔ | ♗ | ♘ | ♖ | ♕
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e79", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function ch960startPos() {\n var rank = new Array(8),\n // randomizer (our die)\n d = function(num) { return Math.floor(Math.random() * ++num) },\n emptySquares = function() {\n var arr = [];\n for (var i = 0; i < 8; i++) if (rank[i] == undefined) arr.push(i);\n return arr;\n };\n // place one bishop on any black square\n rank[d(2) * 2] = \"♗\";\n // place the other bishop on any white square\n rank[d(2) * 2 + 1] = \"♗\";\n // place the queen on any empty square\n rank[emptySquares()[d(5)]] = \"♕\";\n // place one knight on any empty square\n rank[emptySquares()[d(4)]] = \"♘\";\n // place the other knight on any empty square\n rank[emptySquares()[d(3)]] = \"♘\";\n // place the rooks and the king on the squares left, king in the middle\n for (var x = 1; x <= 3; x++) rank[emptySquares()[0]] = x==2 ? \"♔\" : \"♖\";\n return rank;\n}\n\n// testing (10 times)\nfor (var x = 1; x <= 10; x++) console.log(ch960startPos().join(\" | \"));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Generate lower case ASCII alphabet", + "type": "Waypoint", + "description": [ + "Task:", + "

Generate an array, list, lazy sequence, or even an indexable string of all the lower case ASCII characters, from a to z. If the standard library contains such a sequence, show how to access it, but don't fail to show how to generate a similar sequence.

For this basic task use a reliable style of coding, a style fit for a very large program, and use strong typing if available. It's bug prone to enumerate all the lowercase characters manually in the code. During code review it's not immediate obvious to spot the bug in a Tcl line like this contained in a page of code:

", + "

set alpha {a b c d e f g h i j k m n o p q r s t u v w x y z}

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "In ES5, we can use '''String.fromCharCode()''', which suffices for Unicode characters which can be represented with one 16 bit number.", + "", + "For Unicode characters beyond this range, in ES5 we have to enter a pair of Unicode number escapes.", + "", + "(function (cFrom, cTo) {", + "", + " function cRange(cFrom, cTo) {", + " var iStart = cFrom.charCodeAt(0);", + "", + " return Array.apply(", + " null, Array(cTo.charCodeAt(0) - iStart + 1)", + " ).map(function (_, i) {", + "", + " return String.fromCharCode(iStart + i);", + "", + " });", + " }", + "", + " return cRange(cFrom, cTo);", + "", + "})('a', 'z');", + "", + "Returns:", + "[\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\"]", + "", + "===ES6===", + "", + "In ES6, the new '''String.fromCodePoint()''' method can can return 4-byte characters (such as Emoji, for example) as well as the usual 2-byte characters.", + "", + "(function (lstRanges) {", + "", + " function cRange(cFrom, cTo) {", + " var iStart = cFrom.codePointAt(0);", + "", + " return Array.apply(", + " null, Array(cTo.codePointAt(0) - iStart + 1)", + " ).map(function (_, i) {", + "", + " return String.fromCodePoint(iStart + i);", + "", + " });", + " }", + "", + " return lstRanges.map(function (lst) {", + " return cRange(lst[0], lst[1]);", + " });", + "", + "})([", + " ['a', 'z'],", + " ['🐐', '🐟']", + "]); ", + "", + "Output:", + "", + "[[\"a\", \"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\", \"i\", \"j\", \"k\", \"l\", \"m\", \"n\", \"o\", \"p\", \"q\", \"r\", \"s\", \"t\", \"u\", \"v\", \"w\", \"x\", \"y\", \"z\"],", + " [\"🐐\", \"🐑\", \"🐒\", \"🐓\", \"🐔\", \"🐕\", \"🐖\", \"🐗\", \"🐘\", \"🐙\", \"🐚\", \"🐛\", \"🐜\", \"🐝\", \"🐞\", \"🐟\"]] ", + "", + "{{works with|ECMAScript|6}}", + "var letters = []", + "for (var i = 97; i <= 122; i++) {", + " letters.push(String.fromCodePoint(i))", + "}", + "", + "Or, if we want to write a more general ES6 function:", + "", + "(() => {", + " // enumFromTo :: Enum a => a -> a -> [a]", + " const enumFromTo = (m, n) => {", + " const [intM, intN] = [m, n].map(fromEnum),", + " f = typeof m === 'string' ? (", + " (_, i) => chr(intM + i)", + " ) : (_, i) => intM + i;", + " return Array.from({", + " length: Math.floor(intN - intM) + 1", + " }, f);", + " };", + "", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // compose :: (b -> c) -> (a -> b) -> (a -> c)", + " const compose = (f, g) => x => f(g(x));", + "", + " // chr :: Int -> Char", + " const chr = x => String.fromCodePoint(x);", + "", + " // ord :: Char -> Int", + " const ord = c => c.codePointAt(0);", + "", + " // fromEnum :: Enum a => a -> Int", + " const fromEnum = x => {", + " const type = typeof x;", + " return type === 'boolean' ? (", + " x ? 1 : 0", + " ) : type === 'string' ? ord(x) : x;", + " };", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x);", + "", + " // uncurry :: Function -> Function", + " const uncurry = f => args => f.apply(null, args);", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // unwords :: [String] -> String", + " const unwords = xs => xs.join(' ');", + "", + " // TEST -------------------------------------------------------------------", + " return unlines(map(compose(unwords, uncurry(enumFromTo)), [", + " ['a', 'z'],", + " ['α', 'ω'],", + " ['א', 'ת'],", + " ['🐐', '🐟']", + " ]));", + "})();", + "{{Out}}", + "
a b c d e f g h i j k l m n o p q r s t u v w x y z",
+      "α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς σ τ υ φ χ ψ ω",
+      "א ב ג ד ה ו ז ח ט י ך כ ל ם מ ן נ ס ע ף פ ץ צ ק ר ש ת",
+      "🐐 🐑 🐒 🐓 🐔 🐕 🐖 🐗 🐘 🐙 🐚 🐛 🐜 🐝 🐞 🐟
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e7a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function (cFrom, cTo) {\n\n function cRange(cFrom, cTo) {\n var iStart = cFrom.charCodeAt(0);\n\n return Array.apply(\n null, Array(cTo.charCodeAt(0) - iStart + 1)\n ).map(function (_, i) {\n\n return String.fromCharCode(iStart + i);\n\n });\n }\n\n return cRange(cFrom, cTo);\n\n})('a', 'z');\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Generator/Exponential", + "type": "Waypoint", + "description": [ + "

A generator is an executable entity (like a function or procedure) that contains code that yields a sequence of values, one at a time, so that each time you call the generator, the next value in the sequence is provided.

", + "

Generators are often built on top of coroutines or objects so that the internal state of the object is handled “naturally”.

", + "

Generators are often used in situations where a sequence is potentially infinite, and where it is possible to construct the next value of the sequence with only minimal state.

Task description

Create a function that returns a generation of the m'th powers of the positive integers starting from zero, in order, and without obvious or simple upper limit. (Any upper limit to the generator should not be stated in the source but should be down to factors such as the languages natural integer size limit or computational time/size).", + "Use it to create a generator of:# Squares.", + "

# Cubes.

", + "Create a new generator that filters all cubes from the generator of squares.", + "Drop the first 20 values from this last generator of filtered results then show the next 10 valuesNote that this task requires the use of generators in the calculation of the result.

See also

", + "Generator" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|Firefox 3.6 using JavaScript 1.7|}} ", + "", + "", + "function PowersGenerator(m) {", + "\tvar n=0;", + "\twhile(1) {", + "\t\tyield Math.pow(n, m);", + "\t\tn += 1;\t", + "\t}", + "}", + "", + "function FilteredGenerator(g, f){", + "\tvar value = g.next();", + "\tvar filter = f.next();", + "\t", + "\twhile(1) {", + "\t\tif( value < filter ) {", + "\t\t\tyield value;", + "\t\t\tvalue = g.next();", + "\t\t} else if ( value > filter ) {", + "\t\t\tfilter = f.next();", + "\t\t} else {", + "\t\t\tvalue = g.next();", + "\t\t\tfilter = f.next();", + "\t\t}", + "\t}\t", + "}", + "", + "", + "", + "var squares = PowersGenerator(2);", + "var cubes = PowersGenerator(3);", + "", + "var filtered = FilteredGenerator(squares, cubes);", + "", + "", + "", + "for( var x = 0; x < 20; x++ ) filtered.next()", + "for( var x = 20; x < 30; x++ ) console.logfiltered.next());", + "", + "", + "", + "===ES6===", + "function* nPowerGen(n) {", + " let e = 0;", + " while (1) { e++ && (yield Math.pow(e, n)); }", + "}", + "", + "function* filterGen(gS, gC, skip=0) {", + " let s = 0; // The square value", + " let c = 0; // The cube value", + " let n = 0; // A skip counter", + "", + " while(1) {", + " s = gS.next().value;", + " s > c && (c = gC.next().value);", + " s == c ?", + " c = gC.next().value :", + " n++ && n > skip && (yield s);", + " }", + "}", + "", + "const filtered = filterGen(nPowerGen(2), nPowerGen(3), skip=20);", + "// Generate the first 10 values", + "for (let n = 0; n < 10; n++) {", + " console.log(filtered.next().value)", + "}", + "
529",
+      "576",
+      "625",
+      "676",
+      "784",
+      "841",
+      "900",
+      "961",
+      "1024",
+      "1089
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e7b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nfunction PowersGenerator(m) {\n\tvar n=0;\n\twhile(1) {\n\t\tyield Math.pow(n, m);\n\t\tn += 1;\t\n\t}\n}\n\nfunction FilteredGenerator(g, f){\n\tvar value = g.next();\n\tvar filter = f.next();\n\t\n\twhile(1) {\n\t\tif( value < filter ) {\n\t\t\tyield value;\n\t\t\tvalue = g.next();\n\t\t} else if ( value > filter ) {\n\t\t\tfilter = f.next();\n\t\t} else {\n\t\t\tvalue = g.next();\n\t\t\tfilter = f.next();\n\t\t}\n\t}\t\n}\n\n\n\nvar squares = PowersGenerator(2);\nvar cubes = PowersGenerator(3);\n\nvar filtered = FilteredGenerator(squares, cubes);\n\n\n\nfor( var x = 0; x < 20; x++ ) filtered.next()\nfor( var x = 20; x < 30; x++ ) console.logfiltered.next());\n\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Gray code", + "type": "Waypoint", + "description": [ + "

Gray code is a form of binary encoding where transitions between consecutive numbers differ by only one bit. This is a useful encoding for reducing hardware data hazards with values that change rapidly and/or connect to slower hardware as inputs. It is also useful for generating inputs for Karnaugh maps in order from left to right or top to bottom.

Create functions to encode a number to and decode a number from Gray code.

Display the normal binary representations, Gray code representations, and decoded Gray code values for all 5-bit binary numbers (0-31 inclusive, leading 0's not necessary).

There are many possible Gray codes. The following encodes what is called \"binary reflected Gray code.\"

Encoding (MSB is bit 0, b is binary, g is Gray code):

if b[i-1] = 1",
+      "   g[i] = not b[i]",
+      "else",
+      "   g[i] = b[i]

Or:

g = b xor (b logically right shifted 1 time)

Decoding (MSB is bit 0, b is binary, g is Gray code):

b[0] = g[0]for other bits:",
+      "b[i] = g[i] xor b[i-1]
Reference", + "Converting Between Gray and Binary Codes. It includes step-by-step animations." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e80", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Greatest common divisor", + "type": "Waypoint", + "description": [ + "Task:", + "

Find the greatest common divisor of two integers.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Iterative implementation", + "function gcd(a,b) {", + " a = Math.abs(a);", + " b = Math.abs(b);", + "", + " if (b > a) {", + " var temp = a;", + " a = b;", + " b = temp; ", + " }", + "", + " while (true) {", + " a %= b;", + " if (a === 0) { return b; }", + " b %= a;", + " if (b === 0) { return a; }", + " }", + "}", + "", + "Recursive.", + "function gcd_rec(a, b) {", + " return b ? gcd_rec(b, a % b) : Math.abs(a);", + "}", + "", + "Implementation that works on an array of integers.", + "function GCD(arr) {", + " var i, y,", + " n = arr.length,", + " x = Math.abs(arr[0]);", + "", + " for (i = 1; i < n; i++) {", + " y = Math.abs(arr[i]);", + "", + " while (x && y) {", + " (x > y) ? x %= y : y %= x;", + " }", + " x += y;", + " }", + " return x;", + "}", + "", + "//For example:", + "GCD([57,0,-45,-18,90,447]); //=> 3", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e82", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function gcd(a,b) {\n a = Math.abs(a);\n b = Math.abs(b);\n\n if (b > a) {\n var temp = a;\n a = b;\n b = temp; \n }\n\n while (true) {\n a %= b;\n if (a === 0) { return b; }\n b %= a;\n if (b === 0) { return a; }\n }\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Greatest subsequential sum", + "type": "Waypoint", + "description": [ + "Task:", + "

Given a sequence of integers, find a continuous subsequence which maximizes the sum of its elements, that is, the elements of no other single subsequence add up to a value larger than this one.

", + "

An empty subsequence is considered to have the sum of 0; thus if all elements are negative, the result must be the empty sequence.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Simple brute force approach.", + "function MaximumSubsequence(population) {", + " var maxValue = 0;", + " var subsequence = [];", + "", + " for (var i = 0, len = population.length; i < len; i++) {", + " for (var j = i; j <= len; j++) {", + " var subsequence = population.slice(i, j);", + " var value = sumValues(subsequence);", + " if (value > maxValue) {", + " maxValue = value;", + " greatest = subsequence;", + " };", + " }", + " }", + "", + " return greatest;", + "}", + "", + "function sumValues(arr) {", + " var result = 0;", + " for (var i = 0, len = arr.length; i < len; i++) {", + " result += arr[i];", + " }", + " return result;", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e84", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function MaximumSubsequence(population) {\n var maxValue = 0;\n var subsequence = [];\n\n for (var i = 0, len = population.length; i < len; i++) {\n for (var j = i; j <= len; j++) {\n var subsequence = population.slice(i, j);\n var value = sumValues(subsequence);\n if (value > maxValue) {\n maxValue = value;\n greatest = subsequence;\n };\n }\n }\n\n return greatest;\n}\n\nfunction sumValues(arr) {\n var result = 0;\n for (var i = 0, len = arr.length; i < len; i++) {\n result += arr[i];\n }\n return result;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Guess the number/With feedback (player)", + "type": "Waypoint", + "description": [ + "

The task is to write a player for the game that follows the following rules:

", + "

The scorer will choose a number between set limits. The computer player will print a guess of the target number. The computer asks for a score of whether its guess is higher than, lower than, or equal to the target. The computer guesses, and the scorer scores, in turn, until the computer correctly guesses the target number.

The computer should guess intelligently based on the accumulated scores given. One way is to use a Binary search based algorithm.

Cf. ", + "Guess the number/With Feedback", + "Bulls and cows/Player" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "=== Spidermonkey version ===", + "", + "A boring solution that does nothing clever or inscrutable.", + "", + "Well, it does use recursion for the guessing function, but that's OK because the depth is bounded by LOG2 of the range. That's not true if the user changes his number, but then he gets what he deserves.", + "", + "#!/usr/bin/env js", + "", + "var DONE = RIGHT = 0, HIGH = 1, LOW = -1;", + "", + "function main() {", + " showInstructions();", + " while (guess(1, 100) !== DONE);", + "}", + "", + "function guess(low, high) {", + " if (low > high) {", + " print(\"I can't guess it. Perhaps you changed your number.\");", + " return DONE;", + " }", + " ", + " var g = Math.floor((low + high) / 2);", + " var result = getResult(g);", + " switch (result) {", + " case RIGHT:", + " return DONE;", + " case LOW:", + " return guess(g + 1, high);", + " case HIGH:", + " return guess(low, g - 1);", + " }", + "}", + "", + "function getResult(g) {", + " while(true) {", + " putstr('Is it ' + g + '? ');", + " var ans = readline().toUpperCase().replace(/^\\s+/, '') + ' ';", + " switch (ans[0]) {", + " case 'R':", + " print('I got it! Thanks for the game.');", + " return RIGHT;", + " case 'L': ", + " return LOW;", + " case 'H':", + " return HIGH;", + " default:", + " print('Please tell me if I am \"high\", \"low\" or \"right\".');", + " }", + " }", + "}", + "", + "function showInstructions() {", + " print('Think of a number between 1 and 100 and I will try to guess it.');", + " print('After I guess, type \"low\", \"high\" or \"right\", and then press enter.');", + " putstr(\"When you've thought of a number press enter.\");", + " readline();", + "}", + "", + "main();", + "", + "", + "An example session:", + " Think of a number between 1 and 100 and I will try to guess it.", + " After I guess, type \"low\", \"high\" or \"right\", and then press enter.", + " When you've thought of a number press enter.", + " Is it 50? high", + " Is it 25? high", + " Is it 12? low", + " Is it 18? high", + " Is it 15? high", + " Is it 13? right", + " I got it! Thanks for the game.", + "", + "Another example session:", + " Think of a number between 1 and 100 and I will try to guess it.", + " After I guess, type \"low\", \"high\" or \"right\", and then press enter.", + " When you've thought of a number press enter.", + " Is it 50? n", + " Please tell me if I am \"high\", \"low\" or \"right\".", + " Is it 50? h", + " Is it 25? h", + " Is it 12? h", + " Is it 6? h", + " Is it 3? h", + " Is it 1? h", + " I can't guess it. Perhaps you changed your number.", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e87", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "#!/usr/bin/env js\n\nvar DONE = RIGHT = 0, HIGH = 1, LOW = -1;\n\nfunction main() {\n showInstructions();\n while (guess(1, 100) !== DONE);\n}\n\nfunction guess(low, high) {\n if (low > high) {\n print(\"I can't guess it. Perhaps you changed your number.\");\n return DONE;\n }\n \n var g = Math.floor((low + high) / 2);\n var result = getResult(g);\n switch (result) {\n case RIGHT:\n return DONE;\n case LOW:\n return guess(g + 1, high);\n case HIGH:\n return guess(low, g - 1);\n }\n}\n\nfunction getResult(g) {\n while(true) {\n putstr('Is it ' + g + '? ');\n var ans = readline().toUpperCase().replace(/^\\s+/, '') + ' ';\n switch (ans[0]) {\n case 'R':\n print('I got it! Thanks for the game.');\n return RIGHT;\n case 'L': \n return LOW;\n case 'H':\n return HIGH;\n default:\n print('Please tell me if I am \"high\", \"low\" or \"right\".');\n }\n }\n}\n\nfunction showInstructions() {\n print('Think of a number between 1 and 100 and I will try to guess it.');\n print('After I guess, type \"low\", \"high\" or \"right\", and then press enter.');\n putstr(\"When you've thought of a number press enter.\");\n readline();\n}\n\nmain();\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Hamming numbers", + "type": "Waypoint", + "description": [ + "

Hamming numbers are numbers of the form

", + "

H = 2i × 3j × 5k

", + "

where

", + "

i, j, k ≥ 0

Hamming numbers are also known as ugly numbers and also 5-smooth numbers (numbers whose prime divisors are less or equal to 5).

", + "Task:", + "

Generate the sequence of Hamming numbers, in increasing order. In particular:

", + "Show the first twenty Hamming numbers.", + "Show the 1691st Hamming number (the last one below 231).", + "Show the one millionth Hamming number (if the language – or a convenient library – supports arbitrary-precision integers).References:", + "Hamming numbers", + "Smooth number", + "Hamming problem from Dr. Dobb's CodeTalk (dead link as of Sep 2011; parts of the thread here and here)." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|JavaScript|1.7}} {{works with|Firefox|2}}", + "{{trans|Ruby}}", + "This does not calculate the 1,000,000th Hamming number.", + "", + "Note the use of '''for''' (x in obj) to iterate over the ''properties'' of an object, versus '''for each''' (y in obj) to iterate over the ''values'' of the properties of an object.", + "function hamming() {", + " var queues = {2: [], 3: [], 5: []};", + " var base;", + " var next_ham = 1;", + " while (true) {", + " yield next_ham;", + "", + " for (base in queues) {queues[base].push(next_ham * base)}", + "", + " next_ham = [ queue[0] for each (queue in queues) ].reduce(function(min, val) {", + " return Math.min(min,val)", + " });", + "", + " for (base in queues) {if (queues[base][0] == next_ham) queues[base].shift()}", + " }", + "}", + "", + "var ham = hamming();", + "var first20=[], i=1;", + "", + "for (; i <= 20; i++) ", + " first20.push(ham.next());", + "print(first20.join(', '));", + "print('...');", + "for (; i <= 1690; i++) ", + " ham.next();", + "print(i + \" => \" + ham.next());", + "{{out}}", + "
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36",
+      "...",
+      "1691 => 2125764000 
", + "", + "===Fast & complete version===", + "", + "{{trans|C#}}", + "", + "A translation of my fast C# version. I was curious to see how much slower JavaScript is. The result: it runs about 5x times slower than C#, though YMMV. You can try it yourself here: http://jsfiddle.net/N7AFN/", + "", + "--Mike Lorenz", + "", + "", + "", + "", + "
", + "", + "", + "", + "", + "
", + "", + "{{out}}", + "
5-Smooth:",
+      "",
+      "1:\t\t1",
+      "2:\t\t2",
+      "3:\t\t3",
+      "4:\t\t4",
+      "5:\t\t5",
+      "6:\t\t6",
+      "7:\t\t8",
+      "8:\t\t9",
+      "9:\t\t10",
+      "10:\t\t12",
+      "11:\t\t15",
+      "12:\t\t16",
+      "13:\t\t18",
+      "14:\t\t20",
+      "15:\t\t24",
+      "16:\t\t25",
+      "17:\t\t27",
+      "18:\t\t30",
+      "19:\t\t32",
+      "20:\t\t36",
+      "1691:\t\t2125764000",
+      "1000000:\t519312780448388736089589843750000000000000000000000000000000000000000000000000000000",
+      "Elapsed time:\t1.73 seconds",
+      "",
+      "7-Smooth:",
+      "",
+      "1:\t\t1",
+      "2:\t\t2",
+      "3:\t\t3",
+      "4:\t\t4",
+      "5:\t\t5",
+      "6:\t\t6",
+      "7:\t\t7",
+      "8:\t\t8",
+      "9:\t\t9",
+      "10:\t\t10",
+      "11:\t\t12",
+      "12:\t\t14",
+      "13:\t\t15",
+      "14:\t\t16",
+      "15:\t\t18",
+      "16:\t\t20",
+      "17:\t\t21",
+      "18:\t\t24",
+      "19:\t\t25",
+      "20:\t\t27",
+      "1691:\t\t3317760",
+      "1000000:\t4157409948433216829957008507500000000",
+      "Elapsed time:\t1.989 seconds
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7e8d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function hamming() {\n var queues = {2: [], 3: [], 5: []};\n var base;\n var next_ham = 1;\n while (true) {\n yield next_ham;\n\n for (base in queues) {queues[base].push(next_ham * base)}\n\n next_ham = [ queue[0] for each (queue in queues) ].reduce(function(min, val) {\n return Math.min(min,val)\n });\n\n for (base in queues) {if (queues[base][0] == next_ham) queues[base].shift()}\n }\n}\n\nvar ham = hamming();\nvar first20=[], i=1;\n\nfor (; i <= 20; i++) \n first20.push(ham.next());\nprint(first20.join(', '));\nprint('...');\nfor (; i <= 1690; i++) \n ham.next();\nprint(i + \" => \" + ham.next());\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "IBAN", + "type": "Waypoint", + "description": [ + "

The International Bank Account Number (IBAN) is an internationally agreed means of identifying bank accounts across national borders with a reduced risk of propagating transcription errors.

The IBAN consists of up to 34 alphanumeric characters:

", + "

:* first the two-letter ISO 3166-1 alpha-2 country code,

", + "

:* then two check digits, and

", + "

:* finally a country-specific Basic Bank Account Number (BBAN).

", + "

The check digits enable a sanity check of the bank account number to confirm its integrity even before submitting a transaction.

", + "Task:", + "

Validate the following fictitious IBAN: GB82 WEST 1234 5698 7654 32

", + "

Details of the algorithm can be found on the Wikipedia page.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var ibanLen = { ", + "\tNO:15, BE:16, DK:18, FI:18, FO:18, GL:18, NL:18, MK:19,", + "\tSI:19, AT:20, BA:20, EE:20, KZ:20, LT:20, LU:20, CR:21,", + "\tCH:21, HR:21, LI:21, LV:21, BG:22, BH:22, DE:22, GB:22,", + "\tGE:22, IE:22, ME:22, RS:22, AE:23, GI:23, IL:23, AD:24,", + "\tCZ:24, ES:24, MD:24, PK:24, RO:24, SA:24, SE:24, SK:24,", + "\tVG:24, TN:24, PT:25, IS:26, TR:26, FR:27, GR:27, IT:27,", + "\tMC:27, MR:27, SM:27, AL:28, AZ:28, CY:28, DO:28, GT:28,", + "\tHU:28, LB:28, PL:28, BR:29, PS:29, KW:30, MU:30, MT:31", + "}", + "", + "function isValid(iban) {", + "\tiban = iban.replace(/\\s/g, '')", + "\tif (!iban.match(/^[\\dA-Z]+$/)) return false", + "\tvar len = iban.length", + "\tif (len != ibanLen[iban.substr(0,2)]) return false", + "\tiban = iban.substr(4) + iban.substr(0,4)", + "\tfor (var s='', i=0; i') // true", + "document.write(isValid('GB82 WEST 1.34 5698 7654 32'), '
') // false", + "document.write(isValid('GB82 WEST 1234 5698 7654 325'), '
') // false", + "document.write(isValid('GB82 TEST 1234 5698 7654 32'), '
') // false", + "document.write(isValid('SA03 8000 0000 6080 1016 7519'), '
') // true", + "
", + "{{out}}", + " true", + " false", + " false", + " false", + " true", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eaf", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var ibanLen = { \n\tNO:15, BE:16, DK:18, FI:18, FO:18, GL:18, NL:18, MK:19,\n\tSI:19, AT:20, BA:20, EE:20, KZ:20, LT:20, LU:20, CR:21,\n\tCH:21, HR:21, LI:21, LV:21, BG:22, BH:22, DE:22, GB:22,\n\tGE:22, IE:22, ME:22, RS:22, AE:23, GI:23, IL:23, AD:24,\n\tCZ:24, ES:24, MD:24, PK:24, RO:24, SA:24, SE:24, SK:24,\n\tVG:24, TN:24, PT:25, IS:26, TR:26, FR:27, GR:27, IT:27,\n\tMC:27, MR:27, SM:27, AL:28, AZ:28, CY:28, DO:28, GT:28,\n\tHU:28, LB:28, PL:28, BR:29, PS:29, KW:30, MU:30, MT:31\n}\n\nfunction isValid(iban) {\n\tiban = iban.replace(/\\s/g, '')\n\tif (!iban.match(/^[\\dA-Z]+$/)) return false\n\tvar len = iban.length\n\tif (len != ibanLen[iban.substr(0,2)]) return false\n\tiban = iban.substr(4) + iban.substr(0,4)\n\tfor (var s='', i=0; i') // true\ndocument.write(isValid('GB82 WEST 1.34 5698 7654 32'), '
') // false\ndocument.write(isValid('GB82 WEST 1234 5698 7654 325'), '
') // false\ndocument.write(isValid('GB82 TEST 1234 5698 7654 32'), '
') // false\ndocument.write(isValid('SA03 8000 0000 6080 1016 7519'), '
') // true\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "I before E except after C", + "type": "Waypoint", + "description": [ + "

The phrase \"I before E, except after C\" is a

", + "

widely known mnemonic which is supposed to help when spelling English words.

", + "Task:", + "

Using the word list from http://www.puzzlers.org/pub/wordlists/unixdict.txt,

", + "check if the two sub-clauses of the phrase are plausible individually:", + "

::# \"I before E when not preceded by C\"

", + "

::# \"E before I when preceded by C\"

", + "

If both sub-phrases are plausible then the original phrase can be said to be plausible.

Something is plausible if the number of words having the feature is more than two times the number of words having the opposite feature (where feature is 'ie' or 'ei' preceded or not by 'c' as appropriate).

", + "Stretch goal:", + "

As a stretch goal use the entries from the table of Word Frequencies in Written and Spoken English: based on the British National Corpus, (selecting those rows with three space or tab separated words only), to see if the phrase is plausible when word frequencies are taken into account.

", + "

Show your output here as well as your program.

", + "cf.:", + "Schools to rethink 'i before e' - BBC news, 20 June 2009", + "I Before E Except After C - QI Series 8 Ep 14, (humorous)", + "Companion website for the book: \"Word Frequencies in Written and Spoken English: based on the British National Corpus\"." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eb0", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Identity matrix", + "type": "Waypoint", + "description": [ + "Task:", + "

Build an identity matrix of a size known at run-time.

", + "

An identity matrix is a square matrix of size n × n,

", + "where the diagonal elements are all 1s (ones), ", + "and all the other elements are all 0s (zeroes).", + "

$I_n = \\begin{bmatrix}

", + "

1 & 0 & 0 & \\cdots & 0 \\\\

", + "

0 & 1 & 0 & \\cdots & 0 \\\\

", + "

0 & 0 & 1 & \\cdots & 0 \\\\

", + "

\\vdots & \\vdots & \\vdots & \\ddots & \\vdots \\\\

", + "

0 & 0 & 0 & \\cdots & 1 \\\\

", + "

\\end{bmatrix}$

", + "Related tasks:", + " Spiral matrix", + " Zig-zag matrix ", + " Ulam_spiral_(for_primes)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "function idMatrix(n) {", + " return Array.apply(null, new Array(n))", + " .map(function (x, i, xs) {", + " return xs.map(function (_, k) {", + " return i === k ? 1 : 0;", + " })", + " });", + "}", + "", + "===ES6===", + "", + "(() => {", + "", + " // idMatrix :: Int -> [[0 | 1]]", + " const idMatrix = n => Array.from({", + " length: n", + " }, (_, i) => Array.from({", + " length: n", + " }, (_, j) => i !== j ? 0 : 1));", + "", + " // show :: a -> String", + " const show = JSON.stringify;", + "", + " // TEST", + " return idMatrix(5)", + " .map(show)", + " .join('\\n');", + "})();", + "", + "{{Out}}", + "
[1,0,0,0,0]",
+      "[0,1,0,0,0]",
+      "[0,0,1,0,0]",
+      "[0,0,0,1,0]",
+      "[0,0,0,0,1]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eb1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function idMatrix(n) {\n return Array.apply(null, new Array(n))\n .map(function (x, i, xs) {\n return xs.map(function (_, k) {\n return i === k ? 1 : 0;\n })\n });\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Iterated digits squaring", + "type": "Waypoint", + "description": [ + "

If you add the square of the digits of a Natural number (an integer bigger than zero), you always end with either 1 or 89:

", + "
15 -> 26 -> 40 -> 16 -> 37 -> 58 -> 89",
+      "7 -> 49 -> 97 -> 130 -> 10 -> 1
", + "

An example in Python:

>>> step = lambda x: sum(int(d) ** 2 for d in str(x))

", + "

>>> iterate = lambda x: x if x in [1, 89] else iterate(step(x))

", + "

>>> [iterate(x) for x in xrange(1, 20)]

", + "

[1, 89, 89, 89, 89, 89, 1, 89, 89, 1, 89, 89, 1, 89, 89, 89, 89, 89, 1]

Task:", + "

Count how many number chains for integers 1 <= n < 100_000_000 end with a value 89.

", + "

Or, for much less credit - (showing that your algorithm and/or language is slow):

", + "

Count how many number chains for integers 1 <= n < 1_000_000 end with a value 89.

This problem derives from the Project Euler problem 92.

For a quick algorithm for this task see the talk page

Cf:", + "Combinations with repetitions", + "Digital root", + "Digital root/Multiplicative digital root" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ec1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Jaro distance", + "type": "Waypoint", + "description": [ + "

The Jaro distance is a measure of similarity between two strings.

The higher the Jaro distance for two strings is, the more similar the strings are.

The score is normalized such that 0 equates to no similarity and 1 is an exact match.

", + ";Definition

The Jaro distance $d_j$ of two given strings $s_1$ and $s_2$ is

$d_j = \\left\\{

\\begin{array}{l l}

", + "

0 & \\text{if }m = 0\\\\

", + "

\\frac{1}{3}\\left(\\frac{m}{|s_1|} + \\frac{m}{|s_2|} + \\frac{m-t}{m}\\right) & \\text{otherwise} \\end{array} \\right.$

Where:

$m$ is the number of matching characters;", + "$t$ is half the number of transpositions.

Two characters from $s_1$ and $s_2$ respectively, are considered matching only if they are the same and not farther than $\\left\\lfloor\\frac{\\max(|s_1|,|s_2|)}{2}\\right\\rfloor-1$.

Each character of $s_1$ is compared with all its matching

", + "

characters in $s_2$.

The number of matching (but different sequence order) characters

", + "

divided by 2 defines the number of transpositions.

", + ";Example

Given the strings $s_1$ DWAYNE and $s_2$ DUANE we find:

$m = 4$", + "$|s_1| = 6$", + "$|s_2| = 5$", + "$t = 0$

We find a Jaro score of:

$d_j = \\frac{1}{3}\\left(\\frac{4}{6} + \\frac{4}{5} + \\frac{4-0}{4}\\right) = 0.822$

", + "Task

Implement the Jaro-distance algorithm and show the distances for each of the following pairs:

(\"MARTHA\", \"MARHTA\")", + "(\"DIXON\", \"DICKSONX\")", + "(\"JELLYFISH\", \"SMELLYFISH\") See also", + "Jaro–Winkler distance on Wikipedia." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ec2", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "JortSort", + "type": "Waypoint", + "description": [ + "

jortSort is a sorting toolset that makes the user do the work and guarantees efficiency because you don't have to sort ever again. It was originally presented by Jenn \"Moneydollars\" Schiffer at the prestigious JSConf.

jortSort is a function that takes a single array of comparable objects as its argument. It then sorts the array in ascending order and compares the sorted array to the originally provided array. If the arrays match (i.e. the original array was already sorted), the function returns true. If the arrays do not match (i.e. the original array was not sorted), the function returns false.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "The original JavaScript implementation courtesy of the author, [https://github.com/jennschiffer/jortsort Jenn \"Moneydollars\" Schiffer].", + "var jortSort = function( array ) {", + "", + " // sort the array", + " var originalArray = array.slice(0);", + " array.sort( function(a,b){return a - b} );", + "", + " // compare to see if it was originally sorted", + " for (var i = 0; i < originalArray.length; ++i) {", + " if (originalArray[i] !== array[i]) return false;", + " }", + "", + " return true;", + "};", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ec4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var jortSort = function( array ) {\n\n // sort the array\n var originalArray = array.slice(0);\n array.sort( function(a,b){return a - b} );\n\n // compare to see if it was originally sorted\n for (var i = 0; i < originalArray.length; ++i) {\n if (originalArray[i] !== array[i]) return false;\n }\n\n return true;\n};\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Josephus problem", + "type": "Waypoint", + "description": [ + "

Josephus problem is a math puzzle with a grim description: $n$ prisoners are standing on a circle, sequentially numbered from $0$ to $n-1$.

An executioner walks along the circle, starting from prisoner $0$,

", + "

removing every $k$-th prisoner and killing him.

As the process goes on, the circle becomes smaller and smaller, until only one prisoner remains, who is then freed. >

For example, if there are $n=5$ prisoners and $k=2$, the order the prisoners are killed in (let's call it the \"killing sequence\") will be 1, 3, 0, and 4, and the survivor will be #2.

", + "Task:", + "

Given any $n, k > 0$, find out which prisoner will be the final survivor.

In one such incident, there were 41 prisoners and every 3rd prisoner was being killed ($k=3$).

Among them was a clever chap name Josephus who worked out the problem, stood at the surviving position, and lived on to tell the tale.

Which number was he?

", + "Extra:", + "

The captors may be especially kind and let $m$ survivors free,

", + "and Josephus might just have $m-1$ friends to save.

Provide a way to calculate which prisoner is at any given position on the killing sequence.

", + "Notes:", + "You can always play the executioner and follow the procedure exactly as described, walking around the circle, counting (and cutting off) heads along the way. This would yield the complete killing sequence and answer the above questions, with a complexity of probably $O(kn)$. However, individually it takes no more than $O(m)$ to find out which prisoner is the $m$-th to die.", + "If it's more convenient, you can number prisoners from $1$ to $n$ instead. If you choose to do so, please state it clearly.", + "An alternative description has the people committing assisted suicide instead of being executed, and the last person simply walks away. These details are not relevant, at least not mathematically." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Labels are 1-based, executioner's solution:", + "var Josephus = {", + " init: function(n) {", + " this.head = {};", + " var current = this.head;", + " for (var i = 0; i < n-1; i++) {", + " current.label = i+1;", + " current.next = {prev: current};", + " current = current.next;", + " }", + " current.label = n;", + " current.next = this.head;", + " this.head.prev = current;", + " return this;", + " },", + " kill: function(spacing) {", + " var current = this.head;", + " while (current.next !== current) {", + " for (var i = 0; i < spacing-1; i++) {", + " current = current.next;", + " }", + " current.prev.next = current.next;", + " current.next.prev = current.prev;", + " current = current.next;", + " }", + " return current.label;", + " }", + "}", + "{{out}}", + "
",
+      "> Josephus.init(30).kill(2)",
+      "29",
+      "
", + "", + "With Array methods:", + "function Josephus(n, k, s) {", + "\ts = s | 1", + "\tfor (var ps=[], i=n; i--; ) ps[i]=i", + "\tfor (var ks=[], i=--k; ps.length>s; i=(i+k)%ps.length) ks.push(ps.splice(i, 1))", + "\tdocument.write((arguments.callee+'').split(/\\s|\\(/)[1], '(', [].slice.call(arguments, 0), ') -> ', ps, ' / ', ks.length<45?ks:ks.slice(0,45)+',...' , '
')", + "\treturn [ps, ks]", + "}
", + "{{out}}", + "
",
+      "Josephus(5,1) -> 2 / 1,3,0,4",
+      "Josephus(41,2) -> 30 / 2,5,8,11,14,17,20,23,26,29,32,35,38,0,4,9,13,18,22,27,31,36,40,6,12,19,25,33,39,7,16,28,37,10,24,1,21,3,34,15",
+      "Josephus(23482,3342,3) -> 1087,1335,13317 / 3342,6685,10028,13371,16714,20057,23400,3261,6605,9949,13293,16637,19981,23325,3187,6532,9877,13222,16567,19912,23257,3120,6466,9812,13158,16504,19850,23196,3060,6407,9754,13101,16448,19795,23142,3007,6355,9703,13051,16399,19747,23095,2961,6310,9659,...",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ec5", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var Josephus = {\n init: function(n) {\n this.head = {};\n var current = this.head;\n for (var i = 0; i < n-1; i++) {\n current.label = i+1;\n current.next = {prev: current};\n current = current.next;\n }\n current.label = n;\n current.next = this.head;\n this.head.prev = current;\n return this;\n },\n kill: function(spacing) {\n var current = this.head;\n while (current.next !== current) {\n for (var i = 0; i < spacing-1; i++) {\n current = current.next;\n }\n current.prev.next = current.next;\n current.next.prev = current.prev;\n current = current.next;\n }\n return current.label;\n }\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Kaprekar numbers", + "type": "Waypoint", + "description": [ + "

A positive integer is a Kaprekar number if:

", + "It is 1", + "The decimal representation of its square may be split once into two parts consisting of positive integers which sum to the original number. Note that a split resulting in a part consisting purely of 0s is not valid, ", + "

as 0 is not considered positive.

Example Kaprekar numbers:", + "$2223$ is a Kaprekar number, as $2223 * 2223 = 4941729$, $4941729$ may be split to $494$ and $1729$, and $494 + 1729 = 2223$.", + "The series of Kaprekar numbers is known as A006886, and begins as $1, 9, 45, 55, ...$.", + "Example process:", + "

10000 (1002) splitting from left to right:

", + "The first split is [1, 0000], and is invalid; the 0000 element consists entirely of 0s, and 0 is not considered positive.", + "Slight optimization opportunity: When splitting from left to right, once the right part consists entirely of 0s, no further testing is needed; all further splits would also be invalid.", + "Task description:", + "

Generate and show all Kaprekar numbers less than 10,000.

Extra credit:", + "

Optionally, count (and report the count of) how many Kaprekar numbers are less than 1,000,000.

Extra extra credit:", + "

The concept of Kaprekar numbers is not limited to base 10 (i.e. decimal numbers);

", + "

if you can, show that Kaprekar numbers exist in other bases too.

For this purpose, do the following:

", + "Find all Kaprekar numbers for base 17 between 1 and 1,000,000 (one million);", + "Display each of them in base 10 representation;", + "Optionally, using base 17 representation (use letters 'a' to 'g' for digits 10(10) to 16(10)), display each of the numbers, its square, and where to split the square. ", + "For example, 225(10) is \"d4\" in base 17, its square \"a52g\", and a5(17) + 2g(17) = d4(17), so the display would be something like:
225   d4  a52g  a5 + 2g
Reference:", + "The Kaprekar Numbers by Douglas E. Iannucci (2000). PDF version" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "'''This string version'''", + "function isKaprekar( n, bs ) {", + "\tif ( n < 1 ) return false", + "\tif ( n == 1 ) return true", + "\tbs = bs || 10", + "\tvar s = (n * n).toString(bs)", + "\tfor (var i=1, e=s.length; i", + "'''or this numeric version'''", + "function isKaprekar( n, bs ) {", + "\tif ( n < 1 ) return false", + "\tif ( n == 1 ) return true", + "\tbs = bs || 10", + "\tfor (var a=n*n, b=0, s=1; a; s*=bs) {", + "\t\tb += a%bs*s", + "\t\ta = Math.floor(a/bs)", + "\t\tif (b && a + b == n) return true", + "\t}", + "\treturn false", + "}", + "'''with'''", + "function kaprekar( s, e, bs, pbs ) {", + "\tbs = bs || 10; pbs = pbs || 10", + "\tconst toString = n => n.toString(pbs).toUpperCase()", + "\tdocument.write('start:',toString(s), ' end:',toString(e), ' base:',bs, ' printBase:',pbs, '
' )", + "\tfor (var k=0, n=s; n<=e; n+=1) if (isKaprekar(n, bs)) k+=1, document.write(toString(n), ' ') ", + "\tdocument.write('
found ', k, ' numbers

')", + "}", + "", + "kaprekar( 1, 99 )", + "kaprekar( 1, 255, 16)", + "kaprekar( 1, 255, 16, 16)", + "kaprekar( 1, 288, 17, 17)
", + "{{out}}", + "
",
+      "start:1 end:99 base:10 printBase:10",
+      "1 9 45 55 99",
+      "found 5 numbers",
+      "",
+      "start:1 end:255 base:16 printBase:10",
+      "1 6 10 15 51 85 91 120 136 171 205 255",
+      "found 12 numbers",
+      "",
+      "start:1 end:FF base:16 printBase:16",
+      "1 6 A F 33 55 5B 78 88 AB CD FF",
+      "found 12 numbers",
+      "",
+      "start:1 end:GG base:17 printBase:17",
+      "1 G 3D D4 GG",
+      "found 5 numbers",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eca", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function isKaprekar( n, bs ) {\n\tif ( n < 1 ) return false\n\tif ( n == 1 ) return true\n\tbs = bs || 10\n\tvar s = (n * n).toString(bs)\n\tfor (var i=1, e=s.length; ireplaceMe is a function.');" + ] + }, + { + "title": "K-d tree", + "type": "Waypoint", + "description": [ + "

A k-d tree (short for k-dimensional tree) is a space-partitioning data structure for organizing points in a k-dimensional space. k-d trees are a useful data structure for several applications, such as searches involving a multidimensional search key (e.g. range searches and nearest neighbor searches).

", + "

k-d trees are a special case of binary space partitioning trees.

k-d trees are not suitable, however, for efficiently finding the nearest neighbor in high dimensional spaces. As a general rule, if the dimensionality is k, the number of points in the data, N, should be N ≫ 2k.

", + "

Otherwise, when k-d trees are used with high-dimensional data, most of the points in the tree will be evaluated and the efficiency is no better than exhaustive search, and other methods such as approximate nearest-neighbor are used instead.

Task: Construct a k-d tree and perform a nearest neighbor search for two example data sets:

The Wikipedia example data of [(2,3), (5,4), (9,6), (4,7), (8,1), (7,2)].", + "1000 3-d points uniformly distributed in a 3-d cube.", + "

For the Wikipedia example, find the nearest neighbor to point (9, 2)

", + "

For the random data, pick a random location and find the nearest neighbor.

In addition, instrument your code to count the number of nodes visited in the nearest neighbor search. Count a node as visited if any field of it is accessed.

Output should show the point searched for, the point found,

", + "

the distance to the point, and the number of nodes visited.

There are variant algorithms for constructing the tree.

", + "

You can use a simple median strategy or implement something more efficient.

", + "

Variants of the nearest neighbor search include nearest N neighbors, approximate nearest neighbor, and range searches.

", + "

You do not have to implement these.

", + "

The requirement for this task is specifically the nearest single neighbor.

", + "

Also there are algorithms for inserting, deleting, and balancing k-d trees.

", + "

These are also not required for the task.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ecb", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Knapsack problem/0-1", + "type": "Waypoint", + "description": [ + "

A tourist wants to make a good trip at the weekend with his friends.

They will go to the mountains to see the wonders of nature, so he needs to pack well for the trip.

He has a good knapsack for carrying things, but knows that he can carry a maximum of only 4kg in it, and it will have to last the whole day.

He creates a list of what he wants to bring for the trip but the total weight of all items is too much.

He then decides to add columns to his initial list detailing their weights and a numerical value representing how important the item is for the trip.

", + "

Here is the list:

", + "

{| style=\"text-align: left; width: 80%;\" border=\"4\" cellpadding=\"2\" cellspacing=\"2\"

", + "

|+ Table of potential knapsack items

", + "

|- style=\"background-color: rgb(255, 204, 255);\"

", + "

! item !! weight (dag) !! value

", + "

|-

", + "

| map || 9 || 150

", + "

|-

", + "

| compass || 13 || 35

", + "

|-

", + "

| water || 153 || 200

", + "

|-

", + "

| sandwich || 50 || 160

", + "

|-

", + "

| glucose || 15 || 60

", + "

|-

", + "

| tin || 68 || 45

", + "

|-

", + "

| banana || 27 || 60

", + "

|-

", + "

| apple || 39 || 40

", + "

|-

", + "

| cheese || 23 || 30

", + "

|-

", + "

| beer || 52 || 10

", + "

|-

", + "

| suntan cream || 11 || 70

", + "

|-

", + "

| camera || 32 || 30

", + "

|-

", + "

| T-shirt || 24 || 15

", + "

|-

", + "

| trousers || 48 || 10

", + "

|-

", + "

| umbrella || 73 || 40

", + "

|-

", + "

| waterproof trousers || 42 || 70

", + "

|-

", + "

| waterproof overclothes || 43 || 75

", + "

|-

", + "

| note-case || 22 || 80

", + "

|-

", + "

| sunglasses || 7 || 20

", + "

|-

", + "

| towel || 18 || 12

", + "

|-

", + "

| socks || 4 || 50

", + "

|-

", + "

| book || 30 || 10

", + "

|- style=\"background-color: rgb(255, 204, 255);\"

", + "

| knapsack || ≤400 dag || ?

", + "

|}

", + "

The tourist can choose to take any combination of items from the list,

", + "

but only one of each item is available.

He may not cut or diminish the items, so he can only take whole units of any item.

", + "Task:", + "

Show which items the tourist can carry in his knapsack so that their total weight does not

", + "

exceed 400 dag [4 kg], and their total value is maximized.

[dag = decagram = 10 grams]

", + "Related tasks:", + " Knapsack problem/Bounded", + " Knapsack problem/Unbounded", + " Knapsack problem/Continuous" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Also available at [https://gist.github.com/truher/4715551|this gist].", + "/*global portviz:false, _:false */", + "/*", + " * 0-1 knapsack solution, recursive, memoized, approximate.", + " *", + " * credits:", + " *", + " * the Go implementation here:", + " * http://rosettacode.org/mw/index.php?title=Knapsack_problem/0-1", + " *", + " * approximation details here:", + " * http://math.mit.edu/~goemans/18434S06/knapsack-katherine.pdf", + " */", + "portviz.knapsack = {};", + "(function() {", + " this.combiner = function(items, weightfn, valuefn) {", + " // approximation guarantees result >= (1-e) * optimal", + " var _epsilon = 0.01;", + " var _p = _.max(_.map(items,valuefn));", + " var _k = _epsilon * _p / items.length;", + " ", + " var _memo = (function(){", + " var _mem = {};", + " var _key = function(i, w) {", + " return i + '::' + w;", + " };", + " return {", + " get: function(i, w) {", + " return _mem[_key(i,w)];", + " },", + " put: function(i, w, r) {", + " _mem[_key(i,w)]=r;", + " return r;", + " }", + " };", + " })();", + " ", + " var _m = function(i, w) {", + " ", + " i = Math.round(i);", + " w = Math.round(w);", + " ", + " ", + " if (i < 0 || w === 0) {", + " // empty base case", + " return {items: [], totalWeight: 0, totalValue: 0};", + " }", + " ", + " var mm = _memo.get(i,w);", + " if (!_.isUndefined(mm)) {", + " return mm;", + " }", + " ", + " var item = items[i];", + " if (weightfn(item) > w) {", + " //item does not fit, try the next item", + " return _memo.put(i, w, _m(i-1, w));", + " }", + " // this item could fit.", + " // are we better off excluding it?", + " var excluded = _m(i-1, w);", + " // or including it?", + " var included = _m(i-1, w - weightfn(item));", + " if (included.totalValue + Math.floor(valuefn(item)/_k) > excluded.totalValue) {", + " // better off including it", + " // make a copy of the list", + " var i1 = included.items.slice();", + " i1.push(item);", + " return _memo.put(i, w,", + " {items: i1,", + " totalWeight: included.totalWeight + weightfn(item),", + " totalValue: included.totalValue + Math.floor(valuefn(item)/_k)});", + " }", + " //better off excluding it", + " return _memo.put(i,w, excluded);", + " };", + " return {", + " /* one point */", + " one: function(maxweight) {", + " var scaled = _m(items.length - 1, maxweight);", + " return {", + " items: scaled.items,", + " totalWeight: scaled.totalWeight,", + " totalValue: scaled.totalValue * _k", + " };", + " },", + " /* the entire EF */", + " ef: function(maxweight, step) {", + " return _.map(_.range(0, maxweight+1, step), function(weight) {", + " var scaled = _m(items.length - 1, weight);", + " return {", + " items: scaled.items,", + " totalWeight: scaled.totalWeight,", + " totalValue: scaled.totalValue * _k", + " };", + " });", + " }", + " };", + " };", + "}).apply(portviz.knapsack);", + "", + "/*global portviz:false, _:false */", + "/*", + " * after rosettacode.org/mw/index.php?title=Knapsack_problem/0-1", + " */", + "var allwants = [", + " {name:\"map\", weight:9, value: 150},", + " {name:\"compass\", weight:13, value: 35},", + " {name:\"water\", weight:153, value: 200},", + " {name:\"sandwich\", weight: 50, value: 160},", + " {name:\"glucose\", weight:15, value: 60},", + " {name:\"tin\", weight:68, value: 45},", + " {name:\"banana\", weight:27, value: 60},", + " {name:\"apple\", weight:39, value: 40},", + " {name:\"cheese\", weight:23, value: 30},", + " {name:\"beer\", weight:52, value: 10},", + " {name:\"suntan cream\", weight:11, value: 70},", + " {name:\"camera\", weight:32, value: 30},", + " {name:\"T-shirt\", weight:24, value: 15},", + " {name:\"trousers\", weight:48, value: 10},", + " {name:\"umbrella\", weight:73, value: 40},", + " {name:\"waterproof trousers\", weight:42, value: 70},", + " {name:\"waterproof overclothes\", weight:43, value: 75},", + " {name:\"note-case\", weight:22, value: 80},", + " {name:\"sunglasses\", weight:7, value: 20},", + " {name:\"towel\", weight:18, value: 12},", + " {name:\"socks\", weight:4, value: 50},", + " {name:\"book\", weight:30, value: 10}", + "];", + " ", + "var near = function(actual, expected, tolerance) {", + " if (expected === 0 && actual === 0) return true;", + " if (expected === 0) {", + " return Math.abs(expected - actual) / actual < tolerance;", + " }", + " return Math.abs(expected - actual) / expected < tolerance;", + "};", + " ", + "test(\"one knapsack\", function() {", + " var combiner =", + " portviz.knapsack.combiner(allwants,", + " function(x){return x.weight;},", + " function(x){return x.value;});", + " var oneport = combiner.one(400);", + " ok(near(oneport.totalValue, 1030, 0.01), \"correct total value\");", + " ok(near(oneport.totalValue, 1030, 0.01), \"correct total value\");", + " equal(oneport.totalWeight, 396, \"correct total weight\");", + "});", + " ", + "test(\"frontier\", function() {", + " var combiner =", + " portviz.knapsack.combiner(allwants,", + " function(x){return x.weight;},", + " function(x){return x.value;});", + " var ef = combiner.ef(400, 1);", + " equal(ef.length, 401, \"401 because it includes the endpoints\");", + " ef = combiner.ef(400, 40);", + " equal(ef.length, 11, \"11 because it includes the endpoints\");", + " var expectedTotalValue = [", + " 0,", + " 330,", + " 445,", + " 590,", + " 685,", + " 755,", + " 810,", + " 860,", + " 902,", + " 960,", + " 1030", + " ] ;", + " _.each(ef, function(element, index) {", + " // 15% error! bleah!", + " ok(near(element.totalValue, expectedTotalValue[index], 0.15),", + " 'actual ' + element.totalValue + ' expected ' + expectedTotalValue[index]);", + " });", + " deepEqual(_.pluck(ef, 'totalWeight'), [", + " 0,", + " 39,", + " 74,", + " 118,", + " 158,", + " 200,", + " 236,", + " 266,", + " 316,", + " 354,", + " 396", + " ]);", + " deepEqual(_.map(ef, function(x){return x.items.length;}), [", + " 0,", + " 4,", + " 6,", + " 7,", + " 9,", + " 10,", + " 10,", + " 12,", + " 14,", + " 11,", + " 12", + " ]);", + "});", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ed1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "/*global portviz:false, _:false */\n/*\n * 0-1 knapsack solution, recursive, memoized, approximate.\n *\n * credits:\n *\n * the Go implementation here:\n * http://rosettacode.org/mw/index.php?title=Knapsack_problem/0-1\n *\n * approximation details here:\n * http://math.mit.edu/~goemans/18434S06/knapsack-katherine.pdf\n */\nportviz.knapsack = {};\n(function() {\n this.combiner = function(items, weightfn, valuefn) {\n // approximation guarantees result >= (1-e) * optimal\n var _epsilon = 0.01;\n var _p = _.max(_.map(items,valuefn));\n var _k = _epsilon * _p / items.length;\n \n var _memo = (function(){\n var _mem = {};\n var _key = function(i, w) {\n return i + '::' + w;\n };\n return {\n get: function(i, w) {\n return _mem[_key(i,w)];\n },\n put: function(i, w, r) {\n _mem[_key(i,w)]=r;\n return r;\n }\n };\n })();\n \n var _m = function(i, w) {\n \n i = Math.round(i);\n w = Math.round(w);\n \n \n if (i < 0 || w === 0) {\n // empty base case\n return {items: [], totalWeight: 0, totalValue: 0};\n }\n \n var mm = _memo.get(i,w);\n if (!_.isUndefined(mm)) {\n return mm;\n }\n \n var item = items[i];\n if (weightfn(item) > w) {\n //item does not fit, try the next item\n return _memo.put(i, w, _m(i-1, w));\n }\n // this item could fit.\n // are we better off excluding it?\n var excluded = _m(i-1, w);\n // or including it?\n var included = _m(i-1, w - weightfn(item));\n if (included.totalValue + Math.floor(valuefn(item)/_k) > excluded.totalValue) {\n // better off including it\n // make a copy of the list\n var i1 = included.items.slice();\n i1.push(item);\n return _memo.put(i, w,\n {items: i1,\n totalWeight: included.totalWeight + weightfn(item),\n totalValue: included.totalValue + Math.floor(valuefn(item)/_k)});\n }\n //better off excluding it\n return _memo.put(i,w, excluded);\n };\n return {\n /* one point */\n one: function(maxweight) {\n var scaled = _m(items.length - 1, maxweight);\n return {\n items: scaled.items,\n totalWeight: scaled.totalWeight,\n totalValue: scaled.totalValue * _k\n };\n },\n /* the entire EF */\n ef: function(maxweight, step) {\n return _.map(_.range(0, maxweight+1, step), function(weight) {\n var scaled = _m(items.length - 1, weight);\n return {\n items: scaled.items,\n totalWeight: scaled.totalWeight,\n totalValue: scaled.totalValue * _k\n };\n });\n }\n };\n };\n}).apply(portviz.knapsack);\n\n/*global portviz:false, _:false */\n/*\n * after rosettacode.org/mw/index.php?title=Knapsack_problem/0-1\n */\nvar allwants = [\n {name:\"map\", weight:9, value: 150},\n {name:\"compass\", weight:13, value: 35},\n {name:\"water\", weight:153, value: 200},\n {name:\"sandwich\", weight: 50, value: 160},\n {name:\"glucose\", weight:15, value: 60},\n {name:\"tin\", weight:68, value: 45},\n {name:\"banana\", weight:27, value: 60},\n {name:\"apple\", weight:39, value: 40},\n {name:\"cheese\", weight:23, value: 30},\n {name:\"beer\", weight:52, value: 10},\n {name:\"suntan cream\", weight:11, value: 70},\n {name:\"camera\", weight:32, value: 30},\n {name:\"T-shirt\", weight:24, value: 15},\n {name:\"trousers\", weight:48, value: 10},\n {name:\"umbrella\", weight:73, value: 40},\n {name:\"waterproof trousers\", weight:42, value: 70},\n {name:\"waterproof overclothes\", weight:43, value: 75},\n {name:\"note-case\", weight:22, value: 80},\n {name:\"sunglasses\", weight:7, value: 20},\n {name:\"towel\", weight:18, value: 12},\n {name:\"socks\", weight:4, value: 50},\n {name:\"book\", weight:30, value: 10}\n];\n \nvar near = function(actual, expected, tolerance) {\n if (expected === 0 && actual === 0) return true;\n if (expected === 0) {\n return Math.abs(expected - actual) / actual < tolerance;\n }\n return Math.abs(expected - actual) / expected < tolerance;\n};\n \ntest(\"one knapsack\", function() {\n var combiner =\n portviz.knapsack.combiner(allwants,\n function(x){return x.weight;},\n function(x){return x.value;});\n var oneport = combiner.one(400);\n ok(near(oneport.totalValue, 1030, 0.01), \"correct total value\");\n ok(near(oneport.totalValue, 1030, 0.01), \"correct total value\");\n equal(oneport.totalWeight, 396, \"correct total weight\");\n});\n \ntest(\"frontier\", function() {\n var combiner =\n portviz.knapsack.combiner(allwants,\n function(x){return x.weight;},\n function(x){return x.value;});\n var ef = combiner.ef(400, 1);\n equal(ef.length, 401, \"401 because it includes the endpoints\");\n ef = combiner.ef(400, 40);\n equal(ef.length, 11, \"11 because it includes the endpoints\");\n var expectedTotalValue = [\n 0,\n 330,\n 445,\n 590,\n 685,\n 755,\n 810,\n 860,\n 902,\n 960,\n 1030\n ] ;\n _.each(ef, function(element, index) {\n // 15% error! bleah!\n ok(near(element.totalValue, expectedTotalValue[index], 0.15),\n 'actual ' + element.totalValue + ' expected ' + expectedTotalValue[index]);\n });\n deepEqual(_.pluck(ef, 'totalWeight'), [\n 0,\n 39,\n 74,\n 118,\n 158,\n 200,\n 236,\n 266,\n 316,\n 354,\n 396\n ]);\n deepEqual(_.map(ef, function(x){return x.items.length;}), [\n 0,\n 4,\n 6,\n 7,\n 9,\n 10,\n 10,\n 12,\n 14,\n 11,\n 12\n ]);\n});\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Knapsack problem/Bounded", + "type": "Waypoint", + "description": [ + "

A tourist wants to make a good trip at the weekend with his friends.

They will go to the mountains to see the wonders of nature. So he needs some items during the trip. Food, clothing, etc. He has a good knapsack for carrying the things, but he knows that he can carry only 4 kg weight in his knapsack, because they will make the trip from morning to evening.

He creates a list of what he wants to bring for the trip, but the total weight of all items is too much. He adds a value to each item. The value represents how important the thing for the tourist.

The list contains which items are the wanted things for the trip, what is the weight and value of an item, and how many units does he have from each items.

", + "

This is the list:

", + "

{| style=\"text-align: left; width: 80%;\" border=\"4\" cellpadding=\"2\" cellspacing=\"2\"

", + "

|+ Table of potential knapsack items

", + "

|- style=\"background-color: rgb(255, 204, 255);\"

", + "

! item !! weight (dag) (each) !! value (each) !! piece(s)

", + "

|-

", + "

| map || 9 || 150 || 1

", + "

|-

", + "

| compass || 13 || 35 || 1

", + "

|-

", + "

| water || 153 || 200 || 2

", + "

|-

", + "

| sandwich || 50 || 60 || 2

", + "

|-

", + "

| glucose || 15 || 60 || 2

", + "

|-

", + "

| tin || 68 || 45 || 3

", + "

|-

", + "

| banana || 27 || 60 || 3

", + "

|-

", + "

| apple || 39 || 40 || 3

", + "

|-

", + "

| cheese || 23 || 30 || 1

", + "

|-

", + "

| beer || 52 || 10 || 3

", + "

|-

", + "

| suntan cream || 11 || 70 || 1

", + "

|-

", + "

| camera || 32 || 30 || 1

", + "

|-

", + "

| T-shirt || 24 || 15 || 2

", + "

|-

", + "

| trousers || 48 || 10 || 2

", + "

|-

", + "

| umbrella || 73 || 40 || 1

", + "

|-

", + "

| waterproof trousers || 42 || 70 || 1

", + "

|-

", + "

| waterproof overclothes || 43 || 75 || 1

", + "

|-

", + "

| note-case || 22 || 80 || 1

", + "

|-

", + "

| sunglasses || 7 || 20 || 1

", + "

|-

", + "

| towel || 18 || 12 || 2

", + "

|-

", + "

| socks || 4 || 50 || 1

", + "

|-

", + "

| book || 30 || 10 || 2

", + "

|- style=\"background-color: rgb(255, 204, 255);\"

", + "

| knapsack || ≤400 dag || ? || ?

", + "

|}

", + "

The tourist can choose to take any combination of items from the list, and some number of each item is available (see the column piece(s) in the list above).

He may not cut the items, so he can only take whole units of any item.

", + "Task:", + "

Show which items does the tourist carry in his knapsack so that their total weight does not exceed 4 kg, and their total value is maximized.

", + "Related tasks:", + " Knapsack problem/Unbounded", + " Knapsack problem/Continuous", + " Knapsack problem/0-1" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Based on the (dynamic) J implementation. Expressed as an htm page:", + "", + "", + "", + "This will generate (translating html to mediawiki markup):", + "{|", + "|'''Count'''", + "|'''Item'''", + "!unit weight", + "!unit value", + "|-", + "|1", + "|map", + "|9", + "|150", + "|-", + "|1", + "|compass", + "|13", + "|35", + "|-", + "|1", + "|water", + "|153", + "|200", + "|-", + "|2", + "|glucose", + "|15", + "|60", + "|-", + "|3", + "|banana", + "|27", + "|60", + "|-", + "|1", + "|cheese", + "|23", + "|30", + "|-", + "|1", + "|suntan, cream", + "|11", + "|70", + "|-", + "|1", + "|waterproof, overclothes", + "|43", + "|75", + "|-", + "|1", + "|note-case", + "|22", + "|80", + "|-", + "|1", + "|sunglasses", + "|7", + "|20", + "|-", + "|1", + "|socks", + "|4", + "|50", + "|}", + "Total weight: 396
", + "Total value: 1010", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ed2", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Knapsack problem/Continuous", + "type": "Waypoint", + "description": [ + "

A thief burgles a butcher's shop, where he can select from some items.

The thief knows the weights and prices of each items. Because he has a knapsack with 15 kg maximal capacity, he wants to select the items such that he would have his profit maximized. He may cut the items; the item has a reduced price after cutting that is proportional to the original price by the ratio of masses. That means: half of an item has half the price of the original.

", + "

This is the item list in the butcher's shop:

{| style=\"text-align: left; width: 50%;\" border=\"4\" cellpadding=\"2\" cellspacing=\"2\"

", + "

|+ Table of potential knapsack items

", + "

|- style=\"background-color: rgb(255, 204, 255);\"

", + "

! Item !! Weight (kg) !! Price (Value)

", + "

|-

", + "

| beef || 3.8 || 36

", + "

|-

", + "

| pork || 5.4 || 43

", + "

|-

", + "

| ham || 3.6 || 90

", + "

|-

", + "

| greaves || 2.4 || 45

", + "

|-

", + "

| flitch || 4.0 || 30

", + "

|-

", + "

| brawn || 2.5 || 56

", + "

|-

", + "

| welt || 3.7 || 67

", + "

|-

", + "

| salami || 3.0 || 95

", + "

|-

", + "

| sausage || 5.9 || 98

", + "

|- style=\"background-color: rgb(255, 204, 255);\"

", + "

| Knapsack || <=15 kg || ?

", + "

|}

", + "Task:", + "

Show which items the thief carries in his knapsack so that their total weight does not exceed 15 kg, and their total value is maximized.

", + "Related tasks:", + " Knapsack problem/Bounded", + " Knapsack problem/Unbounded", + " Knapsack problem/0-1", + "See also:", + " Wikipedia article: continuous knapsack." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ed3", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Knapsack problem/Unbounded", + "type": "Waypoint", + "description": [ + "

A traveler gets diverted and has to make an unscheduled stop in what turns out to be Shangri La. Opting to leave, he is allowed to take as much as he likes of the following items, so long as it will fit in his knapsack, and he can carry it.

He knows that he can carry no more than 25 'weights' in total; and that the capacity of his knapsack is 0.25 'cubic lengths'.

Looking just above the bar codes on the items he finds their weights and volumes. He digs out his recent copy of a financial paper and gets the value of each item.

", + "

", + "

style=\"text-align: left; width: 80%;\" border=\"4\"

", + "

cellpadding=\"2\" cellspacing=\"2\">", + "

style=\"font-weight: bold;\" align=\"left\" nowrap=\"nowrap\"

", + "

valign=\"middle\">Item", + "

style=\"font-weight: bold;\" align=\"left\" nowrap=\"nowrap\"

", + "

valign=\"middle\">Explanation", + "

style=\"font-weight: bold;\" align=\"left\" nowrap=\"nowrap\"

", + "

valign=\"middle\">Value (each)", + "

style=\"font-weight: bold;\" align=\"left\" nowrap=\"nowrap\"

", + "

valign=\"middle\">weight", + "

style=\"font-weight: bold;\" align=\"left\" nowrap=\"nowrap\"

", + "

valign=\"middle\">Volume (each)", + "

align=\"left\" nowrap=\"nowrap\" valign=\"middle\">panacea

", + "

(vials of)", + "

valign=\"middle\">Incredible healing properties", + "

align=\"left\" nowrap=\"nowrap\" valign=\"middle\">3000", + "

align=\"left\" nowrap=\"nowrap\" valign=\"middle\">0.3", + "

align=\"left\" nowrap=\"nowrap\" valign=\"middle\">0.025", + "

align=\"left\" nowrap=\"nowrap\" valign=\"middle\">ichor

", + "

(ampules of)", + "

valign=\"middle\">Vampires blood", + "

nowrap=\"nowrap\" valign=\"middle\">1800", + "

align=\"left\" nowrap=\"nowrap\" valign=\"middle\">0.2", + "

align=\"left\" nowrap=\"nowrap\" valign=\"middle\">0.015", + "

align=\"left\" nowrap=\"nowrap\" valign=\"middle\">gold

", + "

(bars)", + "

valign=\"middle\">Shiney shiney", + "

nowrap=\"nowrap\" valign=\"middle\">2500", + "

align=\"left\" nowrap=\"nowrap\" valign=\"middle\">2.0", + "

align=\"left\" nowrap=\"nowrap\" valign=\"middle\">0.002", + "

style=\"background-color: rgb(255, 204, 255);\" align=\"left\"

", + "

nowrap=\"nowrap\" valign=\"middle\">Knapsack", + "

style=\"background-color: rgb(255, 204, 255);\" align=\"left\"

", + "

nowrap=\"nowrap\" valign=\"middle\">For the carrying of", + "

style=\"background-color: rgb(255, 204, 255);\" align=\"left\"

", + "

nowrap=\"nowrap\" valign=\"middle\">-", + "

style=\"background-color: rgb(255, 204, 255);\" align=\"left\"

", + "

nowrap=\"nowrap\" valign=\"middle\"><=25", + "

style=\"background-color: rgb(255, 204, 255);\" align=\"left\"

", + "

nowrap=\"nowrap\" valign=\"middle\"><=0.25

", + "", + "

He can only take whole units of any item, but there is much more of any item than he could ever carry

", + "Task:", + "

Show how many of each item does he take to maximize the value of items he is carrying away with him.

", + "Note: ", + " There are four solutions that maximize the value taken. Only one need be given.

Related tasks:", + " Knapsack problem/Bounded", + " Knapsack problem/Continuous", + " Knapsack problem/0-1" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Brute force.", + "var gold = { 'value': 2500, 'weight': 2.0, 'volume': 0.002 },", + " panacea = { 'value': 3000, 'weight': 0.3, 'volume': 0.025 },", + " ichor = { 'value': 1800, 'weight': 0.2, 'volume': 0.015 },", + " ", + " items = [gold, panacea, ichor],", + " knapsack = {'weight': 25, 'volume': 0.25},", + " max_val = 0,", + " solutions = [],", + " g, p, i, item, val;", + " ", + "for (i = 0; i < items.length; i += 1) {", + " item = items[i];", + " item.max = Math.min(", + " Math.floor(knapsack.weight / item.weight),", + " Math.floor(knapsack.volume / item.volume)", + " );", + "}", + " ", + "for (g = 0; g <= gold.max; g += 1) {", + " for (p = 0; p <= panacea.max; p += 1) {", + " for (i = 0; i <= ichor.max; i += 1) {", + " if (i * ichor.weight + g * gold.weight + p * panacea.weight > knapsack.weight) {", + " continue;", + " }", + " if (i * ichor.volume + g * gold.volume + p * panacea.volume > knapsack.volume) {", + " continue;", + " }", + " val = i * ichor.value + g * gold.value + p * panacea.value;", + " if (val > max_val) {", + " solutions = [];", + " max_val = val;", + " }", + " if (val === max_val) {", + " solutions.push([g, p, i]);", + " }", + " }", + " }", + "}", + " ", + "document.write(\"maximum value: \" + max_val + '
');", + "for (i = 0; i < solutions.length; i += 1) {", + " item = solutions[i];", + " document.write(\"(gold: \" + item[0] + \", panacea: \" + item[1] + \", ichor: \" + item[2] + \")
\");", + "}", + "", + "output:", + "

maximum value: 54500",
+      "(gold: 11, panacea: 0, ichor: 15)",
+      "(gold: 11, panacea: 3, ichor: 10)",
+      "(gold: 11, panacea: 6, ichor: 5)",
+      "(gold: 11, panacea: 9, ichor: 0)
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ed4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var gold = { 'value': 2500, 'weight': 2.0, 'volume': 0.002 },\n panacea = { 'value': 3000, 'weight': 0.3, 'volume': 0.025 },\n ichor = { 'value': 1800, 'weight': 0.2, 'volume': 0.015 },\n \n items = [gold, panacea, ichor],\n knapsack = {'weight': 25, 'volume': 0.25},\n max_val = 0,\n solutions = [],\n g, p, i, item, val;\n \nfor (i = 0; i < items.length; i += 1) {\n item = items[i];\n item.max = Math.min(\n Math.floor(knapsack.weight / item.weight),\n Math.floor(knapsack.volume / item.volume)\n );\n}\n \nfor (g = 0; g <= gold.max; g += 1) {\n for (p = 0; p <= panacea.max; p += 1) {\n for (i = 0; i <= ichor.max; i += 1) {\n if (i * ichor.weight + g * gold.weight + p * panacea.weight > knapsack.weight) {\n continue;\n }\n if (i * ichor.volume + g * gold.volume + p * panacea.volume > knapsack.volume) {\n continue;\n }\n val = i * ichor.value + g * gold.value + p * panacea.value;\n if (val > max_val) {\n solutions = [];\n max_val = val;\n }\n if (val === max_val) {\n solutions.push([g, p, i]);\n }\n }\n }\n}\n \ndocument.write(\"maximum value: \" + max_val + '
');\nfor (i = 0; i < solutions.length; i += 1) {\n item = solutions[i];\n document.write(\"(gold: \" + item[0] + \", panacea: \" + item[1] + \", ichor: \" + item[2] + \")
\");\n}\n\noutput:\n
maximum value: 54500\n(gold: 11, panacea: 0, ichor: 15)\n(gold: 11, panacea: 3, ichor: 10)\n(gold: 11, panacea: 6, ichor: 5)\n(gold: 11, panacea: 9, ichor: 0)
\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Knight's tour", + "type": "Waypoint", + "description": [ + "Task", + "

Problem: you have a standard 8x8 chessboard, empty but for a single knight on some square. Your task is to emit a series of legal knight moves that result in the knight visiting every square on the chessboard exactly once. Note that it is not a requirement that the tour be \"closed\"; that is, the knight need not end within a single move of its start position.

Input and output may be textual or graphical, according to the conventions of the programming environment. If textual, squares should be indicated in algebraic notation. The output should indicate the order in which the knight visits the squares, starting with the initial position. The form of the output may be a diagram of the board with the squares numbered according to visitation sequence, or a textual list of algebraic coordinates in order, or even an actual animation of the knight moving around the chessboard.

Input: starting square

Output: move sequence

", + "Related tasks", + "A* search algorithm", + "N-queens problem", + "Solve a Hidato puzzle", + "Solve a Holy Knight's tour", + "Solve a Hopido puzzle", + "Solve a Numbrix puzzle", + "Solve the no connection puzzle" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ed5", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Knuth's algorithm S", + "type": "Waypoint", + "description": [ + "

This is a method of randomly sampling n items from a set of M items, with equal probability; where M >= n and M, the number of items is unknown until the end.

", + "

This means that the equal probability sampling should be maintained for all successive items > n as they become available (although the content of successive samples can change).

The algorithm:", + "Select the first n items as the sample as they become available;", + "For the i-th item where i > n, have a random chance of n/i of keeping it. If failing this chance, the sample remains the same. If not, have it randomly (1/n) replace one of the previously selected n items of the sample.", + "Repeat #2 for any subsequent items.", + "The Task:", + "Create a function s_of_n_creator that given $n$ the maximum sample size, returns a function s_of_n that takes one parameter, item.", + "Function s_of_n when called with successive items returns an equi-weighted random sample of up to n of its items so far, each time it is called, calculated using Knuths Algorithm S.", + "Test your functions by printing and showing the frequency of occurrences of the selected digits from 100,000 repetitions of:# Use the s_of_n_creator with n == 3 to generate an s_of_n.", + "

# call s_of_n with each of the digits 0 to 9 in order, keeping the returned three digits of its random sampling from its last call with argument item=9.

Note: A class taking n and generating a callable instance/function might also be used.

Reference:", + "The Art of Computer Programming, Vol 2, 3.4.2 p.142", + "Cf.", + "One of n lines in a file ", + "Accumulator factory" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ed6", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Knuth shuffle", + "type": "Waypoint", + "description": [ + "

The Knuth shuffle (a.k.a. the Fisher-Yates shuffle) is an algorithm for randomly shuffling the elements of an array.

", + "

Implement the Knuth shuffle for an integer array (or, if possible, an array of any type).

", + "

Given an array items with indices ranging from 0 to last, the algorithm can be defined as follows (pseudo-code):

for i from last downto 1 do:

", + "

let j = random integer in range 0 $\\leq$ j $\\leq$ i

", + "

swap items[i] with items[j]

Notes:

", + "It modifies the input array in-place. If that is unreasonable in your programming language, you may amend the algorithm to return the shuffled items as a new array instead.", + "The algorithm can also be amended to iterate from left to right, if that is more convenient.", + "

{|

", + "

|-

", + "

! Input array

", + "

! Possible output arrays

", + "

|-

", + "

| []

", + "

| []

", + "

|-

", + "

| [10]

", + "

| [10]

", + "

|-

", + "

| [10, 20]

", + "

| [10, 20][20, 10]

", + "

|-

", + "

| [10, 20, 30]

", + "

| [10, 20, 30][10, 30, 20][20, 10, 30][20, 30, 10][30, 10, 20][30, 20, 10]

", + "

|}

(These are listed here just for your convenience; no need to demonstrate them on the page.)

", + "Sattolo cycle", + "


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "function knuthShuffle(arr) {", + " var rand, temp, i;", + "", + " for (i = arr.length - 1; i > 0; i -= 1) {", + " rand = Math.floor((i + 1) * Math.random());//get random between zero and i (inclusive)", + " temp = arr[rand];//swap i and the zero-indexed number", + " arr[rand] = arr[i];", + " arr[i] = temp;", + " }", + " return arr;", + "}", + "", + "var res = {", + " '1,2,3': 0, '1,3,2': 0,", + " '2,1,3': 0, '2,3,1': 0,", + " '3,1,2': 0, '3,2,1': 0", + "};", + "", + "for (var i = 0; i < 100000; i++) {", + " res[knuthShuffle([1,2,3]).join(',')] += 1;", + "}", + "", + "for (var key in res) {", + " print(key + \"\\t\" + res[key]);", + "}", + "Results in:", + "
1,2,3   16619",
+      "1,3,2   16614",
+      "2,1,3   16752",
+      "2,3,1   16959",
+      "3,1,2   16460",
+      "3,2,1   16596
", + "", + "", + "===ES6===", + "", + "====Mutating in-place swap====", + "(lst => {", + " ", + " // knuthShuffle :: [a] -> [a]", + " let knuthShuffle = lst =>", + " range(0, lst.length - 1)", + " .reduceRight((a, i) => {", + " let iRand = i ? randomInteger(0, i) : 0,", + " tmp = a[iRand];", + "", + " return iRand !== i ? (", + " a[iRand] = a[i],", + " a[i] = tmp,", + " a", + " ) : a;", + " }, lst),", + " ", + " // randomInteger :: Int -> Int -> Int", + " randomInteger = (low, high) =>", + " low + Math.floor(", + " (Math.random() * ((high - low) + 1))", + " ),", + " ", + " // range :: Int -> Int -> Maybe Int -> [Int]", + " range = (m, n, step) => {", + " let d = (step || 1) * (n >= m ? 1 : -1);", + " ", + " return Array.from({", + " length: Math.floor((n - m) / d) + 1", + " }, (_, i) => m + (i * d));", + " };", + " ", + " ", + " return knuthShuffle(lst);", + " ", + "})(", + " 'alpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu'", + " .split(' ')", + " );", + "", + "{{Out}}", + "e.g.", + "[\"iota\", \"epsilon\", \"kappa\", \"theta\", \"gamma\", \"delta\", ", + "\"lambda\", \"eta\", \"zeta\", \"beta\", \"mu\", \"alpha\"]", + "", + "====Non-mutating swap====", + "", + "(lst => {", + "", + " // knuthShuffle :: [a] -> [a]", + " function knuthShuffle(lst) {", + " let lng = lst.length;", + "", + " return lng ? range(0, lng - 1)", + " .reduceRight((a, i) => {", + " let iRand = i > 0 ? randomInteger(0, i) : 0;", + "", + " return i !== iRand ? swapped(a, i, iRand) : a;", + " }, lst) : [];", + " };", + "", + "", + " // A non-mutating variant of swapped():", + "", + " // swapped :: [a] -> Int -> Int -> [a] ", + " let swapped = (lst, iFrom, iTo) => {", + " let [iLow, iHigh] = iTo > iFrom ? (", + " [iFrom, iTo]", + " ) : [iTo, iFrom];", + "", + " return iLow !== iHigh ? (", + " [].concat(", + " (iLow > 0 ? lst.slice(0, iLow) : []), // pre", + " lst[iHigh], // DOWN", + " lst.slice(iLow + 1, iHigh), // mid", + " lst[iLow], // UP", + " lst.slice(iHigh + 1) // post", + " ) ", + " ) : lst.slice(0) // (unchanged copy)", + " },", + "", + " // randomInteger :: Int -> Int -> Int", + " randomInteger = (low, high) =>", + " low + Math.floor(", + " (Math.random() * ((high - low) + 1))", + " ),", + "", + " // range :: Int -> Int -> Maybe Int -> [Int]", + " range = (m, n, step) => {", + " let d = (step || 1) * (n >= m ? 1 : -1);", + "", + " return Array.from({", + " length: Math.floor((n - m) / d) + 1", + " }, (_, i) => m + (i * d));", + " };", + "", + "", + " return knuthShuffle(lst);", + "", + "})(", + " 'alpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu'", + " .split(' ')", + ");", + "", + "{{Out}}", + "e.g.", + "[\"mu\", \"theta\", \"beta\", \"eta\", \"delta\", \"epsilon\", ", + "\"kappa\", \"alpha\", \"gamma\", \"lambda\", \"zeta\", \"iota\"]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ed7", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function knuthShuffle(arr) {\n var rand, temp, i;\n\n for (i = arr.length - 1; i > 0; i -= 1) {\n rand = Math.floor((i + 1) * Math.random());//get random between zero and i (inclusive)\n temp = arr[rand];//swap i and the zero-indexed number\n arr[rand] = arr[i];\n arr[i] = temp;\n }\n return arr;\n}\n\nvar res = {\n '1,2,3': 0, '1,3,2': 0,\n '2,1,3': 0, '2,3,1': 0,\n '3,1,2': 0, '3,2,1': 0\n};\n\nfor (var i = 0; i < 100000; i++) {\n res[knuthShuffle([1,2,3]).join(',')] += 1;\n}\n\nfor (var key in res) {\n print(key + \"\\t\" + res[key]);\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Kronecker product based fractals", + "type": "Waypoint", + "description": [ + "

This task is based on Kronecker product of two matrices. If your

", + "

language has no a built-in function for such product then you need to implement it first.

", + "

The essence of fractals is self-replication (at least, self-similar replications).

", + "

So, using n times self-product of the matrix (filled with 0/1) we will have a fractal of the n-th order.

", + "

Actually, \"self-product\" is a Kronecker power of the matrix. In other words: for a matrix M and a power n create a function like matkronpow(M, n), which returns MxMxMx... (n times product).

", + "

A formal recurrent algorithm of creating Kronecker power of a matrix is the following:

", + "

Algorithm:

", + "

Let M is an initial matrix, and Rn is a resultant block matrix of the Kronecker power, where n is the power (a.k.a. order).

", + "

Self-product of M, i.e., M x M producing R2 (resultant matrix with order/power 2).

", + "

To receive the next order/power matrix use this recurrent formula: Rn = R(n-1) x M.

", + "

Plot this Rn matrix to produce the nth order fractal.

", + "

Even just looking at the resultant matrix you can see what will be plotted.

", + "

There are virtually infinitely many fractals of this type. You are limited only by your creativity and

", + "

the power of your computer.

", + "Task:", + "

Using Kronecker product implement and show two popular and well-known fractals, i.e.:

", + " Vicsek fractal;", + " Sierpinski carpet fractal.", + "The last one ( Sierpinski carpet) is already here on RC, but built using different approaches.", + "Test cases:", + "

These 2 fractals (each order/power 4 at least) should be built using the following 2 simple matrices:

", + "
",
+      "|0 1 0|\tand |1 1 1|",
+      "|1 1 1|\t    |1 0 1|",
+      "|0 1 0|\t    |1 1 1|",
+      "
", + "Note:", + "Output could be a graphical or ASCII-art representation, but if an order is set > 4 then printing is not suitable.", + "The orientation and distortion of the fractal could be your language/tool specific.", + "It would be nice to see one additional fractal of your choice, e.g., based on using a single (double) letter(s) of an alphabet, any sign(s) or alredy made a resultant matrix of the Kronecker product.", + "See implementations and results below in JavaScript, PARI/GP and R languages. They have additional samples of \"H\", \"+\" and checkerboard fractals." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Using Version #1 of [[Kronecker_product| Kronecker product]] in JavaScript.", + "{{Works with|Chrome}}", + "[[File:VicsekFractaljs.png|200px|right|thumb|Output VicsekFractaljs.png]]", + "[[File:SierpCarpetFractaljs.png|200px|right|thumb|Output SierpCarpetFractaljs.png]]", + "[[File:CheckbrdFractaljs.png|200px|right|thumb|Output CheckbrdFractaljs.png]]", + "", + "// KPF.js 6/23/16 aev", + "// HFJS: Plot any matrix mat (filled with 0,1)", + "function pmat01(mat, color) {", + " // DCLs", + " var cvs = document.getElementById('canvId');", + " var ctx = cvs.getContext(\"2d\"); ", + " var w = cvs.width; var h = cvs.height;", + " var m = mat[0].length; var n = mat.length;", + " // Cleaning canvas and setting plotting color ", + " ctx.fillStyle=\"white\"; ctx.fillRect(0,0,w,h);", + " ctx.fillStyle=color;", + " // MAIN LOOP", + " for(var i=0; i'+title+'
:
');",
+      "  for(var i=0; i'); re='';",
+      "  }//fend i",
+      "  document.write('
');", + "}", + "// mkp function (exotic arrow function): Return the Kronecker product", + "// of the a and b matrices", + "mkp=(a,b)=>a.map(a=>b.map(b=>a.map(y=>b.map(x=>r.push(y*x)),t.push(r=[]))),t=[])&&t;", + "
", + "", + ";Required tests:", + "", + "", + "", + "", + " Vicsek fractal", + " ", + "", + "", + "

Vicsek fractal

", + " Next: Sierpinski carpet fractal
", + " ", + "", + "
", + "", + "", + "", + "", + "", + " Sierpinski carpet fractal", + " ", + "", + "", + "

Sierpinski carpet fractal

", + " Next: Checkerboard
", + " ", + "", + "", + "", + "", + "", + "", + " Checkerboard", + " ", + "", + "", + "

Checkerboard

", + " Next: Vicsek fractal
", + " ", + "", + "
", + "", + "{{Output}} ", + "
",
+      "Page VicsekFractal.html with VicsekFractaljs.png",
+      "Page SierpCarpetFractal.html with SierpCarpetFractaljs.png",
+      "Page Checkerboard.html with CheckbrdFractaljs.png",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ed8", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n// KPF.js 6/23/16 aev\n// HFJS: Plot any matrix mat (filled with 0,1)\nfunction pmat01(mat, color) {\n // DCLs\n var cvs = document.getElementById('canvId');\n var ctx = cvs.getContext(\"2d\"); \n var w = cvs.width; var h = cvs.height;\n var m = mat[0].length; var n = mat.length;\n // Cleaning canvas and setting plotting color \n ctx.fillStyle=\"white\"; ctx.fillRect(0,0,w,h);\n ctx.fillStyle=color;\n // MAIN LOOP\n for(var i=0; i'+title+':
');\n  for(var i=0; i'); re='';\n  }//fend i\n  document.write('
');\n}\n// mkp function (exotic arrow function): Return the Kronecker product\n// of the a and b matrices\nmkp=(a,b)=>a.map(a=>b.map(b=>a.map(y=>b.map(x=>r.push(y*x)),t.push(r=[]))),t=[])&&t;\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Kronecker product", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement the Kronecker product of two matrices (arbitrary sized) resulting in a block matrix.

", + "Test cases:", + "

Show results for each of the following two samples:

Sample 1 (from Wikipedia):

", + "
",
+      "│1 2│  x  │0 5│\t= │ 0  5  0 10│",
+      "│3 4│     │6 7│\t  │ 6  7 12 14│",
+      "\t\t  │ 0 15  0 20│",
+      "\t\t  │18 21 24 28│",
+      "

Sample 2:

", + "
",
+      "│0 1 0│ x │1 1 1 1│ = │0 0 0 0 1 1 1 1 0 0 0 0│",
+      "│1 1 1│   │1 0 0 1│   │0 0 0 0 1 0 0 1 0 0 0 0│",
+      "│0 1 0│   │1 1 1 1│   │0 0 0 0 1 1 1 1 0 0 0 0│",
+      "\t              │1 1 1 1 1 1 1 1 1 1 1 1│",
+      "                      │1 0 0 1 1 0 0 1 1 0 0 1│",
+      "                      │1 1 1 1 1 1 1 1 1 1 1 1│",
+      "                      │0 0 0 0 1 1 1 1 0 0 0 0│",
+      "                      │0 0 0 0 1 0 0 1 0 0 0 0│",
+      "                      │0 0 0 0 1 1 1 1 0 0 0 0│",
+      "
", + "

See implementations and results below in JavaScript and PARI/GP languages.

", + "Related task:", + " Kronecker product based fractals. " + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===Imperative===", + "====Version #1.====", + "{{Works with|Chrome}}", + "", + "// matkronprod.js", + "// Prime function:", + "// mkp arrow function: Return the Kronecker product of the a and b matrices.", + "// Note: both a and b must be matrices, i.e., 2D rectangular arrays.", + "mkp=(a,b)=>a.map(a=>b.map(b=>a.map(y=>b.map(x=>r.push(y*x)),t.push(r=[]))),t=[])&&t;", + "// Helper functions:", + "// Log title and matrix mat to console", + "function matl2cons(title,mat) {console.log(title); console.log(mat.join`\\n`)}", + "// Print title to document", + "function pttl2doc(title) {document.write(''+title+'
')}", + "// Print title and matrix mat to document", + "function matp2doc(title,mat) {", + " document.write(''+title+':
');", + " for (var i = 0; i < mat.length; i++) {", + " document.write('  '+mat[i].join(' ')+'
');", + " }", + "}", + "
", + "", + ";Required tests:", + "", + "", + "", + " Kronecker product: Sample 1 (from Wikipedia) and Sample 2", + " ", + " ", + "", + "", + " ", + "{{Output}} '''Console and page results'''", + "
",
+      "Kronecker product of A and B matrices",
+      "A",
+      "1,2",
+      "3,4",
+      "B",
+      "0,5",
+      "6,7",
+      "A x B",
+      "0,5,0,10",
+      "6,7,12,14",
+      "0,15,0,20",
+      "18,21,24,28",
+      "Kronecker product of A and B matrices",
+      "A",
+      "0,1,0",
+      "1,1,1",
+      "0,1,0",
+      "B",
+      "1,1,1,1",
+      "1,0,0,1",
+      "1,1,1,1",
+      "A x B",
+      "0,0,0,0,1,1,1,1,0,0,0,0",
+      "0,0,0,0,1,0,0,1,0,0,0,0",
+      "0,0,0,0,1,1,1,1,0,0,0,0",
+      "1,1,1,1,1,1,1,1,1,1,1,1",
+      "1,0,0,1,1,0,0,1,1,0,0,1",
+      "1,1,1,1,1,1,1,1,1,1,1,1",
+      "0,0,0,0,1,1,1,1,0,0,0,0",
+      "0,0,0,0,1,0,0,1,0,0,0,0",
+      "0,0,0,0,1,1,1,1,0,0,0,0",
+      "
", + "", + "====Version #2.====", + "This version is more understandable for sure.", + "{{trans|PARI/GP}}", + "{{Works with|Chrome}}", + "", + "// matkronprod2.js", + "// Prime function:", + "// mkp2(): Return the Kronecker product of the a and b matrices", + "// Note: both a and b must be matrices, i.e., 2D rectangular arrays.", + "function mkp2(a,b) {", + " var m=a.length, n=a[0].length, p=b.length, q=b[0].length;", + " var rtn=m*p, ctn=n*q; var r=new Array(rtn);", + " for (var i=0; i'+title+'
')}", + "// Print title and matrix mat to document", + "function matp2doc(title,mat) {", + " document.write(''+title+':
');", + " for (var i=0; i < mat.length; i++) {", + " document.write('  '+mat[i].join(' ')+'
');", + " }", + "}", + "
", + ";Required tests:", + "", + "", + "", + " Kronecker product v.2: Sample 1 (from Wikipedia) and Sample 2", + " ", + " ", + "", + "", + " ", + "", + "{{Output}} '''Console and page results'''", + "
",
+      "Output is identical to Version #1 above.",
+      "
", + "", + "===Functional===", + "====ES6====", + "{{Trans|Haskell}}", + "(As JavaScript is now widely embedded in non-browser contexts, a non-HTML string value is returned here, rather than invoking a DOM method, which will not always be available to a JavaScript interpreter)", + "(() => {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // concat :: [[a]] -> [a]", + " const concat = xs => [].concat.apply([], xs);", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // 2 or more arguments", + " // curry :: Function -> Function", + " const curry = (f, ...args) => {", + " const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :", + " function () {", + " return go(xs.concat([].slice.apply(arguments)));", + " };", + " return go([].slice.call(args, 1));", + " };", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = curry((f, xs) => xs.map(f));", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x); //, null, 2);", + "", + " // transpose :: [[a]] -> [[a]]", + " const transpose = xs =>", + " xs[0].map((_, col) => xs.map(row => row[col]));", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + "", + " // KRONECKER PRODUCT OF TWO MATRICES --------------------------------------", + "", + " // kprod :: [[Num]] -> [[Num]] -> [[Num]]", + " const kprod = (xs, ys) =>", + " concatMap(", + " m => map(concat, transpose(m)),", + " map(map(f(ys)), xs)", + " );", + "", + " // (* n) mapped over each element in a matrix", + " // f :: [[Num]] -> Num -> [[Num]]", + " const f = curry((mx, n) => map(map(x => x * n), mx));", + "", + " // TEST -------------------------------------------------------------------", + " return unlines(map(rows => unlines(map(show, rows)), [", + " kprod([", + " [1, 2],", + " [3, 4]", + " ], [", + " [0, 5],", + " [6, 7]", + " ]), [], // One empty output line", + " kprod([", + " [0, 1, 0],", + " [1, 1, 1],", + " [0, 1, 0]", + " ], [", + " [1, 1, 1, 1],", + " [1, 0, 0, 1],", + " [1, 1, 1, 1]", + " ])", + " ]));", + "})();", + "{{Out}}", + "
[0,5,0,10]",
+      "[6,7,12,14]",
+      "[0,15,0,20]",
+      "[18,21,24,28]",
+      "",
+      "[0,0,0,0,1,1,1,1,0,0,0,0]",
+      "[0,0,0,0,1,0,0,1,0,0,0,0]",
+      "[0,0,0,0,1,1,1,1,0,0,0,0]",
+      "[1,1,1,1,1,1,1,1,1,1,1,1]",
+      "[1,0,0,1,1,0,0,1,1,0,0,1]",
+      "[1,1,1,1,1,1,1,1,1,1,1,1]",
+      "[0,0,0,0,1,1,1,1,0,0,0,0]",
+      "[0,0,0,0,1,0,0,1,0,0,0,0]",
+      "[0,0,0,0,1,1,1,1,0,0,0,0]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ed9", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n// matkronprod.js\n// Prime function:\n// mkp arrow function: Return the Kronecker product of the a and b matrices.\n// Note: both a and b must be matrices, i.e., 2D rectangular arrays.\nmkp=(a,b)=>a.map(a=>b.map(b=>a.map(y=>b.map(x=>r.push(y*x)),t.push(r=[]))),t=[])&&t;\n// Helper functions:\n// Log title and matrix mat to console\nfunction matl2cons(title,mat) {console.log(title); console.log(mat.join`\\n`)}\n// Print title to document\nfunction pttl2doc(title) {document.write(''+title+'
')}\n// Print title and matrix mat to document\nfunction matp2doc(title,mat) {\n document.write(''+title+':
');\n for (var i = 0; i < mat.length; i++) {\n document.write('  '+mat[i].join(' ')+'
');\n }\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Langton's ant", + "type": "Waypoint", + "description": [ + "

Langton's ant is a cellular automaton that models an ant sitting on a plane of cells, all of which are white initially, facing in one of four directions.

", + "

Each cell can either be black or white.

", + "

The ant moves according to the color of the cell it is currently sitting in, with the following rules:

", + "

:# If the cell is black, it changes to white and the ant turns left;

", + "

:# If the cell is white, it changes to black and the ant turns right;

", + "

:# The ant then moves forward to the next cell, and repeat from step 1.

This rather simple ruleset leads to an initially chaotic movement pattern, and after about 10000 steps, a cycle appears where the ant moves steadily away from the starting location in a diagonal corridor about 10 pixels wide. ", + "

Conceptually the ant can then travel infinitely far away.

", + "Task:", + "

Start the ant near the center of a 100 by 100 field of cells, which is about big enough to contain the initial chaotic part of the movement.

Follow the movement rules for the ant, terminate when it moves out of the region, and show the cell colors it leaves behind.

", + "

The problem has received some analysis; for more details, please take a look at the Wikipedia article (a link is below)..

", + "See also:", + " Wikipedia: Langton's ant.Related task:", + " Rosetta Code: Conway's Game of Life." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "Utilises the HTML5 canvas element to procedurally generate the image... I wanted to see the progress of the grid state as it was generated, so this implementation produces a incrementally changing image until an 'ant' hits a cell outside of the coordinate system. It can also accept multiple ants, this adds minimal complexity with only the addition of an 'ants' array which is iterated in each step, no additional conditions are necessary to simulate multiple ants, they coexist quite well... good ants ! 1st argument is an array of ant objects, 2nd argument is an object property list of options to change grid size, pixel size and interval (animation speed).", + "", + "", + "// create global canvas", + "var canvas = document.createElement('canvas');", + "canvas.id = 'globalCanvas';", + "document.body.appendChild(canvas);", + "", + "function langtonant(antx, optx) {", + "\t'use strict';", + "\tvar x, y, i;", + "", + "\t// extend default opts", + "\tvar opts = {", + "\t\tgridsize: 100,", + "\t\tpixlsize: 4,", + "\t\tinterval: 4", + "\t};", + "\tfor (i in optx) {", + "\t\topts[i] = optx[i];", + "\t}", + "", + "\t// extend default ants", + "\tvar ants = [{", + "\t\tx: 50,", + "\t\ty: 50,", + "\t\td: 0", + "\t}];", + "\tfor (i in antx) {", + "\t\tants[i] = antx[i];", + "\t}", + "", + "\t// initialise grid", + "\tvar grid = [];", + "\tfor (x = 0; x < opts.gridsize; x ++) {", + "\t\tgrid[x] = [];", + "\t\tfor (y = 0; y < opts.gridsize; y ++) {", + "\t\t\tgrid[x][y] = true;", + "\t\t}", + "\t}", + "", + "\t// initialise directions", + "\tvar dirs = [", + "\t\t{x: 1, y: 0},", + "\t\t{x: 0, y: -1},", + "\t\t{x: -1, y: 0},", + "\t\t{x: 0, y: 1}", + "\t];", + "", + "\t// initialise canvas", + "\tvar canv = document.getElementById('globalCanvas');", + "\tvar cont = canv.getContext('2d');", + "\tcanv.width = opts.gridsize * opts.pixlsize;", + "\tcanv.height = opts.gridsize * opts.pixlsize;", + "", + "\t// initialise pixels", + "\tvar pixlblac = cont.createImageData(opts.pixlsize, opts.pixlsize);", + "\tfor (i = 0; i < (opts.pixlsize * opts.pixlsize * 4); i += 4) {", + "\t\tpixlblac.data[i + 3] = 255;", + "\t}", + "\tvar pixlwhit = cont.createImageData(opts.pixlsize, opts.pixlsize);", + "\tfor (i = 0; i < (opts.pixlsize * opts.pixlsize * 4); i += 4) {", + "\t\tpixlwhit.data[i + 3] = 0;", + "\t}", + "", + "\t// run simulation", + "\tfunction simulate() {", + "\t\tvar sane = true;", + "", + "\t\t// iterate over ants", + "\t\tfor (i = 0; i < ants.length; i ++) {", + "\t\t\tvar n = ants[i];", + "", + "\t\t\t// invert, draw, turn", + "\t\t\tif (grid[n.x][n.y]) {", + "\t\t\t\tgrid[n.x][n.y] = false;", + "\t\t\t\tcont.putImageData(pixlblac, n.x * opts.pixlsize, n.y * opts.pixlsize);", + "\t\t\t\tn.d --;", + "\t\t\t} else {", + "\t\t\t\tgrid[n.x][n.y] = true;", + "\t\t\t\tcont.putImageData(pixlwhit, n.x * opts.pixlsize, n.y * opts.pixlsize);", + "\t\t\t\tn.d ++;", + "\t\t\t}", + "", + "\t\t\t// modulus wraparound", + "\t\t\tn.d += dirs.length;", + "\t\t\tn.d %= dirs.length;", + "", + "\t\t\t// position + direction", + "\t\t\tn.x += dirs[n.d].x;", + "\t\t\tn.y += dirs[n.d].y;", + "", + "\t\t\t// sanity check", + "\t\t\tsane = (n.x < 0 || n.x > opts.gridsize || n.y < 0 || n.y > opts.gridsize) ? false : sane;", + "\t\t}", + "", + "\t\t// loop with interval", + "\t\tif (sane) {", + "\t\t\tsetTimeout(simulate, opts.interval);", + "\t\t}", + "\t}", + "", + "\tsimulate();", + "}", + "", + "", + "Usage: default ants, custom opts", + "", + "", + "langtonant({}, {", + "\tgridsize: 100,", + "\tpixlsize: 4,", + "\tinterval: 4", + "});", + "", + "", + "{{out}}", + "", + "[http://jsbin.com/ocuwal/1/edit Live Version]", + "", + "[[Image:Langtons Ant - JavaScript 1.png]]", + "", + "Usage: custom ants, default opts", + "", + "", + "langtonant([", + "\t{", + "\t\tx: (100 / 2) + 7,", + "\t\ty: (100 / 2) + 7,", + "\t\td: 1", + "\t}, {", + "\t\tx: (100 / 2) + 7,", + "\t\ty: (100 / 2) - 7,", + "\t\td: 2", + "\t}, {", + "\t\tx: (100 / 2) - 7,", + "\t\ty: (100 / 2) - 7,", + "\t\td: 3", + "\t}, {", + "\t\tx: (100 / 2) - 7,", + "\t\ty: (100 / 2) + 7,", + "\t\td: 0", + "\t}", + "]);", + "", + "", + "{{out}}", + "", + "[http://jsbin.com/ahumuz/1/edit Live Version]", + "", + "[[Image:Langtons Ant - JavaScript 2.png]]", + "", + "'''More functional approach to Javascript.'''", + "", + "Requires lodash. Wants a canvas with id = \"c\"", + "", + "", + "///////////////////", + "// LODASH IMPORT //", + "///////////////////", + "", + "// import all lodash functions to the main namespace, but isNaN not to cause conflicts", + "_.each(_.keys(_), k => window[k === 'isNaN' ? '_isNaN' : k] = _[k]);", + "", + "const", + "WORLD_WIDTH = 100,", + "WORLD_HEIGHT = 100,", + "PIXEL_SIZE = 4,", + "DIRTY_COLOR = '#000',", + "VIRGIN_COLOR = '#fff',", + "RUNS = 10000,", + "SPEED = 50,", + "", + "// up right down left", + "DIRECTIONS = [0, 1, 2, 3],", + "", + "displayWorld = (world) => each(world, (row, rowidx) => {", + " each(row, (cell, cellidx) => {", + " canvas.fillStyle = cell === 1 ? DIRTY_COLOR : VIRGIN_COLOR;", + " canvas.fillRect(rowidx * PIXEL_SIZE, cellidx * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE);", + " });", + "}),", + "", + "moveAnt = (world, ant) => {", + " world[ant.x][ant.y] = world[ant.x][ant.y] === 1 ? 0 : 1;", + " ant.dir = DIRECTIONS[(4 + ant.dir + (world[ant.x][ant.y] === 0 ? 1 : -1)) % 4];", + " switch (ant.dir) {", + " case DIRECTIONS[0]:", + " ant.y -= 1;", + " break;", + " case DIRECTIONS[1]:", + " ant.x -= 1;", + " break;", + " case DIRECTIONS[2]:", + " ant.y += 1;", + " break;", + " case DIRECTIONS[3]:", + " ant.x += 1;", + " break;", + " }", + "", + " return [world, ant];", + "},", + "", + "updateWorld = (world, ant, runs) => {", + " [world, ant] = moveAnt(world, ant);", + " displayWorld(world);", + "", + " if (runs > 0) setTimeout(partial(updateWorld, world, ant, --runs), SPEED);", + "},", + "", + "canvas = document.getElementById('c').getContext('2d');", + "", + "let", + "world = map(range(WORLD_HEIGHT), i => map(range(WORLD_WIDTH), partial(identity, 0))),", + "ant = {", + " x: WORLD_WIDTH / 2,", + " y: WORLD_HEIGHT / 2,", + " dir: DIRECTIONS[0]", + "};", + "", + "canvas.canvas.width = WORLD_WIDTH * PIXEL_SIZE;", + "canvas.canvas.height = WORLD_HEIGHT * PIXEL_SIZE;", + "", + "updateWorld(world, ant, RUNS);", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eda", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n// create global canvas\nvar canvas = document.createElement('canvas');\ncanvas.id = 'globalCanvas';\ndocument.body.appendChild(canvas);\n\nfunction langtonant(antx, optx) {\n\t'use strict';\n\tvar x, y, i;\n\n\t// extend default opts\n\tvar opts = {\n\t\tgridsize: 100,\n\t\tpixlsize: 4,\n\t\tinterval: 4\n\t};\n\tfor (i in optx) {\n\t\topts[i] = optx[i];\n\t}\n\n\t// extend default ants\n\tvar ants = [{\n\t\tx: 50,\n\t\ty: 50,\n\t\td: 0\n\t}];\n\tfor (i in antx) {\n\t\tants[i] = antx[i];\n\t}\n\n\t// initialise grid\n\tvar grid = [];\n\tfor (x = 0; x < opts.gridsize; x ++) {\n\t\tgrid[x] = [];\n\t\tfor (y = 0; y < opts.gridsize; y ++) {\n\t\t\tgrid[x][y] = true;\n\t\t}\n\t}\n\n\t// initialise directions\n\tvar dirs = [\n\t\t{x: 1, y: 0},\n\t\t{x: 0, y: -1},\n\t\t{x: -1, y: 0},\n\t\t{x: 0, y: 1}\n\t];\n\n\t// initialise canvas\n\tvar canv = document.getElementById('globalCanvas');\n\tvar cont = canv.getContext('2d');\n\tcanv.width = opts.gridsize * opts.pixlsize;\n\tcanv.height = opts.gridsize * opts.pixlsize;\n\n\t// initialise pixels\n\tvar pixlblac = cont.createImageData(opts.pixlsize, opts.pixlsize);\n\tfor (i = 0; i < (opts.pixlsize * opts.pixlsize * 4); i += 4) {\n\t\tpixlblac.data[i + 3] = 255;\n\t}\n\tvar pixlwhit = cont.createImageData(opts.pixlsize, opts.pixlsize);\n\tfor (i = 0; i < (opts.pixlsize * opts.pixlsize * 4); i += 4) {\n\t\tpixlwhit.data[i + 3] = 0;\n\t}\n\n\t// run simulation\n\tfunction simulate() {\n\t\tvar sane = true;\n\n\t\t// iterate over ants\n\t\tfor (i = 0; i < ants.length; i ++) {\n\t\t\tvar n = ants[i];\n\n\t\t\t// invert, draw, turn\n\t\t\tif (grid[n.x][n.y]) {\n\t\t\t\tgrid[n.x][n.y] = false;\n\t\t\t\tcont.putImageData(pixlblac, n.x * opts.pixlsize, n.y * opts.pixlsize);\n\t\t\t\tn.d --;\n\t\t\t} else {\n\t\t\t\tgrid[n.x][n.y] = true;\n\t\t\t\tcont.putImageData(pixlwhit, n.x * opts.pixlsize, n.y * opts.pixlsize);\n\t\t\t\tn.d ++;\n\t\t\t}\n\n\t\t\t// modulus wraparound\n\t\t\tn.d += dirs.length;\n\t\t\tn.d %= dirs.length;\n\n\t\t\t// position + direction\n\t\t\tn.x += dirs[n.d].x;\n\t\t\tn.y += dirs[n.d].y;\n\n\t\t\t// sanity check\n\t\t\tsane = (n.x < 0 || n.x > opts.gridsize || n.y < 0 || n.y > opts.gridsize) ? false : sane;\n\t\t}\n\n\t\t// loop with interval\n\t\tif (sane) {\n\t\t\tsetTimeout(simulate, opts.interval);\n\t\t}\n\t}\n\n\tsimulate();\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Largest int from concatenated ints", + "type": "Waypoint", + "description": [ + "Task: ", + "

Given a set of positive integers, write a function to order the integers in such a way that the concatenation of the numbers forms the largest possible integer and return this integer.

Use the following two sets of integers as tests and show your program output here.

::::* {1, 34, 3, 98, 9, 76, 45, 4}

", + "

::::* {54, 546, 548, 60}

", + "Possible algorithms:", + "A solution could be found by trying all combinations and return the best. ", + "Another way to solve this is to note that in the best arrangement, for any two adjacent original integers X and Y, the concatenation X followed by Y will be numerically greater than or equal to the concatenation Y followed by '''X.", + "Yet another way to solve this is to pad the integers to the same size by repeating the digits then sort using these repeated integers as a sort key.See also:", + " Algorithms: What is the most efficient way to arrange the given numbers to form the biggest number?", + " Constructing the largest number possible by rearranging a list" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + " (function () {", + " 'use strict';", + "", + " // maxCombine :: [Int] -> Int", + " function maxCombine(xs) {", + " return parseInt(", + " xs.sort(", + " function (x, y) {", + " var a = x.toString(),", + " b = y.toString(),", + " ab = parseInt(a + b),", + " ba = parseInt(b + a);", + "", + " return ab > ba ? -1 : (ab < ba ? 1 : 0);", + " }", + " )", + " .join(''), 10", + " );", + " }", + "", + " return [", + " [1, 34, 3, 98, 9, 76, 45, 4],", + " [54, 546, 548, 60]", + " ].map(maxCombine);", + "", + " })();", + "", + "", + "{{Out}}", + "", + "
[998764543431, 6054854654]
", + "", + "", + "", + "===ES6===", + "var maxCombine = (a) => +(a.sort((x, y) => +(\"\" + y + x) - +(\"\" + x + y)).join(''));", + "", + "// test & output", + "console.log([", + " [1, 34, 3, 98, 9, 76, 45, 4],", + " [54, 546, 548, 60]", + "].map(maxCombine));", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7edb", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + " (function () {\n 'use strict';\n\n // maxCombine :: [Int] -> Int\n function maxCombine(xs) {\n return parseInt(\n xs.sort(\n function (x, y) {\n var a = x.toString(),\n b = y.toString(),\n ab = parseInt(a + b),\n ba = parseInt(b + a);\n\n return ab > ba ? -1 : (ab < ba ? 1 : 0);\n }\n )\n .join(''), 10\n );\n }\n\n return [\n [1, 34, 3, 98, 9, 76, 45, 4],\n [54, 546, 548, 60]\n ].map(maxCombine);\n\n })();\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Last Friday of each month", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a program or a script that returns the date of the last Fridays of each month of a given year.

The year may be given through any simple input method in your language (command line, std in, etc).

", + "

Example of an expected output:

", + "
./last_fridays 2012",
+      "2012-01-27",
+      "2012-02-24",
+      "2012-03-30",
+      "2012-04-27",
+      "2012-05-25",
+      "2012-06-29",
+      "2012-07-27",
+      "2012-08-31",
+      "2012-09-28",
+      "2012-10-26",
+      "2012-11-30",
+      "2012-12-28",
+      "
", + "Related tasks", + "Five weekends", + "Day of the week", + "Find the last Sunday of each month" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7edc", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Last letter-first letter", + "type": "Waypoint", + "description": [ + "

A certain children's game involves starting with a word in a particular category. Each participant in turn says a word, but that word must begin with the final letter of the previous word. Once a word has been given, it cannot be repeated. If an opponent cannot give a word in the category, they fall out of the game.

", + "

For example, with \"animals\" as the category,

", + "
",
+      "Child 1: dog ",
+      "Child 2: goldfish",
+      "Child 1: hippopotamus",
+      "Child 2: snake",
+      "...",
+      "
", + "Task:", + "

Take the following selection of 70 English Pokemon names (extracted from Wikipedia's list of Pokemon) and generate the/a sequence with the highest possible number of Pokemon names where the subsequent name starts with the final letter of the preceding name.

No Pokemon name is to be repeated.

",
+      "audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon",
+      "cresselia croagunk darmanitan deino emboar emolga exeggcute gabite",
+      "girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan",
+      "kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine",
+      "nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2",
+      "porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking",
+      "sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko",
+      "tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask",
+      "
", + "

Extra brownie points for dealing with the full list of 646 names.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7edd", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Leap year", + "type": "Waypoint", + "description": [ + "

Determine whether a given year is a leap year in the Gregorian calendar.

See Also

", + "Leap year (wiki)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var isLeapYear = function (year) { return (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0); };", + "Or, by setting the day to the 29th and checking if the day remains", + "// Month values start at 0, so 1 is for February", + "var isLeapYear = function (year) { return new Date(year, 1, 29).getDate() === 29; };", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ede", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var isLeapYear = function (year) { return (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0); };\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Least common multiple", + "type": "Waypoint", + "description": [ + "Task:", + "

Compute the least common multiple of two integers.

Given m and n, the least common multiple is the smallest positive integer that has both m and n as factors.

", + "Example:", + "

The least common multiple of 12 and 18 is 36, because 12 is a factor (12 × 3 = 36), and 18 is a factor (18 × 2 = 36), and there is no positive integer less than 36 that has both factors. As a special case, if either m or n is zero, then the least common multiple is zero.

One way to calculate the least common multiple is to iterate all the multiples of m, until you find one that is also a multiple of n.

If you already have gcd for greatest common divisor, then this formula calculates lcm.

", + "

::: $\\operatorname{lcm}(m, n) = \\frac{|m \\times n|}{\\operatorname{gcd}(m, n)}$

", + "

One can also find lcm by merging the prime decompositions of both m and n.

", + "References:", + " MathWorld.", + " Wikipedia." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "Computing the least common multiple of an integer array, using the associative law:", + "", + "\\operatorname{lcm}(a,b,c)=\\operatorname{lcm}(\\operatorname{lcm}(a,b),c),", + "", + "\\operatorname{lcm}(a_1,a_2,\\ldots,a_n) = \\operatorname{lcm}(\\operatorname{lcm}(a_1,a_2,\\ldots,a_{n-1}),a_n).", + "", + "function LCM(A) // A is an integer array (e.g. [-50,25,-45,-18,90,447])", + "{ ", + " var n = A.length, a = Math.abs(A[0]);", + " for (var i = 1; i < n; i++)", + " { var b = Math.abs(A[i]), c = a;", + " while (a && b){ a > b ? a %= b : b %= a; } ", + " a = Math.abs(c*A[i])/(a+b);", + " }", + " return a;", + "}", + "", + "/* For example:", + " LCM([-50,25,-45,-18,90,447]) -> 67050", + "*/", + "", + "", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // gcd :: Integral a => a -> a -> a", + " let gcd = (x, y) => {", + " let _gcd = (a, b) => (b === 0 ? a : _gcd(b, a % b)),", + " abs = Math.abs;", + " return _gcd(abs(x), abs(y));", + " }", + "", + " // lcm :: Integral a => a -> a -> a", + " let lcm = (x, y) =>", + " x === 0 || y === 0 ? 0 : Math.abs(Math.floor(x / gcd(x, y)) * y);", + "", + " // TEST", + " return lcm(12, 18);", + "", + "})();", + "", + "{{Out}}", + "
36
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7edf", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function LCM(A) // A is an integer array (e.g. [-50,25,-45,-18,90,447])\n{ \n var n = A.length, a = Math.abs(A[0]);\n for (var i = 1; i < n; i++)\n { var b = Math.abs(A[i]), c = a;\n while (a && b){ a > b ? a %= b : b %= a; } \n a = Math.abs(c*A[i])/(a+b);\n }\n return a;\n}\n\n/* For example:\n LCM([-50,25,-45,-18,90,447]) -> 67050\n*/\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Left factorials", + "type": "Waypoint", + "description": [ + "

Left factorials, !n, may refer to either subfactorials or to factorial sums;

", + "the same notation can be confusingly seen used for the two different definitions.

Sometimes, subfactorials (also known as derangements) may use any of the notations:

", + "

::::::* !n`

", + "

::::::* !n

", + "

::::::*

(It may not be visually obvious, but the last example uses an upside-down exclamation mark.)

", + "This Rosetta Code task will be using this formula for left factorial:", + "

", + "

:: $ !n = \\sum_{k=0}^{n-1} k! $

", + "
", + "

where

", + "

", + "

:: $!0 = 0$

", + "
", + "Task", + "

Display the left factorials for:

", + "zero through ten (inclusive)", + "20 through 110 (inclusive) by tens", + "

Display the length (in decimal digits) of the left factorials for:

", + "1,000, 2,000 through 10,000 (inclusive), by thousands.Also see", + " The OEIS entry: A003422 left factorials", + " The MathWorld entry: left factorial", + " The MathWorld entry: factorial sums", + " The MathWorld entry: subfactorialRelated task:", + " permutations/derangements (subfactorials)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ee0", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Letter frequency", + "type": "Waypoint", + "description": [ + "Task:", + "

Open a text file and count the occurrences of each letter.

Some of these programs count all characters (including punctuation),

", + "

but some only count letters A to Z.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "JavaScript is no longer used only in environments which are carefully isolated from file systems, but JavaScript standards still do not specify standard file-system functions. ", + "Leaving aside the particular and variable details of how files will be opened and read in environments like Node.js and OS X JavaScript for Automation etc., ", + "we can still use core JavasScript (ES5 in the example below), to count the characters in a text once it has been read from a file system.", + "", + "(function(txt) {", + "", + " var cs = txt.split(''),", + " i = cs.length,", + " dct = {},", + " c = '',", + " keys;", + " ", + " while (i--) {", + " c = cs[i];", + " dct[c] = (dct[c] || 0) + 1;", + " }", + " ", + " keys = Object.keys(dct);", + " keys.sort();", + " return keys.map(function (c) { return [c, dct[c]]; });", + "", + "})(\"Not all that Mrs. Bennet, however, with the assistance of her five\\", + "daughters, could ask on the subject, was sufficient to draw from her\\", + "husband any satisfactory description of Mr. Bingley. They attacked him\\", + "in various ways--with barefaced questions, ingenious suppositions, and\\", + "distant surmises; but he eluded the skill of them all, and they were at\\", + "last obliged to accept the second-hand intelligence of their neighbour,\\", + "Lady Lucas. Her report was highly favourable. Sir William had been\\", + "delighted with him. He was quite young, wonderfully handsome, extremely\\", + "agreeable, and, to crown the whole, he meant to be at the next assembly\\", + "with a large party. Nothing could be more delightful! To be fond of\\", + "dancing was a certain step towards falling in love; and very lively\\", + "hopes of Mr. Bingley's heart were entertained.\"); ", + "", + "{{Out}}", + "", + "[[\" \", 121], [\"!\", 1], [\"'\", 1], [\",\", 13], [\"-\", 3], [\".\", 9], [\";\", 2], ", + "[\"B\", 3], [\"H\", 2], [\"L\", 2], [\"M\", 3], [\"N\", 2], [\"S\", 1], [\"T\", 2], [\"W\", 1], ", + "[\"a\", 53], [\"b\", 13], [\"c\", 17], [\"d\", 29], [\"e\", 82], [\"f\", 17], [\"g\", 16], [\"h\", 36],", + "[\"i\", 44], [\"j\", 1], [\"k\", 3], [\"l\", 34], [\"m\", 11], [\"n\", 41], [\"o\", 40], [\"p\", 8], ", + "[\"q\", 2], [\"r\", 35], [\"s\", 39], [\"t\", 55], [\"u\", 20], [\"v\", 7], [\"w\", 17], [\"x\", 2], [\"y\", 16]]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ee1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function(txt) {\n\n var cs = txt.split(''),\n i = cs.length,\n dct = {},\n c = '',\n keys;\n \n while (i--) {\n c = cs[i];\n dct[c] = (dct[c] || 0) + 1;\n }\n \n keys = Object.keys(dct);\n keys.sort();\n return keys.map(function (c) { return [c, dct[c]]; });\n\n})(\"Not all that Mrs. Bennet, however, with the assistance of her five\\\ndaughters, could ask on the subject, was sufficient to draw from her\\\nhusband any satisfactory description of Mr. Bingley. They attacked him\\\nin various ways--with barefaced questions, ingenious suppositions, and\\\ndistant surmises; but he eluded the skill of them all, and they were at\\\nlast obliged to accept the second-hand intelligence of their neighbour,\\\nLady Lucas. Her report was highly favourable. Sir William had been\\\ndelighted with him. He was quite young, wonderfully handsome, extremely\\\nagreeable, and, to crown the whole, he meant to be at the next assembly\\\nwith a large party. Nothing could be more delightful! To be fond of\\\ndancing was a certain step towards falling in love; and very lively\\\nhopes of Mr. Bingley's heart were entertained.\"); \n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Levenshtein distance", + "type": "Waypoint", + "description": [ + "

In information theory and computer science, the Levenshtein distance is a metric for measuring the amount of difference between two sequences (i.e. an edit distance). The Levenshtein distance between two strings is defined as the minimum number of edits needed to transform one string into the other, with the allowable edit operations being insertion, deletion, or substitution of a single character.

", + "Example:", + "

The Levenshtein distance between \"kitten\" and \"sitting\" is 3, since the following three edits change one into the other, and there isn't a way to do it with fewer than three edits:

", + "

:# kitten sitten (substitution of 'k' with 's')

", + "

:# sitten sittin (substitution of 'e' with 'i')

", + "

:# sittin sitting (insert 'g' at the end).

", + "

''The Levenshtein distance between \"rosettacode\", \"raisethysword\" is 8.

The distance between two strings is same as that when both strings are reversed.

", + "Task;", + "

Implements a Levenshtein distance function, or uses a library function, to show the Levenshtein distance between \"kitten\" and \"sitting\".

", + "Related task:", + " Longest common subsequence" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "Iterative:", + "function levenshtein(a, b) {", + " var t = [], u, i, j, m = a.length, n = b.length;", + " if (!m) { return n; }", + " if (!n) { return m; }", + " for (j = 0; j <= n; j++) { t[j] = j; }", + " for (i = 1; i <= m; i++) {", + " for (u = [i], j = 1; j <= n; j++) {", + " u[j] = a[i - 1] === b[j - 1] ? t[j - 1] : Math.min(t[j - 1], t[j], u[j - 1]) + 1;", + " } t = u;", + " } return u[n];", + "}", + "", + "// tests", + "[ ['', '', 0],", + " ['yo', '', 2],", + " ['', 'yo', 2],", + " ['yo', 'yo', 0],", + " ['tier', 'tor', 2],", + " ['saturday', 'sunday', 3],", + " ['mist', 'dist', 1],", + " ['tier', 'tor', 2],", + " ['kitten', 'sitting', 3],", + " ['stop', 'tops', 2],", + " ['rosettacode', 'raisethysword', 8],", + " ['mississippi', 'swiss miss', 8]", + "].forEach(function(v) {", + " var a = v[0], b = v[1], t = v[2], d = levenshtein(a, b);", + " if (d !== t) {", + " console.log('levenstein(\"' + a + '\",\"' + b + '\") was ' + d + ' should be ' + t);", + " }", + "});", + "", + "===ES6===", + "{{Trans|Haskell}}", + "", + "By composition of generic functions:", + "(() => {", + " 'use strict';", + "", + " // levenshtein :: String -> String -> Int", + " const levenshtein = (sa, sb) => {", + " const [s1, s2] = [sa.split(''), sb.split('')];", + "", + " return last(s2.reduce((ns, c) => {", + " const [n, ns1] = uncons(ns);", + "", + " return scanl(", + " (z, [c1, x, y]) =>", + " minimum(", + " [y + 1, z + 1, x + fromEnum(c1 != c)]", + " ),", + " n + 1,", + " zip3(s1, ns, ns1)", + " );", + " }, range(0, s1.length)));", + " };", + "", + "", + " /*********************************************************************/", + " // GENERIC FUNCTIONS", + "", + " // minimum :: [a] -> a", + " const minimum = xs =>", + " xs.reduce((a, x) => (x < a || a === undefined ? x : a), undefined);", + "", + " // fromEnum :: Enum a => a -> Int", + " const fromEnum = x => {", + " const type = typeof x;", + " return type === 'boolean' ? (", + " x ? 1 : 0", + " ) : (type === 'string' ? x.charCodeAt(0) : undefined);", + " };", + "", + " // uncons :: [a] -> Maybe (a, [a])", + " const uncons = xs => xs.length ? [xs[0], xs.slice(1)] : undefined;", + "", + " // scanl :: (b -> a -> b) -> b -> [a] -> [b]", + " const scanl = (f, a, xs) => {", + " for (var lst = [a], lng = xs.length, i = 0; i < lng; i++) {", + " a = f(a, xs[i], i, xs), lst.push(a);", + " }", + " return lst;", + " };", + "", + " // zip3 :: [a] -> [b] -> [c] -> [(a,b,c)]", + " const zip3 = (xs, ys, zs) =>", + " xs.slice(0, Math.min(xs.length, ys.length, zs.length))", + " .map((x, i) => [x, ys[i], zs[i]]);", + "", + " // last :: [a] -> a", + " const last = xs => xs.length ? xs.slice(-1) : undefined;", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " /*********************************************************************/", + " // TEST", + " return [", + " [\"kitten\", \"sitting\"],", + " [\"sitting\", \"kitten\"],", + " [\"rosettacode\", \"raisethysword\"],", + " [\"raisethysword\", \"rosettacode\"]", + " ].map(pair => levenshtein.apply(null, pair));", + "", + " // -> [3, 3, 8, 8]", + "})();", + "", + "{{Out}}", + "[3, 3, 8, 8]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ee2", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function levenshtein(a, b) {\n var t = [], u, i, j, m = a.length, n = b.length;\n if (!m) { return n; }\n if (!n) { return m; }\n for (j = 0; j <= n; j++) { t[j] = j; }\n for (i = 1; i <= m; i++) {\n for (u = [i], j = 1; j <= n; j++) {\n u[j] = a[i - 1] === b[j - 1] ? t[j - 1] : Math.min(t[j - 1], t[j], u[j - 1]) + 1;\n } t = u;\n } return u[n];\n}\n\n// tests\n[ ['', '', 0],\n ['yo', '', 2],\n ['', 'yo', 2],\n ['yo', 'yo', 0],\n ['tier', 'tor', 2],\n ['saturday', 'sunday', 3],\n ['mist', 'dist', 1],\n ['tier', 'tor', 2],\n ['kitten', 'sitting', 3],\n ['stop', 'tops', 2],\n ['rosettacode', 'raisethysword', 8],\n ['mississippi', 'swiss miss', 8]\n].forEach(function(v) {\n var a = v[0], b = v[1], t = v[2], d = levenshtein(a, b);\n if (d !== t) {\n console.log('levenstein(\"' + a + '\",\"' + b + '\") was ' + d + ' should be ' + t);\n }\n});\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Linear congruential generator", + "type": "Waypoint", + "description": [ + "

The linear congruential generator is a very simple example of a random number generator. All linear congruential generators use this formula:

$r_{n + 1} = a \\times r_n + c \\pmod m$", + "

Where:

$r_0$ is a seed.", + "$r_1$, $r_2$, $r_3$, ..., are the random numbers.", + "$a$, $c$, $m$ are constants.", + "

If one chooses the values of $a$, $c$ and $m$ with care, then the generator produces a uniform distribution of integers from $0$ to $m - 1$.

LCG numbers have poor quality. $r_n$ and $r_{n + 1}$ are not independent, as true random numbers would be. Anyone who knows $r_n$ can predict $r_{n + 1}$, therefore LCG is not cryptographically secure. The LCG is still good enough for simple tasks like Miller-Rabin primality test, or FreeCell deals. Among the benefits of the LCG, one can easily reproduce a sequence of numbers, from the same $r_0$. One can also reproduce such sequence with a different programming language, because the formula is so simple.

The task is to replicate two historic random number generators. One is the rand() function from BSD libc, and the other is the rand() function from the Microsoft C Runtime (MSCVRT.DLL). Each replica must yield the same sequence of integers as the original generator, when starting from the same seed.

In these formulas, the seed becomes $state_0$. The random sequence is $rand_1$, $rand_2$ and so on.

BSD formula:

$state_{n + 1} = 1103515245 \\times state_n + 12345 \\pmod{2^{31}}$", + "$rand_n = state_n$", + "$rand_n$ is in range 0 to 2147483647.", + "

Microsoft formula:

$state_{n + 1} = 214013 \\times state_n + 2531011 \\pmod{2^{31}}$", + "$rand_n = state_n \\div 2^{16}$", + "$rand_n$ is in range 0 to 32767.", + "

The BSD formula was so awful that FreeBSD switched to a different formula. More info is at Random number generator (included)#C.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ee3", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "List comprehensions", + "type": "Waypoint", + "description": [ + "

A list comprehension is a special syntax in some programming languages to describe lists. It is similar to the way mathematicians describe sets, with a set comprehension, hence the name.

Some attributes of a list comprehension are:

", + "They should be distinct from (nested) for loops and the use of map and filter functions within the syntax of the language.", + "They should return either a list or an iterator (something that returns successive members of a collection, in order).", + "The syntax has parts corresponding to that of set-builder notation. Task:", + "

Write a list comprehension that builds the list of all Pythagorean triples with elements between 1 and n.

If the language has multiple ways for expressing such a construct (for example, direct list comprehensions and generators), write one example for each.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "ES5 does not provide built-in notation for list comprehensions. The list monad pattern which underlies list comprehension notation can, however, be used in any language which supports the use of higher order functions. The following shows how we can achieve the same result by directly using a list monad in ES5, without the abbreviating convenience of any specific syntactic sugar. ", + "", + "// USING A LIST MONAD DIRECTLY, WITHOUT SPECIAL SYNTAX FOR LIST COMPREHENSIONS", + "", + "(function (n) {", + "", + " return mb(r(1, n), function (x) { // x <- [1..n]", + " return mb(r(1 + x, n), function (y) { // y <- [1+x..n]", + " return mb(r(1 + y, n), function (z) { // z <- [1+y..n]", + " ", + " return x * x + y * y === z * z ? [[x, y, z]] : [];", + " ", + " })})});", + "", + "", + " // LIBRARY FUNCTIONS", + " ", + " // Monadic bind for lists", + " function mb(xs, f) {", + " return [].concat.apply([], xs.map(f));", + " }", + " ", + " // Monadic return for lists is simply lambda x -> [x]", + " // as in [[x, y, z]] : [] above", + "", + " // Integer range [m..n]", + " function r(m, n) {", + " return Array.apply(null, Array(n - m + 1))", + " .map(function (n, x) {", + " return m + x;", + " });", + " }", + "", + "})(100);", + "", + "Output:", + "", + "
[[3, 4, 5], [5, 12, 13], [6, 8, 10], [7, 24, 25], [8, 15, 17], [9, 12, 15], [9, 40, 41], [10, 24, 26], [11, 60, 61], [12, 16, 20], [12, 35, 37], [13, 84, 85], [14, 48, 50], [15, 20, 25], [15, 36, 39], [16, 30, 34], [16, 63, 65], [18, 24, 30], [18, 80, 82], [20, 21, 29], [20, 48, 52], [21, 28, 35], [21, 72, 75], [24, 32, 40], [24, 45, 51], [24, 70, 74], [25, 60, 65], [27, 36, 45], [28, 45, 53], [28, 96, 100], [30, 40, 50], [30, 72, 78], [32, 60, 68], [33, 44, 55], [33, 56, 65], [35, 84, 91], [36, 48, 60], [36, 77, 85], [39, 52, 65], [39, 80, 89], [40, 42, 58], [40, 75, 85], [42, 56, 70], [45, 60, 75], [48, 55, 73], [48, 64, 80], [51, 68, 85], [54, 72, 90], [57, 76, 95], [60, 63, 87], [60, 80, 100], [65, 72, 97]]
", + "", + "===ES6===", + "{{trans|Python}}", + "", + "{{works with|JavaScript|1.7+ (Firefox 2+)}} {{works with|SpiderMonkey|1.7}}", + "", + "See [https://developer.mozilla.org/en/New_in_JavaScript_1.7#Array_comprehensions here] for more details", + "", + "function range(begin, end) {", + " for (let i = begin; i < end; ++i)", + " yield i;", + "}", + "", + "function triples(n) {", + " return [", + " [x, y, z]", + " for each(x in range(1, n + 1))", + " for each(y in range(x, n + 1))", + " for each(z in range(y, n + 1))", + " if (x * x + y * y == z * z)", + " ]", + "}", + "", + "for each(var triple in triples(20))", + "print(triple);", + "", + "outputs:", + "
3,4,5",
+      "5,12,13",
+      "6,8,10",
+      "8,15,17",
+      "9,12,15",
+      "12,16,20
", + "", + "", + "List comprehension notation was not, in the end, included in the final ES6 standard, and the code above will not run in fully ES6-compliant browsers or interpreters, but we can still go straight to the underlying monadic logic of list comprehensions and obtain: ", + "", + "[ (x, y, z)", + "| x <- [1 .. n], y <- [x .. n], z <- [y .. n], x ^ 2 + y ^ 2 == z ^ 2 ]", + "", + "by using concatMap (the monadic bind function for lists), and x => [x] (monadic pure/return for lists):", + "", + "(n => {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " const enumFromTo = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + "", + " // EXAMPLE ----------------------------------------------------------------", + "", + " // [(x, y, z) | x <- [1..n], y <- [x..n], z <- [y..n], x ^ 2 + y ^ 2 == z ^ 2]", + "", + " return concatMap(x =>", + " concatMap(y =>", + " concatMap(z =>", + "", + " x * x + y * y === z * z ? [", + " [x, y, z]", + " ] : [],", + "", + " enumFromTo(y, n)),", + " enumFromTo(x, n)),", + " enumFromTo(1, n));", + "})(20);", + "{{Out}}", + "[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15], [12, 16, 20]]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ee4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// USING A LIST MONAD DIRECTLY, WITHOUT SPECIAL SYNTAX FOR LIST COMPREHENSIONS\n\n(function (n) {\n\n return mb(r(1, n), function (x) { // x <- [1..n]\n return mb(r(1 + x, n), function (y) { // y <- [1+x..n]\n return mb(r(1 + y, n), function (z) { // z <- [1+y..n]\n \n return x * x + y * y === z * z ? [[x, y, z]] : [];\n \n })})});\n\n\n // LIBRARY FUNCTIONS\n \n // Monadic bind for lists\n function mb(xs, f) {\n return [].concat.apply([], xs.map(f));\n }\n \n // Monadic return for lists is simply lambda x -> [x]\n // as in [[x, y, z]] : [] above\n\n // Integer range [m..n]\n function r(m, n) {\n return Array.apply(null, Array(n - m + 1))\n .map(function (n, x) {\n return m + x;\n });\n }\n\n})(100);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Longest common subsequence", + "type": "Waypoint", + "description": [ + "

The longest common subsequence (or LCS) of groups A and B is the longest group of elements from A and B that are common between the two groups and in the same order in each group. For example, the sequences \"1234\" and \"1224533324\" have an LCS of \"1234\":

", + "

1234

", + "

1224533324

", + "

For a string example, consider the sequences \"thisisatest\" and \"testing123testing\". An LCS would be \"tsitest\":

", + "

thisisatest

", + "

testing123testing

In this puzzle, your code only needs to deal with strings. Write a function which returns an LCS of two strings (case-sensitive). You don't need to show multiple LCS's.

For more information on this problem please see Wikipedia.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===Recursion===", + "{{trans|Java}}", + "This is more or less a translation of the recursive Java version above.", + "function lcs(a, b) {", + " var aSub = a.substr(0, a.length - 1);", + " var bSub = b.substr(0, b.length - 1);", + " ", + " if (a.length === 0 || b.length === 0) {", + " return '';", + " } else if (a.charAt(a.length - 1) === b.charAt(b.length - 1)) {", + " return lcs(aSub, bSub) + a.charAt(a.length - 1);", + " } else {", + " var x = lcs(a, bSub);", + " var y = lcs(aSub, b);", + " return (x.length > y.length) ? x : y;", + " }", + "}", + "", + "ES6 recursive implementation", + "", + "", + "var longest = (xs, ys) => (xs.length > ys.length) ? xs : ys;", + "", + "var lcs = (xx, yy) => {", + " if (!xx.length || !yy.length) { return ''; }", + "", + " var x = xx[0],", + " y = yy[0];", + " xs = xx.slice(1);", + " ys = yy.slice(1);", + "", + " return (x === y) ? lcs(xs, ys) :", + " longest(lcs(xx, ys), lcs(xs, yy));", + "};", + "", + "===Dynamic Programming===", + "This version runs in O(mn) time and consumes O(mn) space.", + "Factoring out loop edge cases could get a small constant time improvement, and it's fairly trivial to edit the final loop to produce a full diff in addition to the lcs.", + "function lcs(x,y){", + "\tvar s,i,j,m,n,", + "\t\tlcs=[],row=[],c=[],", + "\t\tleft,diag,latch;", + "\t//make sure shorter string is the column string", + "\tif(mrow[j]){row[j] = left;}", + "\t\t\t}", + "\t\t}", + "\t}", + "\ti--,j--;", + "\t//row[j] now contains the length of the lcs", + "\t//recover the lcs from the table", + "\twhile(i>-1&&j>-1){", + "\t\tswitch(c[i][j]){", + "\t\t\tdefault: j--;", + "\t\t\t\tlcs.unshift(x[i]);", + "\t\t\tcase (i&&c[i-1][j]): i--;", + "\t\t\t\tcontinue;", + "\t\t\tcase (j&&c[i][j-1]): j--;", + "\t\t}", + "\t}", + "\treturn lcs.join('');", + "}", + "", + "'''BUG note: In line 6, m and n are not yet initialized, and so x and y are never swapped.'''", + "'''Swapping is useless here, and becomes wrong when extending the algorithm to produce a diff.'''", + "", + "The final loop can be modified to concatenate maximal common substrings rather than individual characters:", + "\tvar t=i;", + "\twhile(i>-1&&j>-1){", + "\t\tswitch(c[i][j]){", + "\t\t\tdefault:i--,j--;", + "\t\t\t\tcontinue;", + "\t\t\tcase (i&&c[i-1][j]):", + "\t\t\t\tif(t!==i){lcs.unshift(x.substring(i+1,t+1));}", + "\t\t\t\tt=--i;", + "\t\t\t\tcontinue;", + "\t\t\tcase (j&&c[i][j-1]): j--;", + "\t\t\t\tif(t!==i){lcs.unshift(x.substring(i+1,t+1));}", + "\t\t\t\tt=i;", + "\t\t}", + "\t}", + "\tif(t!==i){lcs.unshift(x.substring(i+1,t+1));}", + "", + "===Greedy Algorithm===", + "This is an heuristic algorithm that won't always return the correct answer, but is significantly faster and less memory intensive than the dynamic programming version, in exchange for giving up the ability to re-use the table to find alternate solutions and greater complexity in generating diffs. Note that this implementation uses a binary buffer for additional efficiency gains, but it's simple to transform to use string or array concatenation;", + "function lcs_greedy(x,y){", + " var p1, i, idx,", + " symbols = {},", + " r = 0,", + " p = 0,", + " l = 0,", + " m = x.length,", + " n = y.length,", + " s = new Buffer((m < n) ? n : m);", + "", + " p1 = popsym(0);", + "", + " for (i = 0; i < m; i++) {", + " p = (r === p) ? p1 : popsym(i);", + " p1 = popsym(i + 1);", + " if (p > p1) {", + " i += 1;", + " idx = p1;", + " } else {", + " idx = p;", + " }", + "", + " if (idx === n) {", + " p = popsym(i);", + " } else {", + " r = idx;", + " s[l] = x.charCodeAt(i);", + " l += 1;", + " }", + " }", + " return s.toString('utf8', 0, l);", + "\t", + " function popsym(index) {", + " var s = x[index],", + " pos = symbols[s] + 1;", + "", + " pos = y.indexOf(s, ((pos > r) ? pos : r));", + " if (pos === -1) { pos = n; }", + " symbols[s] = pos;", + " return pos;", + " }", + "}", + "", + "Note that it won't return the correct answer for all inputs. For example: lcs_greedy('bcaaaade', 'deaaaabc'); // 'bc' instead of 'aaaa'", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ee9", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function lcs(a, b) {\n var aSub = a.substr(0, a.length - 1);\n var bSub = b.substr(0, b.length - 1);\n \n if (a.length === 0 || b.length === 0) {\n return '';\n } else if (a.charAt(a.length - 1) === b.charAt(b.length - 1)) {\n return lcs(aSub, bSub) + a.charAt(a.length - 1);\n } else {\n var x = lcs(a, bSub);\n var y = lcs(aSub, b);\n return (x.length > y.length) ? x : y;\n }\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Longest increasing subsequence", + "type": "Waypoint", + "description": [ + "

Calculate and show here a longest increasing subsequence of the list:

", + "

$\\{3, 2, 6, 4, 5, 1\\}$

", + "

And of the list:

", + "

$\\{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15\\}$

Note that a list may have more than one subsequence that is of the maximum length.

Ref:", + "Dynamic Programming #1: Longest Increasing Subsequence on Youtube", + "An efficient solution can be based on Patience sorting." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{libheader|Lo-Dash underscore library}}", + "", + "", + "", + "var _ = require('underscore');", + "function findIndex(input){", + "\tvar len = input.length;", + "\tvar maxSeqEndingHere = _.range(len).map(function(){return 1;});", + "\tfor(var i=0; i=0;j--)", + "\t\t\tif(input[i] > input[j] && maxSeqEndingHere[j] >= maxSeqEndingHere[i])", + "\t\t\t\tmaxSeqEndingHere[i] = maxSeqEndingHere[j]+1;", + "\treturn maxSeqEndingHere;", + "}", + "", + "function findSequence(input, result){", + "\tvar maxValue = Math.max.apply(null, result);", + "\tvar maxIndex = result.indexOf(Math.max.apply(Math, result));", + "\tvar output = [];", + "\toutput.push(input[maxIndex]);", + "\tfor(var i = maxIndex ; i >= 0; i--){", + "\t\tif(maxValue==0)break;", + "\t\tif(input[maxIndex] > input[i] && result[i] == maxValue-1){", + "\t\t\toutput.push(input[i]);", + "\t\t\tmaxValue--;", + "\t\t}", + "\t}", + "\toutput.reverse();", + "\treturn output;", + "}", + "", + "", + "var x = [0, 7, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15];", + "var y = [3, 2, 6, 4, 5, 1];", + "", + "var result = findIndex(x);", + "var final = findSequence(x, result);", + "console.log(final);", + "", + "var result1 = findIndex(y);", + "var final1 = findSequence(y, result1);", + "console.log(final1);", + "", + "", + "{{out}}", + "
",
+      "[ 0, 2, 6, 9, 11, 15 ]",
+      "[ 2, 4, 5 ]",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eea", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n\nvar _ = require('underscore');\nfunction findIndex(input){\n\tvar len = input.length;\n\tvar maxSeqEndingHere = _.range(len).map(function(){return 1;});\n\tfor(var i=0; i=0;j--)\n\t\t\tif(input[i] > input[j] && maxSeqEndingHere[j] >= maxSeqEndingHere[i])\n\t\t\t\tmaxSeqEndingHere[i] = maxSeqEndingHere[j]+1;\n\treturn maxSeqEndingHere;\n}\n\nfunction findSequence(input, result){\n\tvar maxValue = Math.max.apply(null, result);\n\tvar maxIndex = result.indexOf(Math.max.apply(Math, result));\n\tvar output = [];\n\toutput.push(input[maxIndex]);\n\tfor(var i = maxIndex ; i >= 0; i--){\n\t\tif(maxValue==0)break;\n\t\tif(input[maxIndex] > input[i] && result[i] == maxValue-1){\n\t\t\toutput.push(input[i]);\n\t\t\tmaxValue--;\n\t\t}\n\t}\n\toutput.reverse();\n\treturn output;\n}\n\n\nvar x = [0, 7, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15];\nvar y = [3, 2, 6, 4, 5, 1];\n\nvar result = findIndex(x);\nvar final = findSequence(x, result);\nconsole.log(final);\n\nvar result1 = findIndex(y);\nvar final1 = findSequence(y, result1);\nconsole.log(final1);\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Longest string challenge", + "type": "Waypoint", + "description": [ + "Background:", + "

This \"longest string challenge\" is inspired by a problem that used to be given to students learning Icon. Students were expected to try to solve the problem in Icon and another language with which the student was already familiar. The basic problem is quite simple; the challenge and fun part came through the introduction of restrictions. Experience has shown that the original restrictions required some adjustment to bring out the intent of the challenge and make it suitable for Rosetta Code.

The original programming challenge and some solutions can be found at Unicon Programming TWiki / Longest Strings Puzzle. (See notes on the talk page if you have trouble with the site).

", + "Basic problem statement", + "

Write a program that reads lines from standard input and, upon end of file, writes the longest line to standard output.

", + "

If there are ties for the longest line, the program writes out all the lines that tie.

", + "

If there is no input, the program should produce no output.

", + "Task ", + "

Implement a solution to the basic problem that adheres to the spirit of the restrictions (see below).

Describe how you circumvented or got around these 'restrictions' and met the 'spirit' of the challenge. Your supporting description may need to describe any challenges to interpreting the restrictions and how you made this interpretation. You should state any assumptions, warnings, or other relevant points. The central idea here is to make the task a bit more interesting by thinking outside of the box and perhaps by showing off the capabilities of your language in a creative way. Because there is potential for considerable variation between solutions, the description is key to helping others see what you've done.

This task is likely to encourage a variety of different types of solutions. They should be substantially different approaches.

Given the input:

", + "
",
+      "a",
+      "bb",
+      "ccc",
+      "ddd",
+      "ee",
+      "f",
+      "ggg",
+      "

the output should be (possibly rearranged):

", + "
",
+      "ccc",
+      "ddd",
+      "ggg",
+      "
", + "Original list of restrictionsNo comparison operators may be used.", + "No arithmetic operations, such as addition and subtraction, may be used.", + "The only datatypes you may use are integer and string. In particular, you may not use lists.", + "Do not re-read the input file. Avoid using files as a replacement for lists (this restriction became apparent in the discussion).Intent of restrictions:", + "

Because of the variety of languages on Rosetta Code and the wide variety of concepts used in them, there needs to be a bit of clarification and guidance here to get to the spirit of the challenge and the intent of the restrictions.

The basic problem can be solved very conventionally, but that's boring and pedestrian. The original intent here wasn't to unduly frustrate people with interpreting the restrictions, it was to get people to think outside of their particular box and have a bit of fun doing it.

The guiding principle here should be to be creative in demonstrating some of the capabilities of the programming language being used. If you need to bend the restrictions a bit, explain why and try to follow the intent. If you think you've implemented a 'cheat', call out the fragment yourself and ask readers if they can spot why. If you absolutely can't get around one of the restrictions, explain why in your description.

Now having said that, the restrictions require some elaboration.

In general, the restrictions are meant to avoid the explicit use of these features.", + "\"No comparison operators may be used\" - At some level there must be some test that allows the solution to get at the length and determine if one string is longer. Comparison operators, in particular any less/greater comparison should be avoided. Representing the length of any string as a number should also be avoided. Various approaches allow for detecting the end of a string. Some of these involve implicitly using equal/not-equal; however, explicitly using equal/not-equal should be acceptable.", + "\"No arithmetic operations\" - Again, at some level something may have to advance through the string. Often there are ways a language can do this implicitly advance a cursor or pointer without explicitly using a +, - , ++, --, add, subtract, etc.", + "The datatype restrictions are amongst the most difficult to reinterpret. In the language of the original challenge strings are atomic datatypes and structured datatypes like lists are quite distinct and have many different operations that apply to them. This becomes a bit fuzzier with languages with a different programming paradigm. The intent would be to avoid using an easy structure to accumulate the longest strings and spit them out. There will be some natural reinterpretation here.

To make this a bit more concrete, here are a couple of specific examples:

", + "

In C, a string is an array of chars, so using a couple of arrays as strings is in the spirit while using a second array in a non-string like fashion would violate the intent.

", + "

In APL or J, arrays are the core of the language so ruling them out is unfair. Meeting the spirit will come down to how they are used.

Please keep in mind these are just examples and you may hit new territory finding a solution. There will be other cases like these. Explain your reasoning. You may want to open a discussion on the talk page as well.

", + "The added \"No rereading\" restriction is for practical reasons, re-reading stdin should be broken. I haven't outright banned the use of other files but I've discouraged them as it is basically another form of a list. Somewhere there may be a language that just sings when doing file manipulation and where that makes sense; however, for most there should be a way to accomplish without resorting to an externality.

At the end of the day for the implementer this should be a bit of fun. As an implementer you represent the expertise in your language, the reader may have no knowledge of your language. For the reader it should give them insight into how people think outside the box in other languages. Comments, especially for non-obvious (to the reader) bits will be extremely helpful. While the implementations may be a bit artificial in the context of this task, the general techniques may be useful elsewhere.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eeb", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Long multiplication", + "type": "Waypoint", + "description": [ + "Task:", + "

Explicitly implement long multiplication.

This is one possible approach to arbitrary-precision integer algebra.

", + "

For output, display the result of 264 * 264.

", + "

The decimal representation of 264 is:

", + "

18,446,744,073,709,551,616

The output of 264 * 264 is 2128, and is:

", + "

340,282,366,920,938,463,463,374,607,431,768,211,456

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Iterative===", + "", + "With integer expression inputs at this scale, JavaScript still gives a slightly lossy result, despite the subsequent digit by digit string concatenation approach.", + "", + "The problem is that the JavaScript Math.pow expressions become lossy at around 2^54, and Math.pow(2, 64) evaluates to a rounded:", + "", + "18446744073709552000 rather than the full 18446744073709551616", + "", + "This means that to handle larger inputs, the multiplication function needs to have string parameters:", + "", + "function mult(strNum1,strNum2){", + "", + " var a1 = strNum1.split(\"\").reverse();", + " var a2 = strNum2.toString().split(\"\").reverse();", + " var aResult = new Array;", + " ", + " for ( var iterNum1 = 0; iterNum1 < a1.length; iterNum1++ ) {", + " for ( var iterNum2 = 0; iterNum2 < a2.length; iterNum2++ ) {", + " var idxIter = iterNum1 + iterNum2; // Get the current array position.", + " aResult[idxIter] = a1[iterNum1] * a2[iterNum2] + ( idxIter >= aResult.length ? 0 : aResult[idxIter] );", + " ", + " if ( aResult[idxIter] > 9 ) { // Carrying", + " aResult[idxIter + 1] = Math.floor( aResult[idxIter] / 10 ) + ( idxIter + 1 >= aResult.length ? 0 : aResult[idxIter + 1] );", + " aResult[idxIter] -= Math.floor( aResult[idxIter] / 10 ) * 10;", + " }", + " }", + " }", + " return aResult.reverse().join(\"\");", + "}", + "", + "", + "mult('18446744073709551616', '18446744073709551616')", + "", + "{{Out}}", + "
340282366920938463463374607431768211456
", + "", + "", + "===Functional (ES 5)===", + "", + "The function below accepts integer string or native integer arguments, but as JavaScript (unlike Haskell and Python, for example), lacks an arbitrary precision integer type, larger inputs to this function (beyond the scale of c. 2^54) need to take the form of integer strings, to avoid rounding. ", + "", + "For the same reason, the output always takes the form of an arbitrary precision integer string, rather than a native integer data type. (See the '''largeIntegerString()''' helper function below)", + "", + "(function () {", + " 'use strict';", + "", + " // Javascript lacks an unbounded integer type", + " // so this multiplication function takes and returns", + " // long integer strings rather than any kind of native integer", + "", + " // longMult :: (String | Integer) -> (String | Integer) -> String", + " function longMult(num1, num2) {", + " return largeIntegerString(", + " digitProducts(digits(num1), digits(num2))", + " );", + " }", + "", + " // digitProducts :: [Int] -> [Int] -> [Int]", + " function digitProducts(xs, ys) {", + " return multTable(xs, ys)", + " .map(function (zs, i) {", + " return Array.apply(null, Array(i))", + " .map(function () {", + " return 0;", + " })", + " .concat(zs);", + " })", + " .reduce(function (a, x) {", + " if (a) {", + " var lng = a.length;", + "", + " return x.map(function (y, i) {", + " return y + (i < lng ? a[i] : 0);", + " })", + "", + " } else return x;", + " })", + " }", + "", + " // largeIntegerString :: [Int] -> String", + " function largeIntegerString(lstColumnValues) {", + " var dctProduct = lstColumnValues", + " .reduceRight(function (a, x) {", + " var intSum = x + a.carried,", + " intDigit = intSum % 10;", + "", + " return {", + " digits: intDigit", + " .toString() + a.digits,", + " carried: (intSum - intDigit) / 10", + " };", + " }, {", + " digits: '',", + " carried: 0", + " });", + "", + " return (dctProduct.carried > 0 ? (", + " dctProduct.carried.toString()", + " ) : '') + dctProduct.digits;", + " }", + "", + " // multTables :: [Int] -> [Int] -> [[Int]]", + " function multTable(xs, ys) {", + " return ys.map(function (y) {", + " return xs.map(function (x) {", + " return x * y;", + " })", + " });", + " }", + "", + " // digits :: (Integer | String) -> [Integer]", + " function digits(n) {", + " return (typeof n === 'string' ? n : n.toString())", + " .split('')", + " .map(function (x) {", + " return parseInt(x, 10);", + " });", + " }", + "", + " // TEST showing that larged bounded integer inputs give only rounded results", + " // whereas integer string inputs allow for full precision on this scale (2^128)", + "", + " return {", + " fromIntegerStrings: longMult(", + " '18446744073709551616',", + " '18446744073709551616'", + " ),", + " fromBoundedIntegers: longMult(", + " 18446744073709551616,", + " 18446744073709551616", + " )", + " };", + "})();", + "{{Out}}", + "
{\"fromIntegerStrings\":\"340282366920938463463374607431768211456\", ",
+      "\"fromBoundedIntegers\":\"340282366920938477630474056040704000000\"}
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eec", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function mult(strNum1,strNum2){\n\n var a1 = strNum1.split(\"\").reverse();\n var a2 = strNum2.toString().split(\"\").reverse();\n var aResult = new Array;\n \n for ( var iterNum1 = 0; iterNum1 < a1.length; iterNum1++ ) {\n for ( var iterNum2 = 0; iterNum2 < a2.length; iterNum2++ ) {\n var idxIter = iterNum1 + iterNum2; // Get the current array position.\n aResult[idxIter] = a1[iterNum1] * a2[iterNum2] + ( idxIter >= aResult.length ? 0 : aResult[idxIter] );\n \n if ( aResult[idxIter] > 9 ) { // Carrying\n aResult[idxIter + 1] = Math.floor( aResult[idxIter] / 10 ) + ( idxIter + 1 >= aResult.length ? 0 : aResult[idxIter + 1] );\n aResult[idxIter] -= Math.floor( aResult[idxIter] / 10 ) * 10;\n }\n }\n }\n return aResult.reverse().join(\"\");\n}\n\n\nmult('18446744073709551616', '18446744073709551616')\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Look-and-say sequence", + "type": "Waypoint", + "description": [ + "

The Look and say sequence is a recursively defined sequence of numbers studied most notably by John Conway.

", + "

Sequence Definition

", + "Take a decimal number", + "Look at the number, visually grouping consecutive runs of the same digit.", + "Say the number, from left to right, group by group; as how many of that digit there are - followed by the digit grouped. This becomes the next number of the sequence.", + "

An example:

", + "Starting with the number 1, you have one 1 which produces 11", + "Starting with 11, you have two 1's. I.E.: 21", + "Starting with 21, you have one 2, then one 1. I.E.: (12)(11) which becomes 1211", + "Starting with 1211, you have one 1, one 2, then two 1's. I.E.: (11)(12)(21) which becomes 111221Task:", + "

Write a program to generate successive members of the look-and-say sequence.

", + "See also:", + " Look-and-Say Numbers (feat John Conway), A Numberphile Video.", + " This task is related to, and an application of, the Run-length encoding task.", + " Sequence A005150 on The On-Line Encyclopedia of Integer Sequences." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{trans|Perl}}", + "function lookandsay(str) {", + " return str.replace(/(.)\\1*/g, function(seq, p1){return seq.length.toString() + p1})", + "}", + "", + "var num = \"1\";", + "for (var i = 10; i > 0; i--) {", + " alert(num);", + " num = lookandsay(num);", + "}", + "", + "Without RegExp", + "", + "function lookSay(digits) {", + " var result = '',", + " chars = (digits + ' ').split(''),", + " lastChar = chars[0],", + " times = 0;", + " ", + " chars.forEach(function(nextChar) {", + " if (nextChar === lastChar) {", + " times++;", + " }", + " else {", + " result += (times + '') + lastChar;", + " lastChar = nextChar;", + " times = 1;", + " }", + " });", + " ", + " return result;", + "}", + "", + "(function output(seed, iterations) {", + " for (var i = 0; i < iterations; i++) {", + " console.log(seed);", + " seed = lookSay(seed);", + " }", + "})(\"1\", 10);", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eed", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function lookandsay(str) {\n return str.replace(/(.)\\1*/g, function(seq, p1){return seq.length.toString() + p1})\n}\n\nvar num = \"1\";\nfor (var i = 10; i > 0; i--) {\n alert(num);\n num = lookandsay(num);\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Loop over multiple arrays simultaneously", + "type": "Waypoint", + "description": [ + "Task:", + "

Loop over multiple arrays (or lists or tuples or whatever they're called in

", + "

your language) and display the i th element of each.

Use your language's \"for each\" loop if it has one, otherwise iterate

", + "

through the collection in order with some other loop.

", + "

For this example, loop over the arrays:

", + "

(a,b,c)

", + "

(A,B,C)

", + "

(1,2,3)

", + "

to produce the output:

", + "

aA1

", + "

bB2

", + "

cC3

", + "

If possible, also describe what happens when the arrays are of different lengths.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Imperative===", + "This loops over the indices of the first array, ", + "and uses that to index into the others.", + "var a = [\"a\",\"b\",\"c\"],", + " b = [\"A\",\"B\",\"C\"],", + " c = [1,2,3],", + " output = \"\",", + " i;", + "for (i = 0; i < a.length; i += 1) {", + " output += a[i] + b[i] + c[i] + \"\\n\";", + "}", + "If the b or c arrays are too \"short\", ", + "you will see the string \"undefined\" appear in the output.", + "", + "Alternatively, we can nest a couple of calls to '''.forEach()''': one for the array of three arrays, and one for each of the three index positions:", + "", + "var lstOut = ['', '', ''];", + "", + "[[\"a\", \"b\", \"c\"], [\"A\", \"B\", \"C\"], [\"1\", \"2\", \"3\"]].forEach(", + " function (a) {", + " [0, 1, 2].forEach(", + " function (i) {", + " // side-effect on an array outside the function", + " lstOut[i] += a[i];", + " }", + " );", + " }", + ");", + "", + "// lstOut --> [\"aA1\", \"bB2\", \"cC3\"]", + "", + "===Functional (ES5)===", + "", + "Functional options include folding across an array of arrays with the built-in '''Array.reduce()''',", + "using a zipWith() function of suitable arity, or mapping over the output of a generic (any arity) zip() function.", + "", + "(The generic zip function is the most tolerant – it simply ignores further elements in any arrays which are longer than the shortest array).", + "", + "Reduce / fold:", + "", + "(function (lstArrays) {", + "", + " return lstArrays.reduce(", + " function (a, e) {", + " return [", + " a[0] + e[0],", + " a[1] + e[1],", + " a[2] + e[2]", + " ];", + " }, ['', '', ''] // initial copy of the accumulator", + " ).join('\\n');", + "", + "})([", + " [\"a\", \"b\", \"c\"],", + " [\"A\", \"B\", \"C\"],", + " [\"1\", \"2\", \"3\"]", + "]);", + "", + "A fixed arity ZipWith:", + "", + "(function (x, y, z) {", + "", + " // function of arity 3 mapped over nth items of each of 3 lists", + " // (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]", + " function zipWith3(f, xs, ys, zs) {", + " return zs.length ? [f(xs[0], ys[0], zs[0])].concat(", + " zipWith3(f, xs.slice(1), ys.slice(1), zs.slice(1))) : [];", + " }", + "", + " function concat(x, y, z) {", + " return ''.concat(x, y, z);", + " }", + "", + " return zipWith3(concat, x, y, z).join('\\n')", + "", + "})([\"a\", \"b\", \"c\"], [\"A\", \"B\", \"C\"], [1, 2, 3]);", + "", + "", + "Or we can write a generic '''zipListsWith''' which applies some supplied function overs lists derived from the nth members of an arbitrary list of (equal-length) lists.", + "", + "(function () {", + " 'use strict';", + "", + " // zipListsWith :: ([a] -> b) -> [[a]] -> [[b]]", + " function zipListsWith(f, xss) {", + " return (xss.length ? xss[0] : [])", + " .map(function (_, i) {", + " return f(xss.map(function (xs) {", + " return xs[i];", + " }));", + " });", + " }", + "", + "", + "", + "", + " // Sample function over a list", + "", + " // concat :: [a] -> s", + " function concat(lst) {", + " return ''.concat.apply('', lst);", + " }", + "", + "", + " // TEST", + " ", + " return zipListsWith(", + " concat, ", + " [[\"a\", \"b\", \"c\"], [\"A\", \"B\", \"C\"], [1, 2, 3]]", + " )", + " .join('\\n');", + "", + "})();", + "", + "{{Out}}", + "", + "aA1", + "bB2", + "cC3", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eee", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var a = [\"a\",\"b\",\"c\"],\n b = [\"A\",\"B\",\"C\"],\n c = [1,2,3],\n output = \"\",\n i;\nfor (i = 0; i < a.length; i += 1) {\n output += a[i] + b[i] + c[i] + \"\\n\";\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Loops/Do-while", + "type": "Waypoint", + "description": [ + "

Start with a value at 0. Loop while value mod 6 is not equal to 0.

", + "

Each time through the loop, add 1 to the value then print it.

", + "

The loop must execute at least once.

Reference:", + "Do while loop Wikipedia." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Javascript: Imperative===", + "var val = 0;", + "do {", + " print(++val);", + "} while (val % 6);", + "", + "===Javascript: Functional===", + "====ES5====", + "In a functional idiom of JavaScript we cannot use a Do While '''statement''', as it returns no value and is not a composable expression. We can, however achieve the same effect with a composable doWhile '''function''', which takes three arguments, and returns the output series as a value.", + "", + ":#An initial value,", + ":#a Do function which transforms that value repetitively, corresponding to the body of the loop,", + ":#and a conditional While function.", + "", + "function doWhile(varValue, fnBody, fnTest) {", + " 'use strict';", + " var d = fnBody(varValue); // a transformed value", + "", + " return fnTest(d) ? [d].concat(", + " doWhile(d, fnBody, fnTest)", + " ) : [d];", + "}", + "", + "console.log(", + " doWhile(0, // initial value", + " function (x) { // Do body, returning transformed value", + " return x + 1;", + " },", + " function (x) { // While condition", + " return x % 6;", + " }", + " ).join('\\n')", + "); ", + "", + "Output:", + "1", + "2", + "3", + "4", + "5", + "6 ", + "", + "Alternatively, if we assume instead that the unstated problem was not to produce repetitive computation, but to derive the '''membership of a set''' we could interpret the task as a request for a JavaScript implementation of the '''takeWhile''' function – a familiar staple of functional list processing.", + "", + "So, for example, something like:", + "", + "function range(m, n) {", + " 'use strict';", + " return Array.apply(null, Array(n - m + 1)).map(", + " function (x, i) {", + " return m + i;", + " }", + " );", + "}", + " ", + "function takeWhile(lst, fnTest) {", + " 'use strict';", + " var varHead = lst.length ? lst[0] : null;", + " ", + " return varHead ? (", + " fnTest(varHead) ? [varHead].concat(", + " takeWhile(lst.slice(1), fnTest)", + " ) : []", + " ) : []", + "}", + " ", + "console.log(", + " takeWhile(", + " range(1, 100),", + " function (x) {", + " return x % 6;", + " }", + " ).join('\\n')", + "); ", + "", + "Output:", + "1", + "2", + "3", + "4", + "5", + "", + "====ES6====", + "", + "A process or value of this kind might be better expressed (in functionally composed JavaScript) with an '''unfold''' or '''until''' function, returning a list.", + "", + "(() => {", + " 'use strict';", + "", + " // unfoldr :: (b -> Maybe (a, b)) -> b -> [a]", + " function unfoldr(mf, v) {", + " for (var lst = [], a = v, m;", + " (m = mf(a)) && m.valid;) {", + " lst.push(m.value), a = m.new;", + " }", + " return lst;", + " }", + "", + " // until :: (a -> Bool) -> (a -> a) -> a -> a", + " function until(p, f, x) {", + " let v = x;", + " while(!p(v)) v = f(v);", + " return v;", + " }", + "", + " let result1 = unfoldr(", + " x => {", + " return {", + " value: x,", + " valid: (x % 6) !== 0,", + " new: x + 1", + " }", + " },", + " 1", + " );", + "", + " let result2 = until(", + " m => (m.n % 6) === 0,", + " m => {", + " return {", + " n : m.n + 1,", + " xs : m.xs.concat(m.n)", + " };", + " },", + " {", + " n: 1,", + " xs: []", + " }", + " ).xs;", + " ", + " return [result1, result2];", + "})();", + "", + "", + "", + "[[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ef1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var val = 0;\ndo {\n print(++val);\n} while (val % 6);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Loops/Nested", + "type": "Waypoint", + "description": [ + "

Show a nested loop which searches a two-dimensional array filled with random numbers uniformly distributed over $[1,\\ldots,20]$.

The loops iterate rows and columns of the array printing the elements until the value $20$ is met.

Specifically, this task also shows how to break out of nested loops.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Demonstrates use of break with a label.", + "Uses print() function from [[Rhino]].", + "// a \"random\" 2-D array ", + "var a = [[2, 12, 10, 4], [18, 11, 9, 3], [14, 15, 7, 17], [6, 19, 8, 13], [1, 20, 16, 5]];", + "", + "outer_loop:", + "for (var i in a) {", + " print(\"row \" + i);", + " for (var j in a[i]) {", + " print(\" \" + a[i][j]);", + " if (a[i][j] == 20) ", + " break outer_loop;", + " }", + "}", + "print(\"done\");", + "", + "In a functional idiom of JavaScript, however, we can not use a loop statement, as statements return no value and can not be composed within other functional expressions. Functional JavaScript often replaces a loop with a map or fold. In this case, we can achieve the same task by defining the standard list-processing function '''takeWhile''', which terminates when a condition returns true.", + "", + "We can then search the groups in the nested array by nesting takeWhile inside itself, and finally terminate when the 20 is found by one further application of takeWhile.", + "", + "Using the same data as above, and returning the trail of numbers up to twenty from a nested and composable expression:", + "", + "var lst = [[2, 12, 10, 4], [18, 11, 9, 3], [14, 15, 7, 17], [6, 19, 8, 13], [1,", + " 20, 16, 5]];", + "", + "var takeWhile = function (lst, fnTest) {", + " 'use strict';", + " var varHead = lst.length ? lst[0] : null;", + "", + " return varHead ? (", + " fnTest(varHead) ? [varHead].concat(", + " takeWhile(lst.slice(1), fnTest)", + " ) : []", + " ) : []", + " },", + "", + " // The takeWhile function terminates when notTwenty(n) returns false", + " notTwenty = function (n) {", + " return n !== 20;", + " },", + "", + " // Leftward groups containing no 20", + " // takeWhile nested within takeWhile", + " lstChecked = takeWhile(lst, function (group) {", + " return takeWhile(", + " group,", + " notTwenty", + " ).length === 4;", + " });", + "", + "", + "// Return the trail of numbers preceding 20 from a composable expression", + "", + "console.log(", + " // Numbers before 20 in a group in which it was found", + " lstChecked.concat(", + " takeWhile(", + " lst[lstChecked.length], notTwenty", + " )", + " )", + " // flattened", + " .reduce(function (a, x) {", + " return a.concat(x);", + " }).join('\\n')", + "); ", + "", + "Output:", + "2", + "12", + "10", + "4", + "18", + "11", + "9", + "3", + "14", + "15", + "7", + "17", + "6", + "19", + "8", + "13", + "6", + "19", + "8", + "13", + "1", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ef7", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// a \"random\" 2-D array \nvar a = [[2, 12, 10, 4], [18, 11, 9, 3], [14, 15, 7, 17], [6, 19, 8, 13], [1, 20, 16, 5]];\n\nouter_loop:\nfor (var i in a) {\n print(\"row \" + i);\n for (var j in a[i]) {\n print(\" \" + a[i][j]);\n if (a[i][j] == 20) \n break outer_loop;\n }\n}\nprint(\"done\");\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Lucas-Lehmer test", + "type": "Waypoint", + "description": [ + "

Lucas-Lehmer Test: for $p$ an odd prime, the Mersenne number $2^p-1$ is prime if and only if $2^p-1$ divides $S(p-1)$ where $S(n+1)=(S(n))^2-2$, and $S(1)=4$.

", + "Task:", + "

Calculate all Mersenne primes up to the implementation's

", + "

maximum precision, or the 47th Mersenne prime (whichever comes first).

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7efa", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "LU decomposition", + "type": "Waypoint", + "description": [ + "

Every square matrix $A$ can be decomposed into a product of a lower triangular matrix $L$ and a upper triangular matrix $U$,

", + "

as described in LU decomposition.

$A = LU$

It is a modified form of Gaussian elimination.

", + "

While the Cholesky decomposition only works for symmetric,

", + "

positive definite matrices, the more general LU decomposition

", + "

works for any square matrix.

There are several algorithms for calculating L and U.

", + "

To derive Crout's algorithm for a 3x3 example,

", + "

we have to solve the following system:

$

", + "

A =

", + "

\\begin{pmatrix}

", + "

a_{11} & a_{12} & a_{13}\\\\

", + "

a_{21} & a_{22} & a_{23}\\\\

", + "

a_{31} & a_{32} & a_{33}\\\\

", + "

\\end{pmatrix}

", + "

=

", + "

\\begin{pmatrix}

", + "

l_{11} & 0 & 0 \\\\

", + "

l_{21} & l_{22} & 0 \\\\

", + "

l_{31} & l_{32} & l_{33}\\\\

", + "

\\end{pmatrix}

", + "

\\begin{pmatrix}

", + "

u_{11} & u_{12} & u_{13} \\\\

", + "

0 & u_{22} & u_{23} \\\\

", + "

0 & 0 & u_{33}

", + "

\\end{pmatrix}

", + "

= LU

", + "

$

We now would have to solve 9 equations with 12 unknowns. To make the system uniquely solvable, usually the diagonal elements of $L$ are set to 1

$l_{11}=1$

", + "

$l_{22}=1$

", + "

$l_{33}=1$

so we get a solvable system of 9 unknowns and 9 equations.

$

", + "

A =

", + "

\\begin{pmatrix}

", + "

a_{11} & a_{12} & a_{13}\\\\

", + "

a_{21} & a_{22} & a_{23}\\\\

", + "

a_{31} & a_{32} & a_{33}\\\\

", + "

\\end{pmatrix}

", + "

=

", + "

\\begin{pmatrix}

", + "

1 & 0 & 0 \\\\

", + "

l_{21} & 1 & 0 \\\\

", + "

l_{31} & l_{32} & 1\\\\

", + "

\\end{pmatrix}

", + "

\\begin{pmatrix}

", + "

u_{11} & u_{12} & u_{13} \\\\

", + "

0 & u_{22} & u_{23} \\\\

", + "

0 & 0 & u_{33}

", + "

\\end{pmatrix}

", + "

=

", + "

\\begin{pmatrix}

", + "

u_{11} & u_{12} & u_{13} \\\\

", + "

u_{11}l_{21} & u_{12}l_{21}+u_{22} & u_{13}l_{21}+u_{23} \\\\

", + "

u_{11}l_{31} & u_{12}l_{31}+u_{22}l_{32} & u_{13}l_{31} + u_{23}l_{32}+u_{33}

", + "

\\end{pmatrix}

", + "

= LU

", + "

$

Solving for the other $l$ and $u$, we get the following equations:

$u_{11}=a_{11}$

", + "

$u_{12}=a_{12}$

", + "

$u_{13}=a_{13}$

$u_{22}=a_{22} - u_{12}l_{21}$

", + "

$u_{23}=a_{23} - u_{13}l_{21}$

$u_{33}=a_{33} - (u_{13}l_{31} + u_{23}l_{32})$

and for $l$:

$l_{21}=\\frac{1}{u_{11}} a_{21}$

", + "

$l_{31}=\\frac{1}{u_{11}} a_{31}$

$l_{32}=\\frac{1}{u_{22}} (a_{32} - u_{12}l_{31})$

We see that there is a calculation pattern, which can be expressed as the following formulas, first for $U$

$u_{ij} = a_{ij} - \\sum_{k=1}^{i-1} u_{kj}l_{ik}$

and then for $L$

$l_{ij} = \\frac{1}{u_{jj}} (a_{ij} - \\sum_{k=1}^{j-1} u_{kj}l_{ik})$

We see in the second formula that to get the $l_{ij}$ below the diagonal, we have to divide by the diagonal element (pivot) $u_{jj}$, so we get problems when $u_{jj}$ is either 0 or very small, which leads to numerical instability.

The solution to this problem is pivoting $A$, which means rearranging the rows of $A$, prior to the $LU$ decomposition, in a way that the largest element of each column gets onto the diagonal of $A$. Rearranging the rows means to multiply $A$ by a permutation matrix $P$:

$PA \\Rightarrow A'$

Example:

$

", + "

\\begin{pmatrix}

", + "

0 & 1 \\\\

", + "

1 & 0

", + "

\\end{pmatrix}

", + "

\\begin{pmatrix}

", + "

1 & 4 \\\\

", + "

2 & 3

", + "

\\end{pmatrix}

", + "

\\Rightarrow

", + "

\\begin{pmatrix}

", + "

2 & 3 \\\\

", + "

1 & 4

", + "

\\end{pmatrix}

", + "

$

The decomposition algorithm is then applied on the rearranged matrix so that

$PA = LU$

", + "

Task description

The task is to implement a routine which will take a square nxn matrix $A$ and return a lower triangular matrix $L$, a upper triangular matrix $U$ and a permutation matrix $P$,

", + "

so that the above equation is fullfilled.

", + "

You should then test it on the following two examples and include your output.

Example 1:

", + "
",
+      "A1   3   5",
+      "2   4   7",
+      "1   1   0L1.00000   0.00000   0.00000",
+      "0.50000   1.00000   0.00000",
+      "0.50000  -1.00000   1.00000U2.00000   4.00000   7.00000",
+      "0.00000   1.00000   1.50000",
+      "0.00000   0.00000  -2.00000P0   1   0",
+      "1   0   0",
+      "0   0   1",
+      "

Example 2:

", + "
",
+      "A11    9   24    2",
+      " 1    5    2    6",
+      " 3   17   18    1",
+      " 2    5    7    1L1.00000   0.00000   0.00000   0.00000",
+      "0.27273   1.00000   0.00000   0.00000",
+      "0.09091   0.28750   1.00000   0.00000",
+      "0.18182   0.23125   0.00360   1.00000U11.00000    9.00000   24.00000    2.00000",
+      " 0.00000   14.54545   11.45455    0.45455",
+      " 0.00000    0.00000   -3.47500    5.68750",
+      " 0.00000    0.00000    0.00000    0.51079P1   0   0   0",
+      "0   0   1   0",
+      "0   1   0   0",
+      "0   0   0   1",
+      "
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7efb", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Ludic numbers", + "type": "Waypoint", + "description": [ + "

Ludic numbers are related to prime numbers as they are generated by a sieve quite like the Sieve of Eratosthenes is used to generate prime numbers.

The first ludic number is 1.

To generate succeeding ludic numbers create an array of increasing integers starting from 2.

", + "

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

", + "

(Loop)

", + "Take the first member of the resultant array as the next ludic number 2.", + "Remove every 2nd indexed item from the array (including the first).: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 ...", + "(Unrolling a few loops...)", + "Take the first member of the resultant array as the next ludic number 3.", + "Remove every 3rd indexed item from the array (including the first).:3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 ...", + "Take the first member of the resultant array as the next ludic number 5.", + "Remove every 5th indexed item from the array (including the first).:5 7 11 13 17 19 23 25 29 31 35 37 41 43 47 49 53 55 59 61 65 67 71 73 77 ...", + "Take the first member of the resultant array as the next ludic number 7.", + "Remove every 7th indexed item from the array (including the first).:7 11 13 17 23 25 29 31 37 41 43 47 53 55 59 61 67 71 73 77 83 85 89 91 97 ...", + " ... ", + "Take the first member of the current array as the next ludic number L.", + "Remove every Lth indexed item from the array (including the first).", + " ... ", + "Task:", + "Generate and show here the first 25 ludic numbers.", + "How many ludic numbers are there less than or equal to 1000?", + "Show the 2000..2005th ludic numbers.", + "Stretch goal:", + "

Show all triplets of ludic numbers < 250.

", + "A triplet is any three numbers $x,$ $x+2,$ $x+6$ where all three numbers are also ludic numbers. " + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "/**", + " * Boilerplate to simply get an array filled between 2 numbers", + " * @param {!number} s Start here (inclusive)", + " * @param {!number} e End here (inclusive)", + " */", + "const makeArr = (s, e) => new Array(e + 1 - s).fill(s).map((e, i) => e + i);", + "", + "/**", + " * Remove every n-th element from the given array", + " * @param {!Array} arr", + " * @param {!number} n", + " * @return {!Array}", + " */", + "const filterAtInc = (arr, n) => arr.filter((e, i) => (i + 1) % n);", + "", + "/**", + " * Generate ludic numbers", + " * @param {!Array} arr", + " * @param {!Array} result", + " * @return {!Array}", + " */", + "const makeLudic = (arr, result) => {", + " const iter = arr.shift();", + " result.push(iter);", + " return arr.length ? makeLudic(filterAtInc(arr, iter), result) : result;", + "};", + "", + "/**", + " * Our Ludic numbers. This is a bit of a cheat, as we already know beforehand", + " * up to where our seed array needs to go in order to exactly get to the", + " * 2005th Ludic number.", + " * @type {!Array}", + " */", + "const ludicResult = makeLudic(makeArr(2, 21512), [1]);", + "", + "", + "// Below is just logging out the results.", + "/**", + " * Given a number, return a function that takes an array, and return the", + " * count of all elements smaller than the given", + " * @param {!number} n", + " * @return {!Function}", + " */", + "const smallerThanN = n => arr => {", + " return arr.reduce((p,c) => {", + " return c <= n ? p + 1 : p", + " }, 0)", + "};", + "const smallerThan1K = smallerThanN(1000);", + "", + "console.log('\\nFirst 25 Ludic Numbers:');", + "console.log(ludicResult.filter((e, i) => i < 25).join(', '));", + "", + "console.log('\\nTotal Ludic numbers smaller than 1000:');", + "console.log(smallerThan1K(ludicResult));", + "", + "console.log('\\nThe 2000th to 2005th ludic numbers:');", + "console.log(ludicResult.filter((e, i) => i > 1998).join(', '));", + "", + "console.log('\\nTriplets smaller than 250:');", + "ludicResult.forEach(e => {", + " if (e + 6 < 250 && ludicResult.indexOf(e + 2) > 0 && ludicResult.indexOf(e + 6) > 0) {", + " console.log([e, e + 2, e + 6].join(', '));", + " }", + "});", + "", + "
",
+      "First 25 Ludic Numbers:",
+      "1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107",
+      "",
+      "Total Ludic numbers smaller than 1000:",
+      "142",
+      "",
+      "The 2000th to 2005th ludic numbers:",
+      "21475, 21481, 21487, 21493, 21503, 21511",
+      "",
+      "Triplets smaller than 250:",
+      "1, 3, 7",
+      "5, 7, 11",
+      "11, 13, 17",
+      "23, 25, 29",
+      "41, 43, 47",
+      "173, 175, 179",
+      "221, 223, 227",
+      "233, 235, 239",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7efc", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "/**\n * Boilerplate to simply get an array filled between 2 numbers\n * @param {!number} s Start here (inclusive)\n * @param {!number} e End here (inclusive)\n */\nconst makeArr = (s, e) => new Array(e + 1 - s).fill(s).map((e, i) => e + i);\n\n/**\n * Remove every n-th element from the given array\n * @param {!Array} arr\n * @param {!number} n\n * @return {!Array}\n */\nconst filterAtInc = (arr, n) => arr.filter((e, i) => (i + 1) % n);\n\n/**\n * Generate ludic numbers\n * @param {!Array} arr\n * @param {!Array} result\n * @return {!Array}\n */\nconst makeLudic = (arr, result) => {\n const iter = arr.shift();\n result.push(iter);\n return arr.length ? makeLudic(filterAtInc(arr, iter), result) : result;\n};\n\n/**\n * Our Ludic numbers. This is a bit of a cheat, as we already know beforehand\n * up to where our seed array needs to go in order to exactly get to the\n * 2005th Ludic number.\n * @type {!Array}\n */\nconst ludicResult = makeLudic(makeArr(2, 21512), [1]);\n\n\n// Below is just logging out the results.\n/**\n * Given a number, return a function that takes an array, and return the\n * count of all elements smaller than the given\n * @param {!number} n\n * @return {!Function}\n */\nconst smallerThanN = n => arr => {\n return arr.reduce((p,c) => {\n return c <= n ? p + 1 : p\n }, 0)\n};\nconst smallerThan1K = smallerThanN(1000);\n\nconsole.log('\\nFirst 25 Ludic Numbers:');\nconsole.log(ludicResult.filter((e, i) => i < 25).join(', '));\n\nconsole.log('\\nTotal Ludic numbers smaller than 1000:');\nconsole.log(smallerThan1K(ludicResult));\n\nconsole.log('\\nThe 2000th to 2005th ludic numbers:');\nconsole.log(ludicResult.filter((e, i) => i > 1998).join(', '));\n\nconsole.log('\\nTriplets smaller than 250:');\nludicResult.forEach(e => {\n if (e + 6 < 250 && ludicResult.indexOf(e + 2) > 0 && ludicResult.indexOf(e + 6) > 0) {\n console.log([e, e + 2, e + 6].join(', '));\n }\n});\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Luhn test of credit card numbers", + "type": "Waypoint", + "description": [ + "

The Luhn test is used by some credit card companies to distinguish valid credit card numbers from what could be a random selection of digits.

Those companies using credit card numbers that can be validated by the Luhn test have numbers that pass the following test:

", + " Reverse the order of the digits in the number.", + " Take the first, third, ... and every other odd digit in the reversed digits and sum them to form the partial sum s1", + " Taking the second, fourth ... and every other even digit in the reversed digits:# Multiply each digit by two and sum the digits if the answer is greater than nine to form partial sums for the even digits", + "

# Sum the partial sums of the even digits to form s2

", + "If s1 + s2 ends in zero then the original number is in the form of a valid credit card number as verified by the Luhn test.", + "

For example, if the trial number is 49927398716:

", + "
Reverse the digits:",
+      "  61789372994",
+      "Sum the odd digits:",
+      "  6 + 7 + 9 + 7 + 9 + 4 = 42 = s1",
+      "The even digits:",
+      "    1,  8,  3,  2,  9",
+      "  Two times each even digit:",
+      "    2, 16,  6,  4, 18",
+      "  Sum the digits of each multiplication:",
+      "    2,  7,  6,  4,  9",
+      "  Sum the last:",
+      "    2 + 7 + 6 + 4 + 9 = 28 = s2s1 + s2 = 70 which ends in zero which means that 49927398716 passes the Luhn test
", + "Task:", + "

Write a function/method/procedure/subroutine that will validate a number with the Luhn test, and

", + "use it to validate the following numbers:", + "

49927398716

", + "

49927398717

", + "

1234567812345678

", + "

1234567812345670

", + "Related tasks:", + " SEDOL", + " ISIN" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Using prototype.", + "mod10check = function(cc) {", + " return $A(cc).reverse().map(Number).inject(0, function(s, d, i) {", + " return s + (i % 2 == 1 ? (d == 9 ? 9 : (d * 2) % 9) : d);", + " }) % 10 == 0;", + "};", + "['49927398716','49927398717','1234567812345678','1234567812345670'].each(function(i){alert(mod10check(i))});", + "", + "Without any library.", + "var LuhnCheck = (function()", + "{", + "\tvar luhnArr = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9];", + "\treturn function(str)", + "\t{", + "\t\tvar counter = 0;", + "\t\tvar incNum;", + "\t\tvar odd = false;", + "\t\tvar temp = String(str).replace(/[^\\d]/g, \"\");", + "\t\tif ( temp.length == 0)", + "\t\t\treturn false;", + "\t\tfor (var i = temp.length-1; i >= 0; --i)", + "\t\t{", + "\t\t\tincNum = parseInt(temp.charAt(i), 10);", + "\t\t\tcounter += (odd = !odd)? incNum : luhnArr[incNum];", + "\t\t}", + "\t\treturn (counter%10 == 0);", + "\t}", + "})();", + "ES5.1 version (uses 'reduce' and 'reduceRight' Array methods).", + "function luhn(str){", + "\treturn str.split('').reduceRight(function(prev, curr, idx){", + "\t\tprev = parseInt(prev, 10);", + "\t\tif ((idx + 1) % 2 !== 0) {", + "\t\t\tcurr = (curr * 2).toString().split('').reduce(function(p, c){ return parseInt(p, 10) + parseInt(c, 10)});", + "\t\t}", + "\t\treturn prev + parseInt(curr, 10);", + "\t}) % 10 === 0;", + "}", + "", + "Highly compressed version.", + "var luhn10 = function(a,b,c,d,e) {", + " for(d = +a[b = a.length-1], e=0; b--;)", + " c = +a[b], d += ++e % 2 ? 2 * c % 10 + (c > 4) : c;", + " return !(d%10)", + "};", + "", + "// returns true", + "luhn10('4111111111111111') ", + "", + "// returns false", + "luhn10('4111111111111112') ", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7efd", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "mod10check = function(cc) {\n return $A(cc).reverse().map(Number).inject(0, function(s, d, i) {\n return s + (i % 2 == 1 ? (d == 9 ? 9 : (d * 2) % 9) : d);\n }) % 10 == 0;\n};\n['49927398716','49927398717','1234567812345678','1234567812345670'].each(function(i){alert(mod10check(i))});\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Lychrel numbers", + "type": "Waypoint", + "description": [ + "Take an integer n, greater than zero.", + "Form the next n of its series by reversing the digits of the current n and adding the result to the current n.", + "Stop when n becomes palindromic - i.e. the digits of n in reverse order == n.", + "

The above recurrence relation when applied to most starting numbers n = 1, 2, ... terminates in a palindrome quite quickly, for example if n0 = 12 we get

", + "
12",
+      "12 + 21 = 33, a palindrome!

And if n0 = 55 we get

", + "
55",
+      "55 + 55 = 110",
+      "110 + 011 = 121, a palindrome!

Notice that the check for a palindrome happens after an addition.

", + "

Some starting numbers seem to go on forever; the recurrence relation for 196 has been calculated for millions of repetitions forming numbers with millions of digits, without forming a palindrome. These numbers that do not end in a palindrome are called Lychrel numbers.

For the purposes of this task a Lychrel number is any starting number that does not form a palindrome within 500 (or more) iterations.

", + "Seed and related Lychrel numbers:", + "

Any integer produced in the sequence of a Lychrel number is also a Lychrel number.

In general, any sequence from one Lychrel number might converge to join the sequence from a prior Lychrel number candidate; for example the sequences for the numbers 196 and then 689 begin:

", + "
196",
+      "196 + 691 = 887",
+      "887 + 788 = 1675",
+      "1675 + 5761 = 7436",
+      "7436 + 6347 = 13783",
+      "13783 + 38731 = 52514",
+      "52514 + 41525 = 94039",
+      "...",
+      "689",
+      "689 + 986 = 1675",
+      "1675 + 5761 = 7436",
+      "...
", + "

So we see that the sequence starting with 689 converges to, and continues with the same numbers as that for 196. Because of this we can further split the Lychrel numbers into true Seed Lychrel number candidates, and Related numbers that produce no palindromes but have integers in their sequence seen as part of the sequence generated from a lower Lychrel number.

", + "Task:", + " Find the number of seed Lychrel number candidates and related numbers for n in the range 1..10000 inclusive. (With that iteration limit of 500).", + " Print the number of seed Lychrels found; the actual seed Lychrels; and just the number of relateds found.", + " Print any seed Lychrel or related number that is itself a palindrome.", + "

Show all output here.

", + "References:", + "What's special about 196? Numberphile video.", + "A023108 Positive integers which apparently never result in a palindrome under repeated applications of the function f(x) = x + (x with digits reversed).", + "Status of the 196 conjecture? Mathoverflow." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7efe", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "LZW compression", + "type": "Waypoint", + "description": [ + "

The Lempel-Ziv-Welch (LZW) algorithm provides loss-less data compression.

You can read a complete description of it in the Wikipedia article on the subject. It was patented, but it entered the public domain in 2004.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "//LZW Compression/Decompression for Strings", + "var LZW = {", + " compress: function (uncompressed) {", + " \"use strict\";", + " // Build the dictionary.", + " var i,", + " dictionary = {},", + " c,", + " wc,", + " w = \"\",", + " result = [],", + " dictSize = 256;", + " for (i = 0; i < 256; i += 1) {", + " dictionary[String.fromCharCode(i)] = i;", + " }", + "", + " for (i = 0; i < uncompressed.length; i += 1) {", + " c = uncompressed.charAt(i);", + " wc = w + c;", + " //Do not use dictionary[wc] because javascript arrays ", + " //will return values for array['pop'], array['push'] etc", + " // if (dictionary[wc]) {", + " if (dictionary.hasOwnProperty(wc)) {", + " w = wc;", + " } else {", + " result.push(dictionary[w]);", + " // Add wc to the dictionary.", + " dictionary[wc] = dictSize++;", + " w = String(c);", + " }", + " }", + "", + " // Output the code for w.", + " if (w !== \"\") {", + " result.push(dictionary[w]);", + " }", + " return result;", + " },", + "", + "", + " decompress: function (compressed) {", + " \"use strict\";", + " // Build the dictionary.", + " var i,", + " dictionary = [],", + " w,", + " result,", + " k,", + " entry = \"\",", + " dictSize = 256;", + " for (i = 0; i < 256; i += 1) {", + " dictionary[i] = String.fromCharCode(i);", + " }", + "", + " w = String.fromCharCode(compressed[0]);", + " result = w;", + " for (i = 1; i < compressed.length; i += 1) {", + " k = compressed[i];", + " if (dictionary[k]) {", + " entry = dictionary[k];", + " } else {", + " if (k === dictSize) {", + " entry = w + w.charAt(0);", + " } else {", + " return null;", + " }", + " }", + "", + " result += entry;", + "", + " // Add w+entry[0] to the dictionary.", + " dictionary[dictSize++] = w + entry.charAt(0);", + "", + " w = entry;", + " }", + " return result;", + " }", + "}, // For Test Purposes", + " comp = LZW.compress(\"TOBEORNOTTOBEORTOBEORNOT\"),", + " decomp = LZW.decompress(comp);", + "document.write(comp + '
' + decomp);
", + "", + "{{out}}", + "
84,79,66,69,79,82,78,79,84,256,258,260,265,259,261,263",
+      "TOBEORNOTTOBEORTOBEORNOT
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7eff", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "//LZW Compression/Decompression for Strings\nvar LZW = {\n compress: function (uncompressed) {\n \"use strict\";\n // Build the dictionary.\n var i,\n dictionary = {},\n c,\n wc,\n w = \"\",\n result = [],\n dictSize = 256;\n for (i = 0; i < 256; i += 1) {\n dictionary[String.fromCharCode(i)] = i;\n }\n\n for (i = 0; i < uncompressed.length; i += 1) {\n c = uncompressed.charAt(i);\n wc = w + c;\n //Do not use dictionary[wc] because javascript arrays \n //will return values for array['pop'], array['push'] etc\n // if (dictionary[wc]) {\n if (dictionary.hasOwnProperty(wc)) {\n w = wc;\n } else {\n result.push(dictionary[w]);\n // Add wc to the dictionary.\n dictionary[wc] = dictSize++;\n w = String(c);\n }\n }\n\n // Output the code for w.\n if (w !== \"\") {\n result.push(dictionary[w]);\n }\n return result;\n },\n\n\n decompress: function (compressed) {\n \"use strict\";\n // Build the dictionary.\n var i,\n dictionary = [],\n w,\n result,\n k,\n entry = \"\",\n dictSize = 256;\n for (i = 0; i < 256; i += 1) {\n dictionary[i] = String.fromCharCode(i);\n }\n\n w = String.fromCharCode(compressed[0]);\n result = w;\n for (i = 1; i < compressed.length; i += 1) {\n k = compressed[i];\n if (dictionary[k]) {\n entry = dictionary[k];\n } else {\n if (k === dictSize) {\n entry = w + w.charAt(0);\n } else {\n return null;\n }\n }\n\n result += entry;\n\n // Add w+entry[0] to the dictionary.\n dictionary[dictSize++] = w + entry.charAt(0);\n\n w = entry;\n }\n return result;\n }\n}, // For Test Purposes\n comp = LZW.compress(\"TOBEORNOTTOBEORTOBEORNOT\"),\n decomp = LZW.decompress(comp);\ndocument.write(comp + '
' + decomp);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Magic squares of doubly even order", + "type": "Waypoint", + "description": [ + "

A magic square is an NxN square matrix whose numbers consist of consecutive numbers arranged so that the sum of each row and column, and both diagonals are equal to the same sum (which is called the magic number or magic constant).

A magic square of doubly even order has a size that is a multiple of four (e.g. 4, 8, 12). This means that the subsquares also have an even size, which plays a role in the construction.

", + "

{| style=\"float:right;border: 2px solid black; background:lightblue; color:black; margin-left:auto;margin-right:auto;text-align:center;width:22em;height:15em;table-layout:fixed;font-size:100%\"

", + "

|-

", + "

|1||2||62||61||60||59||7||8

", + "

|-

", + "

|9||10||54||53||52||51||15||16

", + "

|-

", + "

|48||47||19||20||21||22||42||41

", + "

|-

", + "

|40||39||27||28||29||30||34||33

", + "

|-

", + "

|32||31||35||36||37||38||26||25

", + "

|-

", + "

|24||23||43||44||45||46||18||17

", + "

|-

", + "

|49||50||14||13||12||11||55||56

", + "

|-

", + "

|57||58||6||5||4||3||63||64

", + "

|}

", + "Task", + "

Create a magic square of 8 x 8.

", + " Related tasks", + "Magic squares of odd order", + "Magic squares of singly even order", + " See also:", + "Doubly Even Magic Squares (1728.org)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // doubleEvenMagicSquare :: Int -> [[Int]]", + " const doubleEvenMagicSquare = n => {", + " if (n % 4 > 0) return undefined;", + "", + " // truthSeries :: Int -> [Int]", + " const truthSeries = n => {", + " if (n <= 0) return [true];", + " const xs = truthSeries(n - 1);", + " return xs.concat(xs.map(x => !x));", + " };", + "", + " const sqr = n * n,", + " scale = curry(replicate)(n / 4),", + " power = Math.log2(sqr),", + " sequence = isInt(power) ? truthSeries(power) : (", + " flatten(", + " scale(", + " splitEvery(4, truthSeries(4))", + " .map(scale)", + " )", + " )", + " );", + "", + " return splitEvery(n, sequence", + " .map((x, i) => x ? i + 1 : sqr - i));", + " };", + "", + "", + " // GENERIC FUNCTIONS ----------------------------------------------------", + "", + " // flatten :: Tree a -> [a]", + " const flatten = t => (t instanceof Array ? concatMap(flatten, t) : [t]);", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // splitEvery :: Int -> [a] -> [][a]]", + " const splitEvery = (n, xs) => {", + " if (xs.length <= n) return [xs];", + " const [h, t] = [xs.slice(0, n), xs.slice(n)];", + " return [h].concat(splitEvery(n, t));", + " }", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " const curry = f => a => b => f(a, b);", + "", + " // replicate :: Int -> a -> [a]", + " const replicate = (n, a) => {", + " let v = [a],", + " o = [];", + " if (n < 1) return o;", + " while (n > 1) {", + " if (n & 1) o = o.concat(v);", + " n >>= 1;", + " v = v.concat(v);", + " }", + " return o.concat(v);", + " };", + "", + " // isInt :: Int -> Bool", + " const isInt = x => x === Math.floor(x);", + "", + "", + " // TEST AND DISPLAY FUNCTIONS -------------------------------------------", + "", + " // transpose :: [[a]] -> [[a]]", + " const transpose = xs =>", + " xs[0].map((_, iCol) => xs.map((row) => row[iCol]));", + "", + " // diagonals :: [[a]] -> ([a], [a])", + " const diagonals = xs => {", + " const nRows = xs.length,", + " nCols = (nRows > 0 ? xs[0].length : 0);", + " const cell = (x, y) => xs[y][x];", + "", + " if (nRows === nCols) {", + " const ns = range(0, nCols - 1);", + " return [zipWith(cell, ns, ns), zipWith(cell, ns, reverse(ns))];", + " } else return [", + " [],", + " []", + " ];", + " };", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) => {", + " const ny = ys.length;", + " return (xs.length <= ny ? xs : xs.slice(0, ny))", + " .map((x, i) => f(x, ys[i]));", + " }", + "", + " // reverse :: [a] -> [a]", + " const reverse = (xs) => xs.slice(0)", + " .reverse()", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // all :: (a -> Bool) -> [a] -> Bool", + " const all = (f, xs) => xs.every(f);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x);", + "", + " // justifyRight :: Int -> Char -> Text -> Text", + " const justifyRight = (n, cFiller, strText) =>", + " n > strText.length ? (", + " (cFiller.repeat(n) + strText)", + " .slice(-n)", + " ) : strText;", + "", + " // TEST -----------------------------------------------------------------", + "", + " //return doubleEvenMagicSquare(8)", + "", + " return [4, 8, 12]", + " .map(n => {", + " const lines = doubleEvenMagicSquare(n);", + " const sums = lines.concat(", + " transpose(lines)", + " .concat(diagonals(lines))", + " )", + " .map(xs => xs.reduce((a, b) => a + b, 0));", + " const sum = sums[0];", + " return [", + " \"Order: \" + n.toString(),", + " \"Summing to: \" + sum.toString(),", + " \"Row, column and diagonal sums checked: \" +", + " all(x => x === sum, sums)", + " .toString() + '\\n',", + " lines.map(", + " xs => xs.map(", + " x => justifyRight(3, ' ', x.toString())", + " )", + " .join(' '))", + " .join('\\n')", + " ].join('\\n')", + " })", + " .join('\\n\\n');", + "})();", + "", + "{{Out}}", + "
Order: 4",
+      "Summing to: 34",
+      "Row, column and diagonal sums checked: true",
+      "",
+      "  1   15   14    4",
+      " 12    6    7    9",
+      "  8   10   11    5",
+      " 13    3    2   16",
+      "",
+      "Order: 8",
+      "Summing to: 260",
+      "Row, column and diagonal sums checked: true",
+      "",
+      "  1   63   62    4   60    6    7   57",
+      " 56   10   11   53   13   51   50   16",
+      " 48   18   19   45   21   43   42   24",
+      " 25   39   38   28   36   30   31   33",
+      " 32   34   35   29   37   27   26   40",
+      " 41   23   22   44   20   46   47   17",
+      " 49   15   14   52   12   54   55    9",
+      "  8   58   59    5   61    3    2   64",
+      "",
+      "Order: 12",
+      "Summing to: 870",
+      "Row, column and diagonal sums checked: true",
+      "",
+      "  1  143  142    4    5  139  138    8    9  135  134   12",
+      "132   14   15  129  128   18   19  125  124   22   23  121",
+      "120   26   27  117  116   30   31  113  112   34   35  109",
+      " 37  107  106   40   41  103  102   44   45   99   98   48",
+      " 49   95   94   52   53   91   90   56   57   87   86   60",
+      " 84   62   63   81   80   66   67   77   76   70   71   73",
+      " 72   74   75   69   68   78   79   65   64   82   83   61",
+      " 85   59   58   88   89   55   54   92   93   51   50   96",
+      " 97   47   46  100  101   43   42  104  105   39   38  108",
+      " 36  110  111   33   32  114  115   29   28  118  119   25",
+      " 24  122  123   21   20  126  127   17   16  130  131   13",
+      "133   11   10  136  137    7    6  140  141    3    2  144
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f03", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // doubleEvenMagicSquare :: Int -> [[Int]]\n const doubleEvenMagicSquare = n => {\n if (n % 4 > 0) return undefined;\n\n // truthSeries :: Int -> [Int]\n const truthSeries = n => {\n if (n <= 0) return [true];\n const xs = truthSeries(n - 1);\n return xs.concat(xs.map(x => !x));\n };\n\n const sqr = n * n,\n scale = curry(replicate)(n / 4),\n power = Math.log2(sqr),\n sequence = isInt(power) ? truthSeries(power) : (\n flatten(\n scale(\n splitEvery(4, truthSeries(4))\n .map(scale)\n )\n )\n );\n\n return splitEvery(n, sequence\n .map((x, i) => x ? i + 1 : sqr - i));\n };\n\n\n // GENERIC FUNCTIONS ----------------------------------------------------\n\n // flatten :: Tree a -> [a]\n const flatten = t => (t instanceof Array ? concatMap(flatten, t) : [t]);\n\n // concatMap :: (a -> [b]) -> [a] -> [b]\n const concatMap = (f, xs) => [].concat.apply([], xs.map(f));\n\n // splitEvery :: Int -> [a] -> [][a]]\n const splitEvery = (n, xs) => {\n if (xs.length <= n) return [xs];\n const [h, t] = [xs.slice(0, n), xs.slice(n)];\n return [h].concat(splitEvery(n, t));\n }\n\n // curry :: ((a, b) -> c) -> a -> b -> c\n const curry = f => a => b => f(a, b);\n\n // replicate :: Int -> a -> [a]\n const replicate = (n, a) => {\n let v = [a],\n o = [];\n if (n < 1) return o;\n while (n > 1) {\n if (n & 1) o = o.concat(v);\n n >>= 1;\n v = v.concat(v);\n }\n return o.concat(v);\n };\n\n // isInt :: Int -> Bool\n const isInt = x => x === Math.floor(x);\n\n\n // TEST AND DISPLAY FUNCTIONS -------------------------------------------\n\n // transpose :: [[a]] -> [[a]]\n const transpose = xs =>\n xs[0].map((_, iCol) => xs.map((row) => row[iCol]));\n\n // diagonals :: [[a]] -> ([a], [a])\n const diagonals = xs => {\n const nRows = xs.length,\n nCols = (nRows > 0 ? xs[0].length : 0);\n const cell = (x, y) => xs[y][x];\n\n if (nRows === nCols) {\n const ns = range(0, nCols - 1);\n return [zipWith(cell, ns, ns), zipWith(cell, ns, reverse(ns))];\n } else return [\n [],\n []\n ];\n };\n\n // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]\n const zipWith = (f, xs, ys) => {\n const ny = ys.length;\n return (xs.length <= ny ? xs : xs.slice(0, ny))\n .map((x, i) => f(x, ys[i]));\n }\n\n // reverse :: [a] -> [a]\n const reverse = (xs) => xs.slice(0)\n .reverse()\n\n // range :: Int -> Int -> [Int]\n const range = (m, n) =>\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i);\n\n // all :: (a -> Bool) -> [a] -> Bool\n const all = (f, xs) => xs.every(f);\n\n // show :: a -> String\n const show = x => JSON.stringify(x);\n\n // justifyRight :: Int -> Char -> Text -> Text\n const justifyRight = (n, cFiller, strText) =>\n n > strText.length ? (\n (cFiller.repeat(n) + strText)\n .slice(-n)\n ) : strText;\n\n // TEST -----------------------------------------------------------------\n\n //return doubleEvenMagicSquare(8)\n\n return [4, 8, 12]\n .map(n => {\n const lines = doubleEvenMagicSquare(n);\n const sums = lines.concat(\n transpose(lines)\n .concat(diagonals(lines))\n )\n .map(xs => xs.reduce((a, b) => a + b, 0));\n const sum = sums[0];\n return [\n \"Order: \" + n.toString(),\n \"Summing to: \" + sum.toString(),\n \"Row, column and diagonal sums checked: \" +\n all(x => x === sum, sums)\n .toString() + '\\n',\n lines.map(\n xs => xs.map(\n x => justifyRight(3, ' ', x.toString())\n )\n .join(' '))\n .join('\\n')\n ].join('\\n')\n })\n .join('\\n\\n');\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Magic squares of odd order", + "type": "Waypoint", + "description": [ + "

A magic square is an NxN square matrix whose numbers (usually integers) consist of consecutive numbers arranged so that the sum of each row and column, and both long (main) diagonals are equal to the same sum (which is called the magic number or magic constant).

The numbers are usually (but not always) the first N2 positive integers.

A magic square whose rows and columns add up to a magic number but whose main diagonals do not, is known as a semimagic square.

{| style=\"float:right;border: 4px solid blue; background:lightgreen; color:black; margin-left:auto;margin-right:auto;text-align:center;width:15em;height:15em;table-layout:fixed;font-size:150%\"

", + "

|-

", + "

| 8 || 1 || 6

", + "

|-

", + "

| 3 || 5 || 7

", + "

|-

", + "

| 4 || 9 || 2

", + "

|}

", + "Task

For any odd N, generate a magic square with the integers 1 ──► N, and show the results here.

Optionally, show the magic number.

You should demonstrate the generator by showing at least a magic square for N = 5.

", + " Related tasks", + "Magic squares of singly even order", + "Magic squares of doubly even order See also:", + "MathWorld™ entry: Magic_square ", + "Odd Magic Squares (1728.org)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "{{trans|Mathematica}}", + "( and referring to http://www.jsoftware.com/papers/eem/magicsq.htm )", + "", + "(function () {", + "", + " // n -> [[n]]", + " function magic(n) {", + " return n % 2 ? rotation(", + " transposed(", + " rotation(", + " table(n)", + " )", + " )", + " ) : null;", + " }", + "", + " // [[a]] -> [[a]]", + " function rotation(lst) {", + " return lst.map(function (row, i) {", + " return rotated(", + " row, ((row.length + 1) / 2) - (i + 1)", + " );", + " })", + " }", + "", + " // [[a]] -> [[a]]", + " function transposed(lst) {", + " return lst[0].map(function (col, i) {", + " return lst.map(function (row) {", + " return row[i];", + " })", + " });", + " }", + "", + " // [a] -> n -> [a]", + " function rotated(lst, n) {", + " var lng = lst.length,", + " m = (typeof n === 'undefined') ? 1 : (", + " n < 0 ? lng + n : (n > lng ? n % lng : n)", + " );", + "", + " return m ? (", + " lst.slice(-m).concat(lst.slice(0, lng - m))", + " ) : lst;", + " }", + "", + " // n -> [[n]]", + " function table(n) {", + " var rngTop = rng(1, n);", + "", + " return rng(0, n - 1).map(function (row) {", + " return rngTop.map(function (x) {", + " return row * n + x;", + " });", + " });", + " }", + "", + " // [m..n]", + " function rng(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(", + " function (x, i) {", + " return m + i;", + " });", + " }", + "", + " /******************** TEST WITH 3, 5, 11 ***************************/", + "", + " // Results as right-aligned wiki tables", + " function wikiTable(lstRows, blnHeaderRow, strStyle) {", + " var css = strStyle ? 'style=\"' + strStyle + '\"' : '';", + "", + " return '{| class=\"wikitable\" ' + css + lstRows.map(", + " function (lstRow, iRow) {", + " var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|'),", + " strDbl = strDelim + strDelim;", + "", + " return '\\n|-\\n' + strDelim + ' ' + lstRow.join(' ' + strDbl + ' ');", + " }).join('') + '\\n|}';", + " }", + "", + " return [3, 5, 11].map(", + " function (n) {", + " var w = 2.5 * n;", + " return 'magic(' + n + ')\\n\\n' + wikiTable(", + " magic(n), false, 'text-align:center;width:' + w + 'em;height:' + w + 'em;table-layout:fixed;'", + " )", + " }", + " ).join('\\n\\n')", + "})();", + "", + "Output:", + "", + "magic(3)", + "", + "{| class=\"wikitable\" style=\"text-align:center;width:7.5em;height:7.5em;table-layout:fixed;\"", + "|-", + "| 8 || 3 || 4", + "|-", + "| 1 || 5 || 9", + "|-", + "| 6 || 7 || 2", + "|}", + "", + "magic(5)", + "", + "{| class=\"wikitable\" style=\"text-align:center;width:12.5em;height:12.5em;table-layout:fixed;\"", + "|-", + "| 17 || 23 || 4 || 10 || 11", + "|-", + "| 24 || 5 || 6 || 12 || 18", + "|-", + "| 1 || 7 || 13 || 19 || 25", + "|-", + "| 8 || 14 || 20 || 21 || 2", + "|-", + "| 15 || 16 || 22 || 3 || 9", + "|}", + "", + "magic(11)", + "", + "{| class=\"wikitable\" style=\"text-align:center;width:27.5em;height:27.5em;table-layout:fixed;\"", + "|-", + "| 68 || 80 || 92 || 104 || 116 || 7 || 19 || 31 || 43 || 55 || 56", + "|-", + "| 81 || 93 || 105 || 117 || 8 || 20 || 32 || 44 || 45 || 57 || 69", + "|-", + "| 94 || 106 || 118 || 9 || 21 || 33 || 34 || 46 || 58 || 70 || 82", + "|-", + "| 107 || 119 || 10 || 22 || 23 || 35 || 47 || 59 || 71 || 83 || 95", + "|-", + "| 120 || 11 || 12 || 24 || 36 || 48 || 60 || 72 || 84 || 96 || 108", + "|-", + "| 1 || 13 || 25 || 37 || 49 || 61 || 73 || 85 || 97 || 109 || 121", + "|-", + "| 14 || 26 || 38 || 50 || 62 || 74 || 86 || 98 || 110 || 111 || 2", + "|-", + "| 27 || 39 || 51 || 63 || 75 || 87 || 99 || 100 || 112 || 3 || 15", + "|-", + "| 40 || 52 || 64 || 76 || 88 || 89 || 101 || 113 || 4 || 16 || 28", + "|-", + "| 53 || 65 || 77 || 78 || 90 || 102 || 114 || 5 || 17 || 29 || 41", + "|-", + "| 66 || 67 || 79 || 91 || 103 || 115 || 6 || 18 || 30 || 42 || 54", + "|}", + "", + "===ES6===", + "====Cycled . transposed . cycled====", + "{{Trans|Haskell}} ", + "", + "(2nd Haskell version: ''cycledRows . transpose . cycledRows'')", + "(() => {", + "", + " // magicSquare :: Int -> [[Int]]", + " const magicSquare = n =>", + " n % 2 !== 0 ? (", + " compose([transpose, cycled, transpose, cycled, enumSquare])(n)", + " ) : [];", + "", + " // Size of square -> rows containing integers [1..]", + " // enumSquare :: Int -> [[Int]]", + " const enumSquare = n =>", + " chunksOf(n, enumFromTo(1, n * n));", + "", + " // Table of integers -> Table with rows rotated by descending deltas", + " // cycled :: [[Int]] -> [[Int]]", + " const cycled = rows => {", + " const d = Math.floor(rows.length / 2);", + " return zipWith(listCycle, enumFromTo(d, -d), rows)", + " };", + "", + " // Number of positions to shift to right -> List -> Wrap-cycled list", + " // listCycle :: Int -> [a] -> [a]", + " const listCycle = (n, xs) => {", + " const d = -(n % xs.length);", + " return (d !== 0 ? xs.slice(d)", + " .concat(xs.slice(0, d)) : xs);", + " };", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // chunksOf :: Int -> [a] -> [[a]]", + " const chunksOf = (n, xs) =>", + " xs.reduce((a, _, i, xs) =>", + " i % n ? a : a.concat([xs.slice(i, i + n)]), []);", + "", + " // compose :: [(a -> a)] -> (a -> a)", + " const compose = fs => x => fs.reduceRight((a, f) => f(a), x);", + "", + " // enumFromTo :: Int -> Int -> Maybe Int -> [Int]", + " const enumFromTo = (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));", + " };", + "", + " // intercalate :: String -> [a] -> String", + " const intercalate = (s, xs) => xs.join(s);", + "", + " // min :: Ord a => a -> a -> a", + " const min = (a, b) => b < a ? b : a;", + "", + " // show :: a -> String", + " const show = JSON.stringify;", + "", + " // transpose :: [[a]] -> [[a]]", + " const transpose = xs =>", + " xs[0].map((_, iCol) => xs.map(row => row[iCol]));", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) =>", + " Array.from({", + " length: min(xs.length, ys.length)", + " }, (_, i) => f(xs[i], ys[i]));", + "", + " // TEST -------------------------------------------------------------------", + " return intercalate('\\n\\n', [3, 5, 7]", + " .map(magicSquare)", + " .map(xs => unlines(xs.map(show))));", + "})();", + "{{Out}}", + "
[8,1,6]",
+      "[3,5,7]",
+      "[4,9,2]",
+      "",
+      "[17,24,1,8,15]",
+      "[23,5,7,14,16]",
+      "[4,6,13,20,22]",
+      "[10,12,19,21,3]",
+      "[11,18,25,2,9]",
+      "",
+      "[30,39,48,1,10,19,28]",
+      "[38,47,7,9,18,27,29]",
+      "[46,6,8,17,26,35,37]",
+      "[5,14,16,25,34,36,45]",
+      "[13,15,24,33,42,44,4]",
+      "[21,23,32,41,43,3,12]",
+      "[22,31,40,49,2,11,20]
", + "", + "====Traditional 'Siamese' method====", + "Encoding the traditional [[wp:Siamese_method|'Siamese' method]]", + "{{Trans|Haskell}}", + "(() => {", + "", + " // Number of rows -> n rows of integers", + " // oddMagicTable :: Int -> [[Int]]", + " const oddMagicTable = n =>", + " mapAsTable(n, siamMap(quot(n, 2)));", + "", + " // Highest index of square -> Siam xys so far -> xy -> next xy coordinate", + " // nextSiam :: Int -> M.Map (Int, Int) Int -> (Int, Int) -> (Int, Int)", + " const nextSiam = (uBound, sMap, [x, y]) => {", + " const [a, b] = [x + 1, y - 1];", + " return (a > uBound && b < 0) ? (", + " [uBound, 1] // Move down if obstructed by corner", + " ) : a > uBound ? (", + " [0, b] // Wrap at right edge", + " ) : b < 0 ? (", + " [a, uBound] // Wrap at upper edge", + " ) : mapLookup(sMap, [a, b])", + " .nothing ? ( // Unimpeded default: one up one right", + " [a, b]", + " ) : [a - 1, b + 2]; // Position occupied: move down", + " };", + "", + " // Order of table -> Siamese indices keyed by coordinates", + " // siamMap :: Int -> M.Map (Int, Int) Int", + " const siamMap = n => {", + " const", + " uBound = 2 * n,", + " sPath = (uBound, sMap, xy, n) => {", + " const [x, y] = xy,", + " newMap = mapInsert(sMap, xy, n);", + " return (y == uBound && x == quot(uBound, 2) ? (", + " newMap", + " ) : sPath(", + " uBound, newMap, nextSiam(uBound, newMap, [x, y]), n + 1));", + " };", + " return sPath(uBound, {}, [n, 0], 1);", + " };", + "", + " // Size of square -> integers keyed by coordinates -> rows of integers", + " // mapAsTable :: Int -> M.Map (Int, Int) Int -> [[Int]]", + " const mapAsTable = (nCols, dct) => {", + " const axis = enumFromTo(0, nCols - 1);", + " return map(row => map(k => fromJust(mapLookup(dct, k)), row),", + " bind(axis, y => [bind(axis, x => [", + " [x, y]", + " ])]));", + " };", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // bind :: [a] -> (a -> [b]) -> [b]", + " const bind = (xs, f) => [].concat.apply([], xs.map(f));", + "", + " // curry :: Function -> Function", + " const curry = (f, ...args) => {", + " const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :", + " function () {", + " return go(xs.concat(Array.from(arguments)));", + " };", + " return go([].slice.call(args, 1));", + " };", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " const enumFromTo = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // fromJust :: M a -> a", + " const fromJust = m => m.nothing ? {} : m.just;", + "", + " // fst :: [a, b] -> a", + " const fst = pair => pair.length === 2 ? pair[0] : undefined;", + "", + " // intercalate :: String -> [a] -> String", + " const intercalate = (s, xs) => xs.join(s);", + "", + " // justifyRight :: Int -> Char -> Text -> Text", + " const justifyRight = (n, cFiller, strText) =>", + " n > strText.length ? (", + " (cFiller.repeat(n) + strText)", + " .slice(-n)", + " ) : strText;", + "", + " // length :: [a] -> Int", + " const length = xs => xs.length;", + "", + " // log :: a -> IO ()", + " const log = (...args) =>", + " console.log(", + " args", + " .map(show)", + " .join(' -> ')", + " );", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // mapInsert :: Dictionary -> k -> v -> Dictionary", + " const mapInsert = (dct, k, v) =>", + " (dct[(typeof k === 'string' && k) || show(k)] = v, dct);", + "", + " // mapKeys :: Map k a -> [k]", + " const mapKeys = dct =>", + " sortBy(mappendComparing([snd, fst]),", + " map(JSON.parse, Object.keys(dct)));", + "", + " // mapLookup :: Dictionary -> k -> Maybe v", + " const mapLookup = (dct, k) => {", + " const", + " v = dct[(typeof k === 'string' && k) || show(k)],", + " blnJust = (typeof v !== 'undefined');", + " return {", + " nothing: !blnJust,", + " just: v", + " };", + " };", + "", + " // mappendComparing :: [(a -> b)] -> (a -> a -> Ordering)", + " const mappendComparing = fs => (x, y) =>", + " fs.reduce((ord, f) => {", + " if (ord !== 0) return ord;", + " const", + " a = f(x),", + " b = f(y);", + " return a < b ? -1 : a > b ? 1 : 0", + " }, 0);", + "", + " // maximum :: [a] -> a", + " const maximum = xs =>", + " xs.reduce((a, x) => (x > a || a === undefined ? x : a), undefined);", + "", + " // Integral a => a -> a -> a", + " const quot = (n, m) => Math.floor(n / m);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x);", + " //", + " // snd :: (a, b) -> b", + " const snd = tpl => Array.isArray(tpl) ? tpl[1] : undefined;", + " //", + " // sortBy :: (a -> a -> Ordering) -> [a] -> [a]", + " const sortBy = (f, xs) => xs.slice()", + " .sort(f);", + "", + " // table :: String -> [[String]] -> [String]", + " const table = (delim, rows) =>", + " map(curry(intercalate)(delim),", + " transpose(map(col =>", + " map(curry(justifyRight)(maximum(map(length, col)))(' '), col),", + " transpose(rows))));", + "", + " // transpose :: [[a]] -> [[a]]", + " const transpose = xs =>", + " xs[0].map((_, col) => xs.map(row => row[col]));", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // TEST -------------------------------------------------------------------", + "", + " return intercalate('\\n\\n',", + " bind([3, 5, 7],", + " n => unlines(table(\" \",", + " map(xs => map(show, xs), oddMagicTable(n))))));", + "})();", + "{{Out}}", + "
8  1  6",
+      "3  5  7",
+      "4  9  2",
+      "",
+      "17  24   1   8  15",
+      "23   5   7  14  16",
+      " 4   6  13  20  22",
+      "10  12  19  21   3",
+      "11  18  25   2   9",
+      "",
+      "30  39  48   1  10  19  28",
+      "38  47   7   9  18  27  29",
+      "46   6   8  17  26  35  37",
+      " 5  14  16  25  34  36  45",
+      "13  15  24  33  42  44   4",
+      "21  23  32  41  43   3  12",
+      "22  31  40  49   2  11  20
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f04", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function () {\n\n // n -> [[n]]\n function magic(n) {\n return n % 2 ? rotation(\n transposed(\n rotation(\n table(n)\n )\n )\n ) : null;\n }\n\n // [[a]] -> [[a]]\n function rotation(lst) {\n return lst.map(function (row, i) {\n return rotated(\n row, ((row.length + 1) / 2) - (i + 1)\n );\n })\n }\n\n // [[a]] -> [[a]]\n function transposed(lst) {\n return lst[0].map(function (col, i) {\n return lst.map(function (row) {\n return row[i];\n })\n });\n }\n\n // [a] -> n -> [a]\n function rotated(lst, n) {\n var lng = lst.length,\n m = (typeof n === 'undefined') ? 1 : (\n n < 0 ? lng + n : (n > lng ? n % lng : n)\n );\n\n return m ? (\n lst.slice(-m).concat(lst.slice(0, lng - m))\n ) : lst;\n }\n\n // n -> [[n]]\n function table(n) {\n var rngTop = rng(1, n);\n\n return rng(0, n - 1).map(function (row) {\n return rngTop.map(function (x) {\n return row * n + x;\n });\n });\n }\n\n // [m..n]\n function rng(m, n) {\n return Array.apply(null, Array(n - m + 1)).map(\n function (x, i) {\n return m + i;\n });\n }\n\n /******************** TEST WITH 3, 5, 11 ***************************/\n\n // Results as right-aligned wiki tables\n function wikiTable(lstRows, blnHeaderRow, strStyle) {\n var css = strStyle ? 'style=\"' + strStyle + '\"' : '';\n\n return '{| class=\"wikitable\" ' + css + lstRows.map(\n function (lstRow, iRow) {\n var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|'),\n strDbl = strDelim + strDelim;\n\n return '\\n|-\\n' + strDelim + ' ' + lstRow.join(' ' + strDbl + ' ');\n }).join('') + '\\n|}';\n }\n\n return [3, 5, 11].map(\n function (n) {\n var w = 2.5 * n;\n return 'magic(' + n + ')\\n\\n' + wikiTable(\n magic(n), false, 'text-align:center;width:' + w + 'em;height:' + w + 'em;table-layout:fixed;'\n )\n }\n ).join('\\n\\n')\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Magic squares of singly even order", + "type": "Waypoint", + "description": [ + "

A magic square is an NxN square matrix whose numbers consist of consecutive numbers arranged so that the sum of each row and column, and both diagonals are equal to the same sum (which is called the magic number or magic constant).

A magic square of singly even order has a size that is a multiple of 4, plus 2 (e.g. 6, 10, 14). This means that the subsquares have an odd size, which plays a role in the construction.

", + "Task", + "

Create a magic square of 6 x 6.

", + " Related tasks", + "Magic squares of odd order", + "Magic squares of doubly even order", + " See also", + "Singly Even Magic Squares (1728.org)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f05", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Main step of GOST 28147-89", + "type": "Waypoint", + "description": [ + "

GOST 28147-89 is a standard symmetric encryption based on a Feistel network. Structure of the algorithm consists of three levels:

encryption modes - simple replacement, application range, imposing a range of feedback and authentication code generation;", + "cycles - 32-З, 32-Р and 16-З, is a repetition of the main step;", + "main step, a function that takes a 64-bit block of text and one of the eight 32-bit encryption key elements, and uses the replacement table (8x16 matrix of 4-bit values), and returns encrypted block.", + "

Implement the main step of this encryption algorithm.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var Таблица_замен = [", + " [ 4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3],", + " [14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9],", + " [ 5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11],", + " [ 7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3],", + " [ 6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2],", + " [ 4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14],", + " [13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12],", + " [ 1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12]];", + "", + "function ОсновнойШаг(блок_текста, элемент_ключа) {", + " var N = блок_текста.slice(0);", + " var X = элемент_ключа;", + " var S = (N[0] + X) & 0xFFFFFFFF;", + " var ячейка; var нов_S = 0;", + " for (var сч = 0; сч < 4; сч++) {", + " ячейка = (S >>> (сч << 3)) & 0xFF;", + " нов_S += (Таблица_замен[сч*2][ячейка & 0x0F] + (Таблица_замен[сч*2+1][ячейка >>> 4] << 4)) << (сч << 3);", + " }", + " S = (((нов_S << 11) + (нов_S >>> 21)) & 0xFFFFFFFF) ^ N[1];", + " N[1] = N[0]; N[0] = S;", + " return N;", + "}", + "", + "Note: the variable \"блок_текста\" is an array of two 32-bit values that make up the block.", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f06", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var Таблица_замен = [\n [ 4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3],\n [14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9],\n [ 5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11],\n [ 7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3],\n [ 6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2],\n [ 4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14],\n [13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12],\n [ 1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12]];\n\nfunction ОсновнойШаг(блок_текста, элемент_ключа) {\n var N = блок_текста.slice(0);\n var X = элемент_ключа;\n var S = (N[0] + X) & 0xFFFFFFFF;\n var ячейка; var нов_S = 0;\n for (var сч = 0; сч < 4; сч++) {\n ячейка = (S >>> (сч << 3)) & 0xFF;\n нов_S += (Таблица_замен[сч*2][ячейка & 0x0F] + (Таблица_замен[сч*2+1][ячейка >>> 4] << 4)) << (сч << 3);\n }\n S = (((нов_S << 11) + (нов_S >>> 21)) & 0xFFFFFFFF) ^ N[1];\n N[1] = N[0]; N[0] = S;\n return N;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Make directory path", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a directory and any missing parents.

This task is named after the posix mkdir -p command, and several libraries which implement the same behavior.

Please implement a function of a single path string (for example ./path/to/dir) which has the above side-effect.

", + "

If the directory already exists, return successfully.

", + "

Ideally implementations will work equally well cross-platform (on windows, linux, and OS X).

It's likely that your language implements such a function as part of its standard library. If so, please also show how such a function would be implemented.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|Node.js}}", + "", + "Simplified version of the popular [https://www.npmjs.org/package/mkdirp mkdirp library]:", + "", + "var path = require('path');", + "var fs = require('fs');", + "", + "function mkdirp (p, cb) {", + " cb = cb || function () {};", + " p = path.resolve(p);", + "", + " fs.mkdir(p, function (er) {", + " if (!er) {", + " return cb(null);", + " }", + " switch (er.code) {", + " case 'ENOENT':", + " // The directory doesn't exist. Make its parent and try again.", + " mkdirp(path.dirname(p), function (er) {", + " if (er) cb(er);", + " else mkdirp(p, cb);", + " });", + " break;", + "", + " // In the case of any other error, something is borked.", + " default:", + " cb(er);", + " break;", + " }", + " });", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f07", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var path = require('path');\nvar fs = require('fs');\n\nfunction mkdirp (p, cb) {\n cb = cb || function () {};\n p = path.resolve(p);\n\n fs.mkdir(p, function (er) {\n if (!er) {\n return cb(null);\n }\n switch (er.code) {\n case 'ENOENT':\n // The directory doesn't exist. Make its parent and try again.\n mkdirp(path.dirname(p), function (er) {\n if (er) cb(er);\n else mkdirp(p, cb);\n });\n break;\n\n // In the case of any other error, something is borked.\n default:\n cb(er);\n break;\n }\n });\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Mandelbrot set", + "type": "Waypoint", + "description": [ + "Task:", + "

Generate and draw the Mandelbrot set.

", + "

Note that there are many algorithms to draw Mandelbrot set and there are many functions which generate it .

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|Firefox|3.5.11}}", + "", + "This needs the canvas tag of HTML 5 (it will not run on IE8 and lower or old browsers).", + "", + "The code can be run directly from the Javascript console in modern browsers by copying and pasting it.", + "", + "function mandelIter(cx, cy, maxIter) {", + " var x = 0.0;", + " var y = 0.0;", + " var xx = 0;", + " var yy = 0;", + " var xy = 0;", + "", + " var i = maxIter;", + " while (i-- && xx + yy <= 4) {", + " xy = x * y;", + " xx = x * x;", + " yy = y * y;", + " x = xx - yy + cx;", + " y = xy + xy + cy;", + " }", + " return maxIter - i;", + "}", + "", + "function mandelbrot(canvas, xmin, xmax, ymin, ymax, iterations) {", + " var width = canvas.width;", + " var height = canvas.height;", + "", + " var ctx = canvas.getContext('2d');", + " var img = ctx.getImageData(0, 0, width, height);", + " var pix = img.data;", + " ", + " for (var ix = 0; ix < width; ++ix) {", + " for (var iy = 0; iy < height; ++iy) {", + " var x = xmin + (xmax - xmin) * ix / (width - 1);", + " var y = ymin + (ymax - ymin) * iy / (height - 1);", + " var i = mandelIter(x, y, iterations);", + " var ppos = 4 * (width * iy + ix);", + " ", + " if (i > iterations) {", + " pix[ppos] = 0;", + " pix[ppos + 1] = 0;", + " pix[ppos + 2] = 0;", + " } else {", + " var c = 3 * Math.log(i) / Math.log(iterations - 1.0);", + " ", + " if (c < 1) {", + " pix[ppos] = 255 * c;", + " pix[ppos + 1] = 0;", + " pix[ppos + 2] = 0;", + " }", + " else if ( c < 2 ) {", + " pix[ppos] = 255;", + " pix[ppos + 1] = 255 * (c - 1);", + " pix[ppos + 2] = 0;", + " } else {", + " pix[ppos] = 255;", + " pix[ppos + 1] = 255;", + " pix[ppos + 2] = 255 * (c - 2);", + " }", + " }", + " pix[ppos + 3] = 255;", + " }", + " }", + " ", + " ctx.putImageData(img, 0, 0);", + "}", + "", + "var canvas = document.createElement('canvas');", + "canvas.width = 900;", + "canvas.height = 600;", + "", + "document.body.insertBefore(canvas, document.body.childNodes[0]);", + "", + "mandelbrot(canvas, -2, 1, -1, 1, 1000);", + "", + "{{out}} with default parameters:", + "[[File:Mandelbrot-Javascript.png]]", + "", + "=== ES6/WebAssembly ===", + "", + "With ES6 and WebAssembly, the program can run faster. Of course, this requires a compiled WASM file, but one can easily build", + "one for instance with the [https://mbebenita.github.io/WasmExplorer/ WebAssembly explorer]", + "", + "var mandelIter;", + "fetch(\"./mandelIter.wasm\")", + " .then(res => {", + " if (res.ok) return res.arrayBuffer();", + " throw new Error('Unable to fetch WASM.');", + " })", + " .then(bytes => { return WebAssembly.compile(bytes); })", + " .then(module => { return WebAssembly.instantiate(module); })", + " .then(instance => { WebAssembly.instance = instance; draw(); })", + "", + "function mandelbrot(canvas, xmin, xmax, ymin, ymax, iterations) {", + " // ...", + " var i = WebAssembly.instance.exports.mandelIter(x, y, iterations);", + " // ...", + "}", + "", + "function draw() {", + " // canvas initialization if necessary", + " // ...", + " mandelbrot(canvas, -2, 1, -1, 1, 1000);", + " // ...", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f08", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function mandelIter(cx, cy, maxIter) {\n var x = 0.0;\n var y = 0.0;\n var xx = 0;\n var yy = 0;\n var xy = 0;\n\n var i = maxIter;\n while (i-- && xx + yy <= 4) {\n xy = x * y;\n xx = x * x;\n yy = y * y;\n x = xx - yy + cx;\n y = xy + xy + cy;\n }\n return maxIter - i;\n}\n\nfunction mandelbrot(canvas, xmin, xmax, ymin, ymax, iterations) {\n var width = canvas.width;\n var height = canvas.height;\n\n var ctx = canvas.getContext('2d');\n var img = ctx.getImageData(0, 0, width, height);\n var pix = img.data;\n \n for (var ix = 0; ix < width; ++ix) {\n for (var iy = 0; iy < height; ++iy) {\n var x = xmin + (xmax - xmin) * ix / (width - 1);\n var y = ymin + (ymax - ymin) * iy / (height - 1);\n var i = mandelIter(x, y, iterations);\n var ppos = 4 * (width * iy + ix);\n \n if (i > iterations) {\n pix[ppos] = 0;\n pix[ppos + 1] = 0;\n pix[ppos + 2] = 0;\n } else {\n var c = 3 * Math.log(i) / Math.log(iterations - 1.0);\n \n if (c < 1) {\n pix[ppos] = 255 * c;\n pix[ppos + 1] = 0;\n pix[ppos + 2] = 0;\n }\n else if ( c < 2 ) {\n pix[ppos] = 255;\n pix[ppos + 1] = 255 * (c - 1);\n pix[ppos + 2] = 0;\n } else {\n pix[ppos] = 255;\n pix[ppos + 1] = 255;\n pix[ppos + 2] = 255 * (c - 2);\n }\n }\n pix[ppos + 3] = 255;\n }\n }\n \n ctx.putImageData(img, 0, 0);\n}\n\nvar canvas = document.createElement('canvas');\ncanvas.width = 900;\ncanvas.height = 600;\n\ndocument.body.insertBefore(canvas, document.body.childNodes[0]);\n\nmandelbrot(canvas, -2, 1, -1, 1, 1000);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Man or boy test", + "type": "Waypoint", + "description": [ + "

Background: The man or boy test was proposed by computer scientist Donald Knuth as a means of evaluating implementations of the ALGOL 60 programming language. The aim of the test was to distinguish compilers that correctly implemented \"recursion and non-local references\" from those that did not.

", + "

I have written the following simple routine, which may separate the 'man-compilers' from the 'boy-compilers' — Donald Knuth

Task: Imitate Knuth's example in Algol 60 in another language, as far as possible.

Details: Local variables of routines are often kept in activation records (also call frames). In many languages, these records are kept on a call stack. In Algol (and e.g. in Smalltalk), they are allocated on a heap instead. Hence it is possible to pass references to routines that still can use and update variables from their call environment, even if the routine where those variables are declared already returned. This difference in implementations is sometimes called the Funarg Problem.

In Knuth's example, each call to A allocates an activation record for the variable A. When B is called from A, any access to k now refers to this activation record. Now B in turn calls A, but passes itself as an argument. This argument remains bound to the activation record. This call to A also \"shifts\" the variables xi by one place, so eventually the argument B (still bound to its particular

", + "

activation record) will appear as x4 or x5 in a call to A. If this happens when the expression x4 + x5 is evaluated, then this will again call B, which in turn will update k in the activation record it was originally bound to. As this activation record is shared with other instances of calls to A and B, it will influence the whole computation.

So all the example does is to set up a convoluted calling structure, where updates to k can influence the behavior

", + "

in completely different parts of the call tree.

Knuth used this to test the correctness of the compiler, but one can of course also use it to test that other languages can emulate the Algol behavior correctly. If the handling of activation records is correct, the computed value will be −67.

Performance and Memory: Man or Boy is intense and can be pushed to challenge any machine. Memory (both stack and heap) not CPU time is the constraining resource as the recursion creates a proliferation activation records which will quickly exhaust memory and present itself through a stack error. Each language may have ways of adjusting the amount of memory or increasing the recursion depth. Optionally, show how you would make such adjustments.

The table below shows the result, call depths, and total calls for a range of k:

", + "

{| style=\"font-size: 85%\"

", + "

! k

", + "

! 0

", + "

! 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

", + "

|-

", + "

! A

", + "

|align=\"right\"| 1

", + "

|align=\"right\"| 0

", + "

|align=\"right\"| -2

", + "

|align=\"right\"| 0

", + "

|align=\"right\"| 1

", + "

|align=\"right\"| 0

", + "

|align=\"right\"| 1

", + "

|align=\"right\"| -1

", + "

|align=\"right\"| -10

", + "

|align=\"right\"| -30

", + "

|align=\"right\"| -67

", + "

|align=\"right\"| -138

", + "

|align=\"right\"| -291

", + "

|align=\"right\"| -642

", + "

|align=\"right\"| -1,446

", + "

|align=\"right\"| -3,250

", + "

|align=\"right\"| -7,244

", + "

|align=\"right\"| -16,065

", + "

|align=\"right\"| -35,601

", + "

|align=\"right\"| -78,985

", + "

|align=\"right\"| -175,416

", + "

|align=\"right\"| -389,695

", + "

|align=\"right\"| -865,609

", + "

|align=\"right\"| -1,922,362

", + "

|align=\"right\"| -4,268,854

", + "

|align=\"right\"| -9,479,595

", + "

|align=\"right\"| -21,051,458

", + "

|align=\"right\"| -46,750,171

", + "

|align=\"right\"| -103,821,058

", + "

|align=\"right\"| -230,560,902

", + "

|align=\"right\"| -512,016,658

", + "

|-

", + "

! A called

", + "

|align=\"right\"| 1

", + "

|align=\"right\"| 2

", + "

|align=\"right\"| 3

", + "

|align=\"right\"| 4

", + "

|align=\"right\"| 8

", + "

|align=\"right\"| 18

", + "

|align=\"right\"| 38

", + "

|align=\"right\"| 80

", + "

|align=\"right\"| 167

", + "

|align=\"right\"| 347

", + "

|align=\"right\"| 722

", + "

|align=\"right\"| 1,509

", + "

|align=\"right\"| 3,168

", + "

|align=\"right\"| 6,673

", + "

|align=\"right\"| 14,091

", + "

|align=\"right\"| 29,825

", + "

|align=\"right\"| 63,287

", + "

|align=\"right\"| 134,652

", + "

|align=\"right\"| 287,264

", + "

|align=\"right\"| 614,442

", + "

|align=\"right\"| 1,317,533

", + "

|align=\"right\"| 2,831,900

", + "

|align=\"right\"| 6,100,852

", + "

|align=\"right\"| 13,172,239

", + "

|align=\"right\"| 28,499,827

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|-

", + "

! A depth

", + "

|align=\"right\"| 1

", + "

|align=\"right\"| 2

", + "

|align=\"right\"| 3

", + "

|align=\"right\"| 4

", + "

|align=\"right\"| 8

", + "

|align=\"right\"| 16

", + "

|align=\"right\"| 32

", + "

|align=\"right\"| 64

", + "

|align=\"right\"| 128

", + "

|align=\"right\"| 256

", + "

|align=\"right\"| 512

", + "

|align=\"right\"| 1,024

", + "

|align=\"right\"| 2,048

", + "

|align=\"right\"| 4,096

", + "

|align=\"right\"| 8,192

", + "

|align=\"right\"| 16,384

", + "

|align=\"right\"| 32,768

", + "

|align=\"right\"| 65,536

", + "

|align=\"right\"| 131,072

", + "

|align=\"right\"| 262,144

", + "

|align=\"right\"| 524,288

", + "

|align=\"right\"| 1,048,576

", + "

|align=\"right\"| 2,097,152

", + "

|align=\"right\"| 4,194,304

", + "

|align=\"right\"| 8,388,608

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|-

", + "

! B called

", + "

|align=\"right\"| 0

", + "

|align=\"right\"| 1

", + "

|align=\"right\"| 2

", + "

|align=\"right\"| 3

", + "

|align=\"right\"| 7

", + "

|align=\"right\"| 17

", + "

|align=\"right\"| 37

", + "

|align=\"right\"| 79

", + "

|align=\"right\"| 166

", + "

|align=\"right\"| 346

", + "

|align=\"right\"| 721

", + "

|align=\"right\"| 1,508

", + "

|align=\"right\"| 3,167

", + "

|align=\"right\"| 6,672

", + "

|align=\"right\"| 14,090

", + "

|align=\"right\"| 29,824

", + "

|align=\"right\"| 63,286

", + "

|align=\"right\"| 134,651

", + "

|align=\"right\"| 287,263

", + "

|align=\"right\"| 614,441

", + "

|align=\"right\"| 1,317,532

", + "

|align=\"right\"| 2,831,899

", + "

|align=\"right\"| 6,100,851

", + "

|align=\"right\"| 13,172,238

", + "

|align=\"right\"| 28,499,826

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|-

", + "

! B depth

", + "

|align=\"right\"| 0

", + "

|align=\"right\"| 1

", + "

|align=\"right\"| 2

", + "

|align=\"right\"| 3

", + "

|align=\"right\"| 7

", + "

|align=\"right\"| 15

", + "

|align=\"right\"| 31

", + "

|align=\"right\"| 63

", + "

|align=\"right\"| 127

", + "

|align=\"right\"| 255

", + "

|align=\"right\"| 511

", + "

|align=\"right\"| 1,023

", + "

|align=\"right\"| 2,047

", + "

|align=\"right\"| 4,095

", + "

|align=\"right\"| 8,191

", + "

|align=\"right\"| 16,383

", + "

|align=\"right\"| 32,767

", + "

|align=\"right\"| 65,535

", + "

|align=\"right\"| 131,071

", + "

|align=\"right\"| 262,143

", + "

|align=\"right\"| 524,287

", + "

|align=\"right\"| 1,048,575

", + "

|align=\"right\"| 2,097,151

", + "

|align=\"right\"| 4,194,303

", + "

|align=\"right\"| 8,388,607

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|

", + "

|}

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "In Chrome we get a \"Maximum call stack size exceeded\" when a > 13. In Firefox we get \"too much recursion\" when a > 12.", + "function a(k, x1, x2, x3, x4, x5) {", + " function b() {", + " k -= 1;", + " return a(k, b, x1, x2, x3, x4);", + " }", + " return (k > 0) ? b() : x4() + x5();", + "}", + "", + "// this uses lambda wrappers around the numeric arguments", + "function x(n) {", + " return function () {", + " return n;", + " };", + "}", + "alert(a(10, x(1), x(-1), x(-1), x(1), x(0)));", + "", + "Implemented using ES6 syntax", + "var x = n => () => n;", + "", + "var a = (k, x1, x2, x3, x4, x5) => {", + " var b = () => return a(--k, b, x1, x2, x3, x4); //decrement k before use", + " return (k > 0) ? b() : x4() + x5();", + "};", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f09", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function a(k, x1, x2, x3, x4, x5) {\n function b() {\n k -= 1;\n return a(k, b, x1, x2, x3, x4);\n }\n return (k > 0) ? b() : x4() + x5();\n}\n\n// this uses lambda wrappers around the numeric arguments\nfunction x(n) {\n return function () {\n return n;\n };\n}\nalert(a(10, x(1), x(-1), x(-1), x(1), x(0)));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Map range", + "type": "Waypoint", + "description": [ + "

Given two ranges:

", + "

::* $[a_1,a_2]$ and

", + "

::* $[b_1,b_2]$;

", + "

::* then a value $s$ in range $[a_1,a_2]$

", + "

::* is linearly mapped to a value $t$ in range $[b_1,b_2]$

", + " where: ", + "

::* $t = b_1 + {(s - a_1)(b_2 - b_1) \\over (a_2 - a_1)}$

", + "Task:", + "

Write a function/subroutine/... that takes two ranges and a real number, and returns the mapping of the real number from the first to the second range.

Use this function to map values from the range [0, 10] to the range [-1, 0].

", + "Extra credit:", + "

Show additional idiomatic ways of performing the mapping, using tools available to the language.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "// Javascript doesn't have built-in support for ranges", + "// Insted we use arrays of two elements to represent ranges", + "var mapRange = function(from, to, s) {", + " return to[0] + (s - from[0]) * (to[1] - to[0]) / (from[1] - from[0]);", + "};", + "", + "var range = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];", + "for (var i = 0; i < range.length; i++) {", + " range[i] = mapRange([0, 10], [-1, 0], range[i]);", + "}", + "", + "console.log(range);", + "{{out}}", + "
[-1, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.30000000000000004, -0.19999999999999996, -0.09999999999999998, 0]
", + "", + "=== Extra credit ===", + "Here we will use the [https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map ECMAScript 5 support for map] and the [http://underscorejs.org/#range _.range] function from Underscore.js.", + "{{libheader|Underscore.js}}", + "var mapRange = function(from, to, s) {", + " // mapRange expects ranges generated by _.range", + " var a1 = from[0];", + " var a2 = from[from.length - 1];", + " var b1 = to[0];", + " var b2 = to[to.length - 1];", + " return b1 + (s - a1) * (b2 - b1) / (a2 - a1);", + "};", + "", + "// The range function is exclusive", + "var fromRange = _.range(0, 11);", + "var toRange = _.range(-1, 1);", + "", + "// .map constructs a new array", + "fromRange = fromRange.map(function(s) {", + " return mapRange(fromRange, toRange, s);", + "});", + "", + "console.log(fromRange);", + "{{out}}", + "
[-1, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.30000000000000004, -0.19999999999999996, -0.09999999999999998, 0]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f0a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// Javascript doesn't have built-in support for ranges\n// Insted we use arrays of two elements to represent ranges\nvar mapRange = function(from, to, s) {\n return to[0] + (s - from[0]) * (to[1] - to[0]) / (from[1] - from[0]);\n};\n\nvar range = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nfor (var i = 0; i < range.length; i++) {\n range[i] = mapRange([0, 10], [-1, 0], range[i]);\n}\n\nconsole.log(range);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Matrix arithmetic", + "type": "Waypoint", + "description": [ + "

For a given matrix, return the determinant and the permanent of the matrix.

The determinant is given by

", + "

: $\\det(A) = \\sum_\\sigma\\sgn(\\sigma)\\prod_{i=1}^n M_{i,\\sigma_i}$

", + "

while the permanent is given by

", + "

: $ \\operatorname{perm}(A)=\\sum_\\sigma\\prod_{i=1}^n M_{i,\\sigma_i}$

", + "

In both cases the sum is over the permutations $\\sigma$ of the permutations of 1, 2, ..., n. (A permutation's sign is 1 if there are an even number of inversions and -1 otherwise; see parity of a permutation.)

More efficient algorithms for the determinant are known: LU decomposition, see for example [[wp:LU decomposition#Computing the determinant]]. Efficient methods for calculating the permanent are not known.

Cf.:", + "Permutations by swapping" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f0b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Matrix-exponentiation operator", + "type": "Waypoint", + "description": [ + "

Most programming languages have a built-in implementation of exponentiation for integers and reals only.

", + "

Demonstrate how to implement matrix exponentiation as an operator.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|SpiderMonkey}} for the print() and ''Array''.forEach() functions.", + "", + "Extends [[Matrix Transpose#JavaScript]] and [[Matrix multiplication#JavaScript]]", + "// IdentityMatrix is a \"subclass\" of Matrix", + "function IdentityMatrix(n) {", + " this.height = n;", + " this.width = n;", + " this.mtx = [];", + " for (var i = 0; i < n; i++) {", + " this.mtx[i] = [];", + " for (var j = 0; j < n; j++) {", + " this.mtx[i][j] = (i == j ? 1 : 0);", + " }", + " }", + "}", + "IdentityMatrix.prototype = Matrix.prototype;", + "", + "// the Matrix exponentiation function", + "// returns a new matrix", + "Matrix.prototype.exp = function(n) {", + " var result = new IdentityMatrix(this.height);", + " for (var i = 1; i <= n; i++) {", + " result = result.mult(this);", + " }", + " return result;", + "}", + "", + "var m = new Matrix([[3, 2], [2, 1]]);", + "[0,1,2,3,4,10].forEach(function(e){print(m.exp(e)); print()})", + "output", + "
1,0",
+      "0,1",
+      "",
+      "3,2",
+      "2,1",
+      "",
+      "13,8",
+      "8,5",
+      "",
+      "55,34",
+      "34,21",
+      "",
+      "233,144",
+      "144,89",
+      "",
+      "1346269,832040",
+      "832040,514229",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f0c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// IdentityMatrix is a \"subclass\" of Matrix\nfunction IdentityMatrix(n) {\n this.height = n;\n this.width = n;\n this.mtx = [];\n for (var i = 0; i < n; i++) {\n this.mtx[i] = [];\n for (var j = 0; j < n; j++) {\n this.mtx[i][j] = (i == j ? 1 : 0);\n }\n }\n}\nIdentityMatrix.prototype = Matrix.prototype;\n\n// the Matrix exponentiation function\n// returns a new matrix\nMatrix.prototype.exp = function(n) {\n var result = new IdentityMatrix(this.height);\n for (var i = 1; i <= n; i++) {\n result = result.mult(this);\n }\n return result;\n}\n\nvar m = new Matrix([[3, 2], [2, 1]]);\n[0,1,2,3,4,10].forEach(function(e){print(m.exp(e)); print()})\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Matrix multiplication", + "type": "Waypoint", + "description": [ + "Task:", + "

Multiply two matrices together.

They can be of any dimensions, so long as the number of columns of the first matrix is equal to the number of rows of the second matrix.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Iterative====", + "{{works with|SpiderMonkey}} for the print() function", + "", + "Extends [[Matrix Transpose#JavaScript]]", + "// returns a new matrix", + "Matrix.prototype.mult = function(other) {", + " if (this.width != other.height) {", + " throw \"error: incompatible sizes\";", + " }", + "", + " var result = [];", + " for (var i = 0; i < this.height; i++) {", + " result[i] = [];", + " for (var j = 0; j < other.width; j++) {", + " var sum = 0;", + " for (var k = 0; k < this.width; k++) {", + " sum += this.mtx[i][k] * other.mtx[k][j];", + " }", + " result[i][j] = sum;", + " }", + " }", + " return new Matrix(result); ", + "}", + "", + "var a = new Matrix([[1,2],[3,4]])", + "var b = new Matrix([[-3,-8,3],[-2,1,4]]);", + "print(a.mult(b));", + "{{out}}", + "
-7,-6,11",
+      "-17,-20,25
", + "", + "====Functional====", + "(function () {", + " 'use strict';", + "", + " // matrixMultiply:: [[n]] -> [[n]] -> [[n]] ", + " function matrixMultiply(a, b) {", + " var bCols = transpose(b);", + "", + " return a.map(function (aRow) {", + " return bCols.map(function (bCol) {", + " return dotProduct(aRow, bCol);", + " });", + " });", + " }", + " ", + " // [[n]] -> [[n]] -> [[n]]", + " function dotProduct(xs, ys) {", + " return sum(zipWith(product, xs, ys));", + " }", + "", + " return matrixMultiply(", + " [[-1, 1, 4],", + " [ 6, -4, 2],", + " [-3, 5, 0],", + " [ 3, 7, -2]],", + "", + " [[-1, 1, 4, 8],", + " [ 6, 9, 10, 2],", + " [11, -4, 5, -3]]", + " );", + "", + " // --> [[51, -8, 26, -18], [-8, -38, -6, 34], ", + " // [33, 42, 38, -14], [17, 74, 72, 44]]", + "", + "", + " // GENERIC LIBRARY FUNCTIONS", + "", + " // (a -> b -> c) -> [a] -> [b] -> [c]", + " function zipWith(f, xs, ys) {", + " return xs.length === ys.length ? (", + " xs.map(function (x, i) {", + " return f(x, ys[i]);", + " })", + " ) : undefined;", + " }", + "", + " // [[a]] -> [[a]]", + " function transpose(lst) {", + " return lst[0].map(function (_, iCol) {", + " return lst.map(function (row) {", + " return row[iCol];", + " });", + " });", + " }", + "", + " // sum :: (Num a) => [a] -> a", + " function sum(xs) {", + " return xs.reduce(function (a, x) {", + " return a + x;", + " }, 0);", + " }", + "", + " // product :: n -> n -> n", + " function product(a, b) {", + " return a * b;", + " }", + "", + "})();", + "{{Out}}", + "[[51, -8, 26, -18], [-8, -38, -6, 34], ", + " [33, 42, 38, -14], [17, 74, 72, 44]]", + "", + "===ES6===", + "((() => {", + " 'use strict';", + "", + " // matrixMultiply :: Num a => [[a]] -> [[a]] -> [[a]]", + " const matrixMultiply = (a, b) => {", + " const bCols = transpose(b);", + " return a.map(aRow => bCols.map(bCol => dotProduct(aRow, bCol)));", + " }", + "", + " // dotProduct :: Num a => [[a]] -> [[a]] -> [[a]]", + " const dotProduct = (xs, ys) => sum(zipWith(product, xs, ys));", + "", + "", + " // GENERIC", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) =>", + " xs.length === ys.length ? (", + " xs.map((x, i) => f(x, ys[i]))", + " ) : undefined;", + "", + " // transpose :: [[a]] -> [[a]]", + " const transpose = xs =>", + " xs[0].map((_, iCol) => xs.map(row => row[iCol]));", + "", + " // sum :: (Num a) => [a] -> a", + " const sum = xs =>", + " xs.reduce((a, x) => a + x, 0);", + "", + " // product :: Num a => a -> a -> a", + " const product = (a, b) => a * b;", + "", + "", + " // TEST", + " return matrixMultiply(", + " [", + " [-1, 1, 4],", + " [6, -4, 2],", + " [-3, 5, 0],", + " [3, 7, -2]", + " ],", + "", + " [", + " [-1, 1, 4, 8],", + " [6, 9, 10, 2],", + " [11, -4, 5, -3]", + " ]", + " );", + "", + " // --> [[51, -8, 26, -18], [-8, -38, -6, 34],", + " // [33, 42, 38, -14], [17, 74, 72, 44]]", + "}))();", + "{{Out}}", + "[[51, -8, 26, -18], [-8, -38, -6, 34], ", + "[33, 42, 38, -14], [17, 74, 72, 44]]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f0d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// returns a new matrix\nMatrix.prototype.mult = function(other) {\n if (this.width != other.height) {\n throw \"error: incompatible sizes\";\n }\n\n var result = [];\n for (var i = 0; i < this.height; i++) {\n result[i] = [];\n for (var j = 0; j < other.width; j++) {\n var sum = 0;\n for (var k = 0; k < this.width; k++) {\n sum += this.mtx[i][k] * other.mtx[k][j];\n }\n result[i][j] = sum;\n }\n }\n return new Matrix(result); \n}\n\nvar a = new Matrix([[1,2],[3,4]])\nvar b = new Matrix([[-3,-8,3],[-2,1,4]]);\nprint(a.mult(b));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Matrix transposition", + "type": "Waypoint", + "description": [ + "

Transpose an arbitrarily sized rectangular Matrix.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "{{works with|SpiderMonkey}} for the print() function", + "function Matrix(ary) {", + " this.mtx = ary", + " this.height = ary.length;", + " this.width = ary[0].length;", + "}", + "", + "Matrix.prototype.toString = function() {", + " var s = []", + " for (var i = 0; i < this.mtx.length; i++) ", + " s.push( this.mtx[i].join(\",\") );", + " return s.join(\"\\n\");", + "}", + "", + "// returns a new matrix", + "Matrix.prototype.transpose = function() {", + " var transposed = [];", + " for (var i = 0; i < this.width; i++) {", + " transposed[i] = [];", + " for (var j = 0; j < this.height; j++) {", + " transposed[i][j] = this.mtx[j][i];", + " }", + " }", + " return new Matrix(transposed);", + "}", + "", + "var m = new Matrix([[1,1,1,1],[2,4,8,16],[3,9,27,81],[4,16,64,256],[5,25,125,625]]);", + "print(m);", + "print();", + "print(m.transpose());", + "", + "produces", + "
1,1,1,1",
+      "2,4,8,16",
+      "3,9,27,81",
+      "4,16,64,256",
+      "5,25,125,625",
+      "",
+      "1,2,3,4,5",
+      "1,4,9,16,25",
+      "1,8,27,64,125",
+      "1,16,81,256,625
", + "", + "", + "Or, as a functional expression (rather than an imperative procedure):", + "", + "(function () {", + " 'use strict';", + "", + " function transpose(lst) {", + " return lst[0].map(function (_, iCol) {", + " return lst.map(function (row) {", + " return row[iCol];", + " })", + " });", + " }", + " ", + " return transpose(", + " [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]", + " );", + "", + "})();", + "", + "", + "{{Out}}", + "", + "
[[1, 4, 7, 10], [2, 5, 8, 11], [3, 6, 9, 12]]
", + "", + "===ES6===", + "", + "(() => {", + " 'use strict';", + "", + " // transpose :: [[a]] -> [[a]]", + " let transpose = xs =>", + " xs[0].map((_, iCol) => xs.map((row) => row[iCol]));", + "", + "", + "", + " // TEST", + " return transpose([", + " [1, 2],", + " [3, 4],", + " [5, 6]", + " ]);", + "})();", + "", + "{{Out}}", + "[[1, 3, 5], [2, 4, 6]]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f0e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function Matrix(ary) {\n this.mtx = ary\n this.height = ary.length;\n this.width = ary[0].length;\n}\n\nMatrix.prototype.toString = function() {\n var s = []\n for (var i = 0; i < this.mtx.length; i++) \n s.push( this.mtx[i].join(\",\") );\n return s.join(\"\\n\");\n}\n\n// returns a new matrix\nMatrix.prototype.transpose = function() {\n var transposed = [];\n for (var i = 0; i < this.width; i++) {\n transposed[i] = [];\n for (var j = 0; j < this.height; j++) {\n transposed[i][j] = this.mtx[j][i];\n }\n }\n return new Matrix(transposed);\n}\n\nvar m = new Matrix([[1,1,1,1],[2,4,8,16],[3,9,27,81],[4,16,64,256],[5,25,125,625]]);\nprint(m);\nprint();\nprint(m.transpose());\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Maximum triangle path sum", + "type": "Waypoint", + "description": [ + "

Starting from the top of a pyramid of numbers like this, you can walk down going one step on the right or on the left, until you reach the bottom row:

", + "
",
+      "                          55",
+      "                        94 48",
+      "                       95 30 96",
+      "                     77 71 26 67",
+      "

One of such walks is 55 - 94 - 30 - 26.

", + "

You can compute the total of the numbers you have seen in such walk,

", + "

in this case it's 205.

Your problem is to find the maximum total among all possible paths from the top to the bottom row of the triangle. In the little example above it's 321.

", + "Task:", + "

Find the maximum total in the triangle below:

", + "
",
+      "                          55",
+      "                        94 48",
+      "                       95 30 96",
+      "                     77 71 26 67",
+      "                    97 13 76 38 45",
+      "                  07 36 79 16 37 68",
+      "                 48 07 09 18 70 26 06",
+      "               18 72 79 46 59 79 29 90",
+      "              20 76 87 11 32 07 07 49 18",
+      "            27 83 58 35 71 11 25 57 29 85",
+      "           14 64 36 96 27 11 58 56 92 18 55",
+      "         02 90 03 60 48 49 41 46 33 36 47 23",
+      "        92 50 48 02 36 59 42 79 72 20 82 77 42",
+      "      56 78 38 80 39 75 02 71 66 66 01 03 55 72",
+      "     44 25 67 84 71 67 11 61 40 57 58 89 40 56 36",
+      "   85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52",
+      "  06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15",
+      "27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93",
+      "

Such numbers can be included in the solution code, or read from a \"triangle.txt\" file.

This task is derived from the Euler Problem #18.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f0f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Maze solving", + "type": "Waypoint", + "description": [ + "

For a maze generated by this task, write a function

", + "

that finds (and displays) the shortest path between two cells.

", + "

Note that because these mazes are generated by the Depth-first search algorithm, they contain no circular paths,

", + "

and a simple depth-first tree search can be used.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Animated: generating and solving.
To start solving, click to choose a 'start' and an 'end' points.", + "
Go [http://paulo-jorente.de/tests/mazesolver/ here] to see it in action.", + "", + "var ctx, wid, hei, cols, rows, maze, stack = [], start = {x:-1, y:-1}, end = {x:-1, y:-1}, grid = 8;", + "function drawMaze() {", + " for( var i = 0; i < cols; i++ ) {", + " for( var j = 0; j < rows; j++ ) {", + " switch( maze[i][j] ) {", + " case 0: ctx.fillStyle = \"black\"; break;", + " case 1: ctx.fillStyle = \"green\"; break;", + " case 2: ctx.fillStyle = \"red\"; break;", + " case 3: ctx.fillStyle = \"yellow\"; break;", + " case 4: ctx.fillStyle = \"#500000\"; break;", + " }", + " ctx.fillRect( grid * i, grid * j, grid, grid );", + " }", + " }", + "}", + "function getFNeighbours( sx, sy, a ) {", + " var n = [];", + " if( sx - 1 > 0 && maze[sx - 1][sy] == a ) {", + " n.push( { x:sx - 1, y:sy } );", + " }", + " if( sx + 1 < cols - 1 && maze[sx + 1][sy] == a ) {", + " n.push( { x:sx + 1, y:sy } );", + " }", + " if( sy - 1 > 0 && maze[sx][sy - 1] == a ) {", + " n.push( { x:sx, y:sy - 1 } );", + " }", + " if( sy + 1 < rows - 1 && maze[sx][sy + 1] == a ) {", + " n.push( { x:sx, y:sy + 1 } );", + " }", + " return n;", + "}", + "function solveMaze() {", + " if( start.x == end.x && start.y == end.y ) {", + " for( var i = 0; i < cols; i++ ) {", + " for( var j = 0; j < rows; j++ ) {", + " switch( maze[i][j] ) {", + " case 2: maze[i][j] = 3; break;", + " case 4: maze[i][j] = 0; break;", + " }", + " }", + " }", + " drawMaze();", + " return;", + " }", + " var neighbours = getFNeighbours( start.x, start.y, 0 );", + " if( neighbours.length ) {", + " stack.push( start );", + " start = neighbours[0];", + " maze[start.x][start.y] = 2;", + " } else {", + " maze[start.x][start.y] = 4;", + " start = stack.pop();", + " }", + "", + " drawMaze();", + " requestAnimationFrame( solveMaze );", + "}", + "function getCursorPos( event ) {", + " var rect = this.getBoundingClientRect();", + " var x = Math.floor( ( event.clientX - rect.left ) / grid ), ", + " y = Math.floor( ( event.clientY - rect.top ) / grid );", + " if( maze[x][y] ) return;", + " if( start.x == -1 ) {", + " start = { x: x, y: y };", + " } else {", + " end = { x: x, y: y };", + " maze[start.x][start.y] = 2;", + " solveMaze();", + " }", + "}", + "function getNeighbours( sx, sy, a ) {", + " var n = [];", + " if( sx - 1 > 0 && maze[sx - 1][sy] == a && sx - 2 > 0 && maze[sx - 2][sy] == a ) {", + " n.push( { x:sx - 1, y:sy } ); n.push( { x:sx - 2, y:sy } );", + " }", + " if( sx + 1 < cols - 1 && maze[sx + 1][sy] == a && sx + 2 < cols - 1 && maze[sx + 2][sy] == a ) {", + " n.push( { x:sx + 1, y:sy } ); n.push( { x:sx + 2, y:sy } );", + " }", + " if( sy - 1 > 0 && maze[sx][sy - 1] == a && sy - 2 > 0 && maze[sx][sy - 2] == a ) {", + " n.push( { x:sx, y:sy - 1 } ); n.push( { x:sx, y:sy - 2 } );", + " }", + " if( sy + 1 < rows - 1 && maze[sx][sy + 1] == a && sy + 2 < rows - 1 && maze[sx][sy + 2] == a ) {", + " n.push( { x:sx, y:sy + 1 } ); n.push( { x:sx, y:sy + 2 } );", + " }", + " return n;", + "}", + "function createArray( c, r ) {", + " var m = new Array( c );", + " for( var i = 0; i < c; i++ ) {", + " m[i] = new Array( r );", + " for( var j = 0; j < r; j++ ) {", + " m[i][j] = 1;", + " }", + " }", + " return m;", + "}", + "function createMaze() {", + " var neighbours = getNeighbours( start.x, start.y, 1 ), l;", + " if( neighbours.length < 1 ) {", + " if( stack.length < 1 ) {", + " drawMaze(); stack = [];", + " start.x = start.y = -1;", + " document.getElementById( \"canvas\" ).addEventListener( \"mousedown\", getCursorPos, false );", + " return;", + " }", + " start = stack.pop();", + " } else {", + " var i = 2 * Math.floor( Math.random() * ( neighbours.length / 2 ) )", + " l = neighbours[i]; maze[l.x][l.y] = 0;", + " l = neighbours[i + 1]; maze[l.x][l.y] = 0;", + " start = l", + " stack.push( start )", + " }", + " drawMaze();", + " requestAnimationFrame( createMaze );", + "}", + "function createCanvas( w, h ) {", + " var canvas = document.createElement( \"canvas\" );", + " wid = w; hei = h;", + " canvas.width = wid; canvas.height = hei;", + " canvas.id = \"canvas\";", + " ctx = canvas.getContext( \"2d\" );", + " ctx.fillStyle = \"black\"; ctx.fillRect( 0, 0, wid, hei );", + " document.body.appendChild( canvas ); ", + "}", + "function init() {", + " cols = 73; rows = 53;", + " createCanvas( grid * cols, grid * rows );", + " maze = createArray( cols, rows );", + " start.x = Math.floor( Math.random() * ( cols / 2 ) );", + " start.y = Math.floor( Math.random() * ( rows / 2 ) );", + " if( !( start.x & 1 ) ) start.x++; if( !( start.y & 1 ) ) start.y++;", + " maze[start.x][start.y] = 0;", + " createMaze();", + "}", + "", + "HTML to test.", + "
",
+      "",
+      "",
+      "Maze",
+      "",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f11", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nvar ctx, wid, hei, cols, rows, maze, stack = [], start = {x:-1, y:-1}, end = {x:-1, y:-1}, grid = 8;\nfunction drawMaze() {\n for( var i = 0; i < cols; i++ ) {\n for( var j = 0; j < rows; j++ ) {\n switch( maze[i][j] ) {\n case 0: ctx.fillStyle = \"black\"; break;\n case 1: ctx.fillStyle = \"green\"; break;\n case 2: ctx.fillStyle = \"red\"; break;\n case 3: ctx.fillStyle = \"yellow\"; break;\n case 4: ctx.fillStyle = \"#500000\"; break;\n }\n ctx.fillRect( grid * i, grid * j, grid, grid );\n }\n }\n}\nfunction getFNeighbours( sx, sy, a ) {\n var n = [];\n if( sx - 1 > 0 && maze[sx - 1][sy] == a ) {\n n.push( { x:sx - 1, y:sy } );\n }\n if( sx + 1 < cols - 1 && maze[sx + 1][sy] == a ) {\n n.push( { x:sx + 1, y:sy } );\n }\n if( sy - 1 > 0 && maze[sx][sy - 1] == a ) {\n n.push( { x:sx, y:sy - 1 } );\n }\n if( sy + 1 < rows - 1 && maze[sx][sy + 1] == a ) {\n n.push( { x:sx, y:sy + 1 } );\n }\n return n;\n}\nfunction solveMaze() {\n if( start.x == end.x && start.y == end.y ) {\n for( var i = 0; i < cols; i++ ) {\n for( var j = 0; j < rows; j++ ) {\n switch( maze[i][j] ) {\n case 2: maze[i][j] = 3; break;\n case 4: maze[i][j] = 0; break;\n }\n }\n }\n drawMaze();\n return;\n }\n var neighbours = getFNeighbours( start.x, start.y, 0 );\n if( neighbours.length ) {\n stack.push( start );\n start = neighbours[0];\n maze[start.x][start.y] = 2;\n } else {\n maze[start.x][start.y] = 4;\n start = stack.pop();\n }\n\n drawMaze();\n requestAnimationFrame( solveMaze );\n}\nfunction getCursorPos( event ) {\n var rect = this.getBoundingClientRect();\n var x = Math.floor( ( event.clientX - rect.left ) / grid ), \n y = Math.floor( ( event.clientY - rect.top ) / grid );\n if( maze[x][y] ) return;\n if( start.x == -1 ) {\n start = { x: x, y: y };\n } else {\n end = { x: x, y: y };\n maze[start.x][start.y] = 2;\n solveMaze();\n }\n}\nfunction getNeighbours( sx, sy, a ) {\n var n = [];\n if( sx - 1 > 0 && maze[sx - 1][sy] == a && sx - 2 > 0 && maze[sx - 2][sy] == a ) {\n n.push( { x:sx - 1, y:sy } ); n.push( { x:sx - 2, y:sy } );\n }\n if( sx + 1 < cols - 1 && maze[sx + 1][sy] == a && sx + 2 < cols - 1 && maze[sx + 2][sy] == a ) {\n n.push( { x:sx + 1, y:sy } ); n.push( { x:sx + 2, y:sy } );\n }\n if( sy - 1 > 0 && maze[sx][sy - 1] == a && sy - 2 > 0 && maze[sx][sy - 2] == a ) {\n n.push( { x:sx, y:sy - 1 } ); n.push( { x:sx, y:sy - 2 } );\n }\n if( sy + 1 < rows - 1 && maze[sx][sy + 1] == a && sy + 2 < rows - 1 && maze[sx][sy + 2] == a ) {\n n.push( { x:sx, y:sy + 1 } ); n.push( { x:sx, y:sy + 2 } );\n }\n return n;\n}\nfunction createArray( c, r ) {\n var m = new Array( c );\n for( var i = 0; i < c; i++ ) {\n m[i] = new Array( r );\n for( var j = 0; j < r; j++ ) {\n m[i][j] = 1;\n }\n }\n return m;\n}\nfunction createMaze() {\n var neighbours = getNeighbours( start.x, start.y, 1 ), l;\n if( neighbours.length < 1 ) {\n if( stack.length < 1 ) {\n drawMaze(); stack = [];\n start.x = start.y = -1;\n document.getElementById( \"canvas\" ).addEventListener( \"mousedown\", getCursorPos, false );\n return;\n }\n start = stack.pop();\n } else {\n var i = 2 * Math.floor( Math.random() * ( neighbours.length / 2 ) )\n l = neighbours[i]; maze[l.x][l.y] = 0;\n l = neighbours[i + 1]; maze[l.x][l.y] = 0;\n start = l\n stack.push( start )\n }\n drawMaze();\n requestAnimationFrame( createMaze );\n}\nfunction createCanvas( w, h ) {\n var canvas = document.createElement( \"canvas\" );\n wid = w; hei = h;\n canvas.width = wid; canvas.height = hei;\n canvas.id = \"canvas\";\n ctx = canvas.getContext( \"2d\" );\n ctx.fillStyle = \"black\"; ctx.fillRect( 0, 0, wid, hei );\n document.body.appendChild( canvas ); \n}\nfunction init() {\n cols = 73; rows = 53;\n createCanvas( grid * cols, grid * rows );\n maze = createArray( cols, rows );\n start.x = Math.floor( Math.random() * ( cols / 2 ) );\n start.y = Math.floor( Math.random() * ( rows / 2 ) );\n if( !( start.x & 1 ) ) start.x++; if( !( start.y & 1 ) ) start.y++;\n maze[start.x][start.y] = 0;\n createMaze();\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "MD4", + "type": "Waypoint", + "description": [ + "

Find the MD4 message digest of a string of octets.

", + "

Use the ASCII encoded string “Rosetta Code” (without quotes).

", + "

You may either call an MD4 library, or implement MD4 in your language.

MD4 is an obsolete hash function that computes a 128-bit message digest that sometimes appears in obsolete protocols.

RFC 1320 specifies the MD4 algorithm. RFC 6150 declares that MD4 is obsolete.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f12", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "MD5/Implementation", + "type": "Waypoint", + "description": [ + "

The purpose of this task to code and validate an implementation of the MD5 Message Digest Algorithm by coding the algorithm directly (not using a call to a built-in or external hashing library). For details of the algorithm refer to MD5 on Wikipedia or the MD5 definition in IETF RFC (1321).

The implementation needs to implement the key functionality namely producing a correct message digest for an input string. It is not necessary to mimic all of the calling modes such as adding to a digest one block at a time over subsequent calls. ", + "In addition to coding and verifying your implementation, note any challenges your language presented implementing the solution, implementation choices made, or limitations of your solution. ", + "Solutions on this page should implement MD5 directly and NOT use built in (MD5) functions, call outs to operating system calls or library routines written in other languages as is common in the original MD5 task.", + "The following are acceptable:", + "* An original implementation from the specification, reference implementation, or pseudo-code", + "* A translation of a correct implementation from another language", + "* A library routine in the same language; however, the source must be included here.", + "

The solutions shown here will provide practical illustrations of bit manipulation, unsigned integers, working with little-endian data. Additionally, the task requires an attention to details such as boundary conditions since being out by even 1 bit will produce dramatically different results. Subtle implementation bugs can result in some hashes being correct while others are wrong. Not only is it critical to get the individual sub functions working correctly, even small errors in padding, endianness, or data layout will result in failure.

The following verification strings and hashes come from RFC 1321:

                            hash code <== string ",
+      "   0xd41d8cd98f00b204e9800998ecf8427e <== \"\"  ",
+      "   0x0cc175b9c0f1b6a831c399e269772661 <== \"a\"",
+      "   0x900150983cd24fb0d6963f7d28e17f72 <== \"abc\"",
+      "   0xf96b697d7cb7938d525a2f31aaf161d0 <== \"message digest\"",
+      "   0xc3fcd3d76192e4007dfb496cca67e13b <== \"abcdefghijklmnopqrstuvwxyz\"",
+      "   0xd174ab98d277d9f5a5611c2c9f419d9f <== \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"",
+      "   0x57edf4a22be3c955ac49da2e2107b67a <== \"12345678901234567890123456789012345678901234567890123456789012345678901234567890\"

In addition, intermediate outputs to aid in developing an implementation can be found here.

The MD5 Message-Digest Algorithm was developed by RSA Data Security, Inc. in 1991.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f13", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "MD5", + "type": "Waypoint", + "description": [ + "Task:", + "

Encode a string using an MD5 algorithm. The algorithm can be found on Wikipedia.

", + "

Optionally, validate your implementation by running all of the test values in IETF RFC (1321) for MD5.

Additionally, RFC 1321 provides more precise information on the algorithm than the Wikipedia article.

", + "

If the solution on this page is a library solution, see MD5/Implementation for an implementation from scratch.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f14", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Median filter", + "type": "Waypoint", + "description": [ + "

The median filter takes in the neighbourhood the median color (see Median filter)

(to test the function below, you can use these input and output solutions)

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f15", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Metaprogramming", + "type": "Waypoint", + "description": [ + "

Name and briefly demonstrate any support your language has for metaprogramming. Your demonstration may take the form of cross-references to other tasks on Rosetta Code. When possible, provide links to relevant documentation.

For the purposes of this task, \"support for metaprogramming\" means any way the user can effectively modify the language's syntax that's built into the language (like Lisp macros) or that's conventionally used with the language (like the C preprocessor). Such facilities need not be very powerful: even user-defined infix operators count. On the other hand, in general, neither operator overloading nor eval count. The task author acknowledges that what qualifies as metaprogramming is largely a judgment call.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f19", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Metered concurrency", + "type": "Waypoint", + "description": [ + "

The goal of this task is to create a counting semaphore used to control the execution of a set of concurrent units. This task intends to demonstrate coordination of active concurrent units through the use of a passive concurrent unit. The operations for a counting semaphore are acquire, release, and count. Each active concurrent unit should attempt to acquire the counting semaphore before executing its assigned duties. In this case the active concurrent unit should report that it has acquired the semaphore. It should sleep for 2 seconds and then release the semaphore.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f1a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Metronome", + "type": "Waypoint", + "description": [ + "

", + "

The task is to implement a metronome.

The metronome should be capable of producing high and low audio beats, accompanied by a visual beat indicator, and the beat pattern and tempo should be configurable.

For the purpose of this task, it is acceptable to play sound files for production of the beat notes, and an external player may be used.

However, the playing of the sounds should not interfere with the timing of the metronome.

The visual indicator can simply be a blinking red or green area of the screen (depending on whether a high or low beat is being produced), and the metronome can be implemented using a terminal display, or optionally, a graphical display, depending on the language capabilities.

If the language has no facility to output sound, then it is permissible for this to implemented using just the visual indicator.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f1b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Middle three digits", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a function/procedure/subroutine that is called with an integer value and returns the middle three digits of the integer if possible or a clear indication of an error if this is not possible.

Note: The order of the middle digits should be preserved.

Your function should be tested with the following values; the first line should return valid answers, those of the second line should return clear indications of an error:

", + "
",
+      "123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345",
+      "1, 2, -1, -10, 2002, -2002, 0",
+      "
", + "

Show your output on this page.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function middleThree(x){", + " var n=''+Math.abs(x); var l=n.length-1;", + " if(l<2||l%2) throw new Error(x+': Invalid length '+(l+1));", + " return n.slice(l/2-1,l/2+2);", + "}", + "", + "[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345,", + "1, 2, -1, -10, 2002, -2002, 0].forEach(function(n){", + " try{console.log(n,middleThree(n))}catch(e){console.error(e.message)}", + "});", + "", + "
123 \"123\"",
+      "12345 \"234\"",
+      "1234567 \"345\"",
+      "987654321 \"654\"",
+      "10001 \"000\"",
+      "-10001 \"000\"",
+      "-123 \"123\"",
+      "-100 \"100\"",
+      "100 \"100\"",
+      "-12345 \"234\"",
+      "1: Invalid length 1",
+      "2: Invalid length 1",
+      "-1: Invalid length 1",
+      "-10: Invalid length 2",
+      "2002: Invalid length 4",
+      "-2002: Invalid length 4",
+      "0: Invalid length 1
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f1c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function middleThree(x){\n var n=''+Math.abs(x); var l=n.length-1;\n if(l<2||l%2) throw new Error(x+': Invalid length '+(l+1));\n return n.slice(l/2-1,l/2+2);\n}\n\n[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345,\n1, 2, -1, -10, 2002, -2002, 0].forEach(function(n){\n try{console.log(n,middleThree(n))}catch(e){console.error(e.message)}\n});\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Miller–Rabin primality test", + "type": "Waypoint", + "description": [ + "

The Miller–Rabin primality test or Rabin–Miller primality test is a primality test: an algorithm which determines whether a given number is prime or not.

The algorithm, as modified by Michael O. Rabin to avoid the generalized Riemann hypothesis, is a probabilistic algorithm.

The pseudocode, from Wikipedia is:

", + "

Input: n > 2, an odd integer to be tested for primality;

", + "

k, a parameter that determines the accuracy of the test

", + "

Output: composite if n is composite, otherwise probably prime

", + "

write n − 1 as 2s·d with d odd by factoring powers of 2 from n − 1

", + "

LOOP: repeat k times:

", + "

pick a randomly in the range [2, n − 1]

", + "

x ← ad mod n

", + "

if x = 1 or x = n − 1 then do next LOOP

", + "

for r = 1 .. s − 1

", + "

x ← x2 mod n

", + "

if x = 1 then return composite

", + "

if x = n − 1 then do next LOOP

", + "

return composite

", + "

return probably prime

The nature of the test involves big numbers, so the use of \"big numbers\" libraries (or similar features of the language of your choice) are suggested, but not mandatory.", + "Deterministic variants of the test exist and can be implemented as extra (not mandatory to complete the task)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "For the return values of this function, true means \"probably prime\" and false means \"definitely composite.\"", + "", + "function probablyPrime(n, k) {", + "\tif (n === 2 || n === 3)", + "\t\treturn true;", + "\tif (n % 2 === 0 || n < 2)", + "\t\treturn false;", + "", + "\t// Write (n - 1) as 2^s * d", + "\tvar s = 0, d = n - 1;", + "\twhile (d % 2 === 0) {", + "\t\td /= 2;", + "\t\t++s;", + "\t}", + "", + "\tWitnessLoop: do {", + "\t\t// A base between 2 and n - 2", + "\t\tvar x = Math.pow(2 + Math.floor(Math.random() * (n - 3)), d) % n;", + "", + "\t\tif (x === 1 || x === n - 1)", + "\t\t\tcontinue;", + "", + "\t\tfor (var i = s - 1; i--;) {", + "\t\t\tx = x * x % n;", + "\t\t\tif (x === 1)", + "\t\t\t\treturn false;", + "\t\t\tif (x === n - 1)", + "\t\t\t\tcontinue WitnessLoop;", + "\t\t}", + "", + "\t\treturn false;", + "\t} while (--k);", + "", + "\treturn true;", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f1d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function probablyPrime(n, k) {\n\tif (n === 2 || n === 3)\n\t\treturn true;\n\tif (n % 2 === 0 || n < 2)\n\t\treturn false;\n\n\t// Write (n - 1) as 2^s * d\n\tvar s = 0, d = n - 1;\n\twhile (d % 2 === 0) {\n\t\td /= 2;\n\t\t++s;\n\t}\n\n\tWitnessLoop: do {\n\t\t// A base between 2 and n - 2\n\t\tvar x = Math.pow(2 + Math.floor(Math.random() * (n - 3)), d) % n;\n\n\t\tif (x === 1 || x === n - 1)\n\t\t\tcontinue;\n\n\t\tfor (var i = s - 1; i--;) {\n\t\t\tx = x * x % n;\n\t\t\tif (x === 1)\n\t\t\t\treturn false;\n\t\t\tif (x === n - 1)\n\t\t\t\tcontinue WitnessLoop;\n\t\t}\n\n\t\treturn false;\n\t} while (--k);\n\n\treturn true;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Modular exponentiation", + "type": "Waypoint", + "description": [ + "

Find the last 40 decimal digits of $a^b$, where

$a = 2988348162058574136915891421498819466320163312926952423791023078876139$", + "$b = 2351399303373464486466122544523690094744975233415544072992656881240319$", + "

A computer is too slow to find the entire value of $a^b$.

Instead, the program must use a fast algorithm for modular exponentiation: $a^b \\mod m$.

The algorithm must work for any integers $a, b, m$ where $b \\ge 0$ and $m > 0$.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f1f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Modular inverse", + "type": "Waypoint", + "description": [ + "

From Wikipedia:

In modular arithmetic, the modular multiplicative inverse of an integer a modulo m is an integer x such that

:$a\\,x \\equiv 1 \\pmod{m}.$

Or in other words, such that:

:$\\exists k \\in\\Z,\\qquad a\\, x = 1 + k\\,m$

It can be shown that such an inverse exists if and only if a and m are coprime, but we will ignore this for this task.

", + "Task:", + "

Either by implementing the algorithm, by using a dedicated library or by using a built-in function in

", + "

your language, compute the modular inverse of 42 modulo 2017.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Using brute force.", + "var modInverse = function(a, b) {", + " a %= b;", + " for (var x = 1; x < b; x++) {", + " if ((a*x)%b == 1) {", + " return x;", + " }", + " }", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f20", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var modInverse = function(a, b) {\n a %= b;\n for (var x = 1; x < b; x++) {\n if ((a*x)%b == 1) {\n return x;\n }\n }\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Monte Carlo methods", + "type": "Waypoint", + "description": [ + "

A Monte Carlo Simulation is a way of approximating the value of a function

", + "

where calculating the actual value is difficult or impossible.

", + "

It uses random sampling to define constraints on the value

", + "

and then makes a sort of \"best guess.\"

A simple Monte Carlo Simulation can be used to calculate the value for $\\pi$.

If you had a circle and a square where the length of a side of the square

", + "

was the same as the diameter of the circle, the ratio of the area of the circle

", + "

to the area of the square would be $\\pi/4$.

So, if you put this circle inside the square and select many random points

", + "

inside the square, the number of points inside the circle

", + "

divided by the number of points inside the square and the circle

", + "

would be approximately $\\pi/4$.

", + "Task:", + "

Write a function to run a simulation like this, with a variable number of random points to select.

Also, show the results of a few different sample sizes.

For software where the number $\\pi$ is not built-in,

", + "

we give $\\pi$ as a number of digits:

", + "

3.141592653589793238462643383280

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "function mcpi(n) {", + " var x, y, m = 0;", + "", + " for (var i = 0; i < n; i += 1) {", + " x = Math.random();", + " y = Math.random();", + "", + " if (x * x + y * y < 1) {", + " m += 1;", + " }", + " }", + "", + " return 4 * m / n;", + "}", + "", + "console.log(mcpi(1000));", + "console.log(mcpi(10000));", + "console.log(mcpi(100000));", + "console.log(mcpi(1000000));", + "console.log(mcpi(10000000));", + "
3.168",
+      "3.1396",
+      "3.13692",
+      "3.140512",
+      "3.1417656",
+      "
", + "", + "===ES6===", + "(() => {", + " 'use strict';", + "", + " // monteCarloPi :: Int -> Float", + " const monteCarloPi = n =>", + " 4 * range(1, n)", + " .reduce(a => {", + " const [x, y] = [rnd(), rnd()];", + " return x * x + y * y < 1 ? a + 1 : a;", + " }, 0) / n;", + "", + "", + " // GENERIC FUNCTIONS", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // rnd :: () -> Float", + " const rnd = Math.random;", + "", + "", + " // TEST with from 1000 samples to 10E8 samples", + " return range(3, 8)", + " .map(x => monteCarloPi(Math.pow(10, x)));", + "", + " // e.g. -> [3.14, 3.1404, 3.13304, 3.142408, 3.1420304, 3.14156788]", + "})();", + "", + "", + "{{Out}} (5 sample runs with increasing sample sizes)", + "[3.14, 3.1404, 3.13304, 3.142408, 3.1420304, 3.14156788]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f21", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function mcpi(n) {\n var x, y, m = 0;\n\n for (var i = 0; i < n; i += 1) {\n x = Math.random();\n y = Math.random();\n\n if (x * x + y * y < 1) {\n m += 1;\n }\n }\n\n return 4 * m / n;\n}\n\nconsole.log(mcpi(1000));\nconsole.log(mcpi(10000));\nconsole.log(mcpi(100000));\nconsole.log(mcpi(1000000));\nconsole.log(mcpi(10000000));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Monty Hall problem", + "type": "Waypoint", + "description": [ + "

Run random simulations of the Monty Hall game. Show the effects of a strategy of the contestant always keeping his first guess so it can be contrasted with the strategy of the contestant always switching his guess.

Suppose you're on a game show and you're given the choice of three doors. Behind one door is a car; behind the others, goats. The car and the goats were placed randomly behind the doors before the show. The rules of the game show are as follows: After you have chosen a door, the door remains closed for the time being. The game show host, Monty Hall, who knows what is behind the doors, now has to open one of the two remaining doors, and the door he opens must have a goat behind it. If both remaining doors have goats behind them, he chooses one randomly. After Monty Hall opens a door with a goat, he will ask you to decide whether you want to stay with your first choice or to switch to the last remaining door. Imagine that you chose Door 1 and the host opens Door 3, which has a goat. He then asks you \"Do you want to switch to Door Number 2?\" Is it to your advantage to change your choice? (Krauss and Wang 2003:10)

Note that the player may initially choose any of the three doors (not just Door 1), that the host opens a different door revealing a goat (not necessarily Door 3), and that he gives the player a second choice between the two remaining unopened doors.

", + "Task:", + "

Simulate at least a thousand games using three doors for each strategy and show the results in such a way as to make it easy to compare the effects of each strategy.

", + "Reference:", + "Monty Hall Problem - Numberphile. (Video)." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Extensive Solution===", + "", + "This solution can test with n doors, the difference in probability for switching is shown to diminish as the number of doors increases.", + "", + "", + "function montyhall(tests, doors) {", + "\t'use strict';", + "\ttests = tests ? tests : 1000;", + "\tdoors = doors ? doors : 3;", + "\tvar prizeDoor, chosenDoor, shownDoor, switchDoor, chosenWins = 0, switchWins = 0;", + "\t", + "\t// randomly pick a door excluding input doors", + "\tfunction pick(excludeA, excludeB) {", + "\t\tvar door;", + "\t\tdo {", + "\t\t\tdoor = Math.floor(Math.random() * doors);", + "\t\t} while (door === excludeA || door === excludeB);", + "\t\treturn door;", + "\t}", + "\t", + "\t// run tests", + "\tfor (var i = 0; i < tests; i ++) {", + "\t\t", + "\t\t// pick set of doors", + "\t\tprizeDoor = pick();", + "\t\tchosenDoor = pick();", + "\t\tshownDoor = pick(prizeDoor, chosenDoor);", + "\t\tswitchDoor = pick(chosenDoor, shownDoor);", + "", + "\t\t// test set for both choices", + "\t\tif (chosenDoor === prizeDoor) {", + "\t\t\tchosenWins ++;", + "\t\t} else if (switchDoor === prizeDoor) {", + "\t\t\tswitchWins ++;", + "\t\t}", + "\t}", + "\t", + "\t// results", + "\treturn {", + "\t\tstayWins: chosenWins + ' ' + (100 * chosenWins / tests) + '%',", + "\t\tswitchWins: switchWins + ' ' + (100 * switchWins / tests) + '%'", + "\t};", + "}", + "", + "", + "{{out}}", + "", + "montyhall(1000, 3)", + "Object {stayWins: \"349 34.9%\", switchWins: \"651 65.1%\"}", + "montyhall(1000, 4)", + "Object {stayWins: \"253 25.3%\", switchWins: \"384 38.4%\"}", + "montyhall(1000, 5)", + "Object {stayWins: \"202 20.2%\", switchWins: \"265 26.5%\"}", + "", + "", + "===Basic Solution===", + "", + "", + "", + "var totalGames = 10000,", + " selectDoor = function () {", + "\treturn Math.floor(Math.random() * 3); // Choose a number from 0, 1 and 2.", + " },", + " games = (function () {", + "\tvar i = 0, games = [];", + "", + "\tfor (; i < totalGames; ++i) {", + "\t games.push(selectDoor()); // Pick a door which will hide the prize.", + "\t}", + "", + "\treturn games;", + " }()),", + " play = function (switchDoor) {", + "\tvar i = 0, j = games.length, winningDoor, randomGuess, totalTimesWon = 0;", + "", + "\tfor (; i < j; ++i) {", + "\t winningDoor = games[i];", + "\t randomGuess = selectDoor();", + "\t if ((randomGuess === winningDoor && !switchDoor) || ", + "\t\t(randomGuess !== winningDoor && switchDoor)) ", + "\t {", + "\t\t/*", + "\t\t * If I initially guessed the winning door and didn't switch,", + "\t\t * or if I initially guessed a losing door but then switched,", + "\t\t * I've won.", + "\t\t *", + "\t\t * The only time I lose is when I initially guess the winning door ", + "\t\t * and then switch.", + "\t\t */", + "", + "\t\ttotalTimesWon++;", + "\t }", + "\t}", + "\treturn totalTimesWon;", + " };", + "", + "/*", + " * Start the simulation", + " */", + "", + "console.log(\"Playing \" + totalGames + \" games\");", + "console.log(\"Wins when not switching door\", play(false));", + "console.log(\"Wins when switching door\", play(true));", + "", + "", + "{{out}}", + "", + "Playing 10000 games", + "Wins when not switching door 3326", + "Wins when switching door 6630", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f22", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nfunction montyhall(tests, doors) {\n\t'use strict';\n\ttests = tests ? tests : 1000;\n\tdoors = doors ? doors : 3;\n\tvar prizeDoor, chosenDoor, shownDoor, switchDoor, chosenWins = 0, switchWins = 0;\n\t\n\t// randomly pick a door excluding input doors\n\tfunction pick(excludeA, excludeB) {\n\t\tvar door;\n\t\tdo {\n\t\t\tdoor = Math.floor(Math.random() * doors);\n\t\t} while (door === excludeA || door === excludeB);\n\t\treturn door;\n\t}\n\t\n\t// run tests\n\tfor (var i = 0; i < tests; i ++) {\n\t\t\n\t\t// pick set of doors\n\t\tprizeDoor = pick();\n\t\tchosenDoor = pick();\n\t\tshownDoor = pick(prizeDoor, chosenDoor);\n\t\tswitchDoor = pick(chosenDoor, shownDoor);\n\n\t\t// test set for both choices\n\t\tif (chosenDoor === prizeDoor) {\n\t\t\tchosenWins ++;\n\t\t} else if (switchDoor === prizeDoor) {\n\t\t\tswitchWins ++;\n\t\t}\n\t}\n\t\n\t// results\n\treturn {\n\t\tstayWins: chosenWins + ' ' + (100 * chosenWins / tests) + '%',\n\t\tswitchWins: switchWins + ' ' + (100 * switchWins / tests) + '%'\n\t};\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Morse code", + "type": "Waypoint", + "description": [ + "

Morse code is one of the simplest and most versatile methods of telecommunication in existence.

", + "

It has been in use for more than 160 years — longer than any other electronic encoding system.

", + "Task:", + "

Send a string as audible Morse code to an audio device (e.g., the PC speaker).

", + "

As the standard Morse code does not contain all possible characters,

", + "

you may either ignore unknown characters in the file,

", + "

or indicate them somehow (e.g. with a different pitch).

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "This implementation utilises the fairly new Web Audio API in the browser for generating tones, as such it only uses one vendor implementation (WebKit). It is split into three modules; 1. translating the characters into morse code. 2. creating timings for the morse code. 3. creating tones with the timings.", + "", + "", + "var globalAudioContext = new webkitAudioContext();", + "", + "function morsecode(text, unit, freq) {", + "\t'use strict';", + "", + "\t// defaults", + "\tunit = unit ? unit : 0.05;", + "\tfreq = freq ? freq : 700;", + "\tvar cont = globalAudioContext;", + "\tvar time = cont.currentTime;", + "", + "\t// morsecode", + "\tvar code = {", + "\t\ta: '._', b: '_...', c: '_._.', d: '_..', e: '.', f: '.._.',", + "\t\tg: '__.', h: '....', i: '..', j: '.___', k: '_._', l: '._..',", + "\t\tm: '__', n: '_.', o: '___', p: '.__.', q: '__._', r: '._.',", + "\t\ts: '...', t: '_', u: '.._', v: '..._', w: '.__', x: '_.._',", + "\t\ty: '_.__', z: '__..', 0: '_____', 1: '.____', 2: '..___', 3: '...__',", + "\t\t4: '...._', 5: '.....', 6: '_....', 7: '__...', 8: '___..', 9: '____.'", + "\t};", + "", + "\t// generate code for text", + "\tfunction makecode(data) {", + "\t\tfor (var i = 0; i <= data.length; i ++) {", + "\t\t\tvar codedata = data.substr(i, 1).toLowerCase();", + "\t\t\tcodedata = code[codedata];", + "\t\t\t// recognised character", + "\t\t\tif (codedata !== undefined) {", + "\t\t\t\tmaketime(codedata);", + "\t\t\t}", + "\t\t\t// unrecognised character", + "\t\t\telse {", + "\t\t\t\ttime += unit * 7;", + "\t\t\t}", + "\t\t}", + "\t}", + "", + "\t// generate time for code", + "\tfunction maketime(data) {", + "\t\tfor (var i = 0; i <= data.length; i ++) {", + "\t\t\tvar timedata = data.substr(i, 1);", + "\t\t\ttimedata = (timedata === '.') ? 1 : (timedata === '_') ? 3 : 0;", + "\t\t\ttimedata *= unit;", + "\t\t\tif (timedata > 0) {", + "\t\t\t\tmaketone(timedata);", + "\t\t\t\ttime += timedata;", + "\t\t\t\t// tone gap", + "\t\t\t\ttime += unit * 1;", + "\t\t\t}", + "\t\t}", + "\t\t// char gap", + "\t\ttime += unit * 2;", + "\t}", + "", + "\t// generate tone for time", + "\tfunction maketone(data) {", + "\t\tvar start = time;", + "\t\tvar stop = time + data;", + "\t\t// filter: envelope the tone slightly", + "\t\tgain.gain.linearRampToValueAtTime(0, start);", + "\t\tgain.gain.linearRampToValueAtTime(1, start + (unit / 8));", + "\t\tgain.gain.linearRampToValueAtTime(1, stop - (unit / 16));", + "\t\tgain.gain.linearRampToValueAtTime(0, stop);", + "\t}", + "", + "\t// create: oscillator, gain, destination", + "\tvar osci = cont.createOscillator();", + "\tosci.frequency.value = freq;", + "\tvar gain = cont.createGainNode();", + "\tgain.gain.value = 0;", + "\tvar dest = cont.destination;", + "\t// connect: oscillator -> gain -> destination", + "\tosci.connect(gain);", + "\tgain.connect(dest);", + "\t// start oscillator", + "\tosci.start(time);", + "", + "\t// begin encoding: text -> code -> time -> tone", + "\tmakecode(text);", + "", + "\t// return web audio context for reuse / control", + "\treturn cont;", + "}", + "", + "", + "Usage:", + "", + "", + "morsecode('Hello World');", + "", + "", + "{{out}}", + "", + "[http://jsbin.com/orubaq/1/edit Live Version]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f23", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nvar globalAudioContext = new webkitAudioContext();\n\nfunction morsecode(text, unit, freq) {\n\t'use strict';\n\n\t// defaults\n\tunit = unit ? unit : 0.05;\n\tfreq = freq ? freq : 700;\n\tvar cont = globalAudioContext;\n\tvar time = cont.currentTime;\n\n\t// morsecode\n\tvar code = {\n\t\ta: '._', b: '_...', c: '_._.', d: '_..', e: '.', f: '.._.',\n\t\tg: '__.', h: '....', i: '..', j: '.___', k: '_._', l: '._..',\n\t\tm: '__', n: '_.', o: '___', p: '.__.', q: '__._', r: '._.',\n\t\ts: '...', t: '_', u: '.._', v: '..._', w: '.__', x: '_.._',\n\t\ty: '_.__', z: '__..', 0: '_____', 1: '.____', 2: '..___', 3: '...__',\n\t\t4: '...._', 5: '.....', 6: '_....', 7: '__...', 8: '___..', 9: '____.'\n\t};\n\n\t// generate code for text\n\tfunction makecode(data) {\n\t\tfor (var i = 0; i <= data.length; i ++) {\n\t\t\tvar codedata = data.substr(i, 1).toLowerCase();\n\t\t\tcodedata = code[codedata];\n\t\t\t// recognised character\n\t\t\tif (codedata !== undefined) {\n\t\t\t\tmaketime(codedata);\n\t\t\t}\n\t\t\t// unrecognised character\n\t\t\telse {\n\t\t\t\ttime += unit * 7;\n\t\t\t}\n\t\t}\n\t}\n\n\t// generate time for code\n\tfunction maketime(data) {\n\t\tfor (var i = 0; i <= data.length; i ++) {\n\t\t\tvar timedata = data.substr(i, 1);\n\t\t\ttimedata = (timedata === '.') ? 1 : (timedata === '_') ? 3 : 0;\n\t\t\ttimedata *= unit;\n\t\t\tif (timedata > 0) {\n\t\t\t\tmaketone(timedata);\n\t\t\t\ttime += timedata;\n\t\t\t\t// tone gap\n\t\t\t\ttime += unit * 1;\n\t\t\t}\n\t\t}\n\t\t// char gap\n\t\ttime += unit * 2;\n\t}\n\n\t// generate tone for time\n\tfunction maketone(data) {\n\t\tvar start = time;\n\t\tvar stop = time + data;\n\t\t// filter: envelope the tone slightly\n\t\tgain.gain.linearRampToValueAtTime(0, start);\n\t\tgain.gain.linearRampToValueAtTime(1, start + (unit / 8));\n\t\tgain.gain.linearRampToValueAtTime(1, stop - (unit / 16));\n\t\tgain.gain.linearRampToValueAtTime(0, stop);\n\t}\n\n\t// create: oscillator, gain, destination\n\tvar osci = cont.createOscillator();\n\tosci.frequency.value = freq;\n\tvar gain = cont.createGainNode();\n\tgain.gain.value = 0;\n\tvar dest = cont.destination;\n\t// connect: oscillator -> gain -> destination\n\tosci.connect(gain);\n\tgain.connect(dest);\n\t// start oscillator\n\tosci.start(time);\n\n\t// begin encoding: text -> code -> time -> tone\n\tmakecode(text);\n\n\t// return web audio context for reuse / control\n\treturn cont;\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Move-to-front algorithm", + "type": "Waypoint", + "description": [ + "

Given a symbol table of a zero-indexed array of all possible input symbols

", + "

this algorithm reversibly transforms a sequence

", + "

of input symbols into an array of output numbers (indices).

", + "

The transform in many cases acts to give frequently repeated input symbols

", + "

lower indices which is useful in some compression algorithms.

Encoding algorithm:", + "
",
+      "    for each symbol of the input sequence:",
+      "        output the index of the symbol in the symbol table",
+      "        move that symbol to the front of the symbol table",
+      "
Decoding algorithm:", + "
",
+      "    # Using the same starting symbol table",
+      "    for each index of the input sequence:",
+      "        output the symbol at that index of the symbol table",
+      "        move that symbol to the front of the symbol table",
+      "
Example:", + "

Encoding the string of character symbols 'broood' using a symbol table of

", + "

the characters 'a'-to-'z'

{| border=\"1\"

", + "

|-

", + "

! Input

", + "

! Output

", + "

! SymbolTable

", + "

|-

", + "

| broood

", + "

| 1

", + "

| 'abcdefghijklmnopqrstuvwxyz'

", + "

|-

", + "

| broood

", + "

| 1 17

", + "

| 'bacdefghijklmnopqrstuvwxyz'

", + "

|-

", + "

| broood

", + "

| 1 17 15

", + "

| 'rbacdefghijklmnopqstuvwxyz'

", + "

|-

", + "

| broood

", + "

| 1 17 15 0

", + "

| 'orbacdefghijklmnpqstuvwxyz'

", + "

|-

", + "

| broood

", + "

| 1 17 15 0 0

", + "

| 'orbacdefghijklmnpqstuvwxyz'

", + "

|-

", + "

| broood

", + "

| 1 17 15 0 0 5

", + "

| 'orbacdefghijklmnpqstuvwxyz'

", + "

|}

Decoding the indices back to the original symbol order:

", + "

{| border=\"1\"

", + "

|-

", + "

! Input

", + "

! Output

", + "

! SymbolTable

", + "

|-

", + "

| 1 17 15 0 0 5

", + "

| b

", + "

| 'abcdefghijklmnopqrstuvwxyz'

", + "

|-

", + "

| 1 17 15 0 0 5

", + "

| br

", + "

| 'bacdefghijklmnopqrstuvwxyz'

", + "

|-

", + "

| 1 17 15 0 0 5

", + "

| bro

", + "

| 'rbacdefghijklmnopqstuvwxyz'

", + "

|-

", + "

| 1 17 15 0 0 5

", + "

| broo

", + "

| 'orbacdefghijklmnpqstuvwxyz'

", + "

|-

", + "

| 1 17 15 0 0 5

", + "

| brooo

", + "

| 'orbacdefghijklmnpqstuvwxyz'

", + "

|-

", + "

| 1 17 15 0 0 5

", + "

| broood

", + "

| 'orbacdefghijklmnpqstuvwxyz'

", + "

|}

Task:", + "Encode and decode the following three strings of characters using the symbol table of the characters 'a'-to-'z' as above. ", + "Show the strings and their encoding here.", + "Add a check to ensure that the decoded string is the same as the original.", + "

The strings are:

broood

", + "

bananaaa

", + "

hiphophiphop

(Note the spellings.)

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var encodeMTF = function (word) {", + " var init = {wordAsNumbers: [], charList: 'abcdefghijklmnopqrstuvwxyz'.split('')};", + "", + " return word.split('').reduce(function (acc, char) {", + " var charNum = acc.charList.indexOf(char); //get index of char", + " acc.wordAsNumbers.push(charNum); //add original index to acc", + " acc.charList.unshift(acc.charList.splice(charNum, 1)[0]); //put at beginning of list", + " return acc;", + " }, init).wordAsNumbers; //return number list", + "};", + "", + "var decodeMTF = function (numList) {", + " var init = {word: '', charList: 'abcdefghijklmnopqrstuvwxyz'.split('')};", + "", + " return numList.reduce(function (acc, num) {", + " acc.word += acc.charList[num];", + " acc.charList.unshift(acc.charList.splice(num, 1)[0]); //put at beginning of list", + " return acc;", + " }, init).word;", + "};", + "", + "//test our algorithms", + "var words = ['broood', 'bananaaa', 'hiphophiphop'];", + "var encoded = words.map(encodeMTF);", + "var decoded = encoded.map(decodeMTF);", + "", + "//print results", + "console.log(\"from encoded:\");", + "console.log(encoded);", + "console.log(\"from decoded:\");", + "console.log(decoded);", + "{{out}}", + "
from encoded:",
+      "[",
+      "  [1, 17, 15, 0, 0, 5],",
+      "  [1, 1, 13, 1, 1, 1, 0, 0],",
+      "  [7, 8, 15, 2, 15, 2, 2, 3, 2, 2, 3, 2]",
+      "]",
+      "from decoded:",
+      "['broood', 'bananaaa', 'hiphophiphop']
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f25", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var encodeMTF = function (word) {\n var init = {wordAsNumbers: [], charList: 'abcdefghijklmnopqrstuvwxyz'.split('')};\n\n return word.split('').reduce(function (acc, char) {\n var charNum = acc.charList.indexOf(char); //get index of char\n acc.wordAsNumbers.push(charNum); //add original index to acc\n acc.charList.unshift(acc.charList.splice(charNum, 1)[0]); //put at beginning of list\n return acc;\n }, init).wordAsNumbers; //return number list\n};\n\nvar decodeMTF = function (numList) {\n var init = {word: '', charList: 'abcdefghijklmnopqrstuvwxyz'.split('')};\n\n return numList.reduce(function (acc, num) {\n acc.word += acc.charList[num];\n acc.charList.unshift(acc.charList.splice(num, 1)[0]); //put at beginning of list\n return acc;\n }, init).word;\n};\n\n//test our algorithms\nvar words = ['broood', 'bananaaa', 'hiphophiphop'];\nvar encoded = words.map(encodeMTF);\nvar decoded = encoded.map(decodeMTF);\n\n//print results\nconsole.log(\"from encoded:\");\nconsole.log(encoded);\nconsole.log(\"from decoded:\");\nconsole.log(decoded);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Multifactorial", + "type": "Waypoint", + "description": [ + "

The factorial of a number, written as $n!$, is defined as $n! = n(n-1)(n-2)...(2)(1)$.

Multifactorials generalize factorials as follows:

", + "

$n! = n(n-1)(n-2)...(2)(1)$

", + "

$n!! = n(n-2)(n-4)...$

", + "

$n!! ! = n(n-3)(n-6)...$

", + "

$n!! !! = n(n-4)(n-8)...$

", + "

$n!! !! ! = n(n-5)(n-10)...$

In all cases, the terms in the products are positive integers.

If we define the degree of the multifactorial as the difference in successive terms that are multiplied together for a multifactorial (the number of exclamation marks), then the task is twofold:

", + "Write a function that given n and the degree, calculates the multifactorial.", + "Use the function to generate and display here a table of the first ten members (1 to 10) of the first five degrees of multifactorial.

Note: The wikipedia entry on multifactorials gives a different formula. This task uses the Wolfram mathworld definition.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Iterative===", + "{{trans|C}}", + "", + "function multifact(n, deg){", + "\tvar result = n;", + "\twhile (n >= deg + 1){", + "\t\tresult *= (n - deg);", + "\t\tn -= deg;", + "\t}", + "\treturn result;", + "}", + "", + "", + "", + "function test (n, deg) {", + "\tfor (var i = 1; i <= deg; i ++) {", + "\t\tvar results = '';", + "\t\tfor (var j = 1; j <= n; j ++) {", + "\t\t\tresults += multifact(j, i) + ' ';", + "\t\t}", + "\t\tconsole.log('Degree ' + i + ': ' + results);", + "\t}", + "}", + "", + "", + "{{out}}", + "", + "test(10, 5)", + "Degree 1: 1 2 6 24 120 720 5040 40320 362880 3628800 ", + "Degree 2: 1 2 3 8 15 48 105 384 945 3840 ", + "Degree 3: 1 2 3 4 10 18 28 80 162 280 ", + "Degree 4: 1 2 3 4 5 12 21 32 45 120 ", + "Degree 5: 1 2 3 4 5 6 14 24 36 50 ", + "", + "", + "===Recursive===", + "", + "{{trans|C}}", + "function multifact(n, deg){", + " return n <= deg ? n : n * multifact(n - deg, deg);", + "}", + "", + "{{test}}", + "function test (n, deg) {", + " for (var i = 1; i <= deg; i ++) {", + " var results = '';", + " for (var j = 1; j <= n; j ++) {", + " results += multifact(j, i) + ' ';", + " }", + " console.log('Degree ' + i + ': ' + results);", + " }", + "}", + "{{Out}}", + "", + "test(10, 5)", + "Degree 1: 1 2 6 24 120 720 5040 40320 362880 3628800 ", + "Degree 2: 1 2 3 8 15 48 105 384 945 3840 ", + "Degree 3: 1 2 3 4 10 18 28 80 162 280 ", + "Degree 4: 1 2 3 4 5 12 21 32 45 120 ", + "Degree 5: 1 2 3 4 5 6 14 24 36 50 ", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f26", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nfunction multifact(n, deg){\n\tvar result = n;\n\twhile (n >= deg + 1){\n\t\tresult *= (n - deg);\n\t\tn -= deg;\n\t}\n\treturn result;\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Multiple distinct objects", + "type": "Waypoint", + "description": [ + "

Create a sequence (array, list, whatever) consisting of n distinct, initialized items of the same type. n should be determined at runtime.

By distinct we mean that if they are mutable, changes to one do not affect all others; if there is an appropriate equality operator they are considered unequal; etc. The code need not specify a particular kind of distinction, but do not use e.g. a numeric-range generator which does not generalize.

By initialized we mean that each item must be in a well-defined state appropriate for its type, rather than e.g. arbitrary previous memory contents in an array allocation. Do not show only an initialization technique which initializes only to \"zero\" values (e.g. calloc() or int a[n] = {}; in C), unless user-defined types can provide definitions of \"zero\" for that type.

This task was inspired by the common error of intending to do this, but instead creating a sequence of n references to the same mutable object; it might be informative to show the way to do that as well, both as a negative example and as how to do it when that's all that's actually necessary.

This task is most relevant to languages operating in the pass-references-by-value style (most object-oriented, garbage-collected, and/or 'dynamic' languages).

See also: Closures/Value capture

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "var a = new Array(n);", + "for (var i = 0; i < n; i++)", + " a[i] = new Foo();", + "", + "", + "===ES6===", + "", + "(n => {", + "", + " let nObjects = n => Array.from({", + " length: n + 1", + " }, (_, i) => {", + " // optionally indexed object constructor", + " return {", + " index: i", + " };", + " });", + "", + " return nObjects(6);", + "", + "})(6);", + "", + "", + "{{Out}}", + "[{\"index\":0}, {\"index\":1}, {\"index\":2}, {\"index\":3}, ", + "{\"index\":4}, {\"index\":5}, {\"index\":6}]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f27", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var a = new Array(n);\nfor (var i = 0; i < n; i++)\n a[i] = new Foo();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Multiple regression", + "type": "Waypoint", + "description": [ + "Task:", + "

Given a set of data vectors in the following format:

$y = \\{ y_1, y_2, ..., y_n \\}\\,$

$X_i = \\{ x_{i1}, x_{i2}, ..., x_{in} \\}, i \\in 1..k\\,$

Compute the vector $\\beta = \\{ \\beta_1, \\beta_2, ..., \\beta_k \\}$ using ordinary least squares regression using the following equation:

$y_j = \\Sigma_i \\beta_i \\cdot x_{ij} , j \\in 1..n$

You can assume y is given to you as a vector (a one-dimensional array), and X is given to you as a two-dimensional array (i.e. matrix).

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|SpiderMonkey}} for the print() and ''Array''.map() functions.", + "", + "{{trans|Ruby}}", + "", + "Extends the Matrix class from [[Matrix Transpose#JavaScript]], [[Matrix multiplication#JavaScript]], [[Reduced row echelon form#JavaScript]].", + "Uses the IdentityMatrix from [[Matrix exponentiation operator#JavaScript]]", + "// modifies the matrix \"in place\"", + "Matrix.prototype.inverse = function() {", + " if (this.height != this.width) {", + " throw \"can't invert a non-square matrix\";", + " } ", + "", + " var I = new IdentityMatrix(this.height);", + " for (var i = 0; i < this.height; i++) ", + " this.mtx[i] = this.mtx[i].concat(I.mtx[i])", + " this.width *= 2;", + "", + " this.toReducedRowEchelonForm();", + "", + " for (var i = 0; i < this.height; i++) ", + " this.mtx[i].splice(0, this.height);", + " this.width /= 2;", + "", + " return this;", + "}", + "", + "function ColumnVector(ary) {", + " return new Matrix(ary.map(function(v) {return [v]}))", + "}", + "ColumnVector.prototype = Matrix.prototype", + "", + "Matrix.prototype.regression_coefficients = function(x) {", + " var x_t = x.transpose();", + " return x_t.mult(x).inverse().mult(x_t).mult(this);", + "}", + "", + "// the Ruby example", + "var y = new ColumnVector([1,2,3,4,5]);", + "var x = new ColumnVector([2,1,3,4,5]);", + "print(y.regression_coefficients(x));", + "print();", + "", + "// the Tcl example", + "y = new ColumnVector([", + " 52.21, 53.12, 54.48, 55.84, 57.20, 58.57, 59.93, 61.29, ", + " 63.11, 64.47, 66.28, 68.10, 69.92, 72.19, 74.46", + "]);", + "x = new Matrix(", + " [1.47,1.50,1.52,1.55,1.57,1.60,1.63,1.65,1.68,1.70,1.73,1.75,1.78,1.80,1.83].map(", + " function(v) {return [Math.pow(v,0), Math.pow(v,1), Math.pow(v,2)]}", + " )", + ");", + "print(y.regression_coefficients(x));", + "{{out}}", + "
0.9818181818181818",
+      "",
+      "128.8128035798277",
+      "-143.1620228653037",
+      "61.960325442985436
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f28", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// modifies the matrix \"in place\"\nMatrix.prototype.inverse = function() {\n if (this.height != this.width) {\n throw \"can't invert a non-square matrix\";\n } \n\n var I = new IdentityMatrix(this.height);\n for (var i = 0; i < this.height; i++) \n this.mtx[i] = this.mtx[i].concat(I.mtx[i])\n this.width *= 2;\n\n this.toReducedRowEchelonForm();\n\n for (var i = 0; i < this.height; i++) \n this.mtx[i].splice(0, this.height);\n this.width /= 2;\n\n return this;\n}\n\nfunction ColumnVector(ary) {\n return new Matrix(ary.map(function(v) {return [v]}))\n}\nColumnVector.prototype = Matrix.prototype\n\nMatrix.prototype.regression_coefficients = function(x) {\n var x_t = x.transpose();\n return x_t.mult(x).inverse().mult(x_t).mult(this);\n}\n\n// the Ruby example\nvar y = new ColumnVector([1,2,3,4,5]);\nvar x = new ColumnVector([2,1,3,4,5]);\nprint(y.regression_coefficients(x));\nprint();\n\n// the Tcl example\ny = new ColumnVector([\n 52.21, 53.12, 54.48, 55.84, 57.20, 58.57, 59.93, 61.29, \n 63.11, 64.47, 66.28, 68.10, 69.92, 72.19, 74.46\n]);\nx = new Matrix(\n [1.47,1.50,1.52,1.55,1.57,1.60,1.63,1.65,1.68,1.70,1.73,1.75,1.78,1.80,1.83].map(\n function(v) {return [Math.pow(v,0), Math.pow(v,1), Math.pow(v,2)]}\n )\n);\nprint(y.regression_coefficients(x));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Multiplication tables", + "type": "Waypoint", + "description": [ + "Task:", + "

Produce a formatted 12×12 multiplication table of the kind memorized by rote when in primary (or elementary) school.

", + "

Only print the top half triangle of products.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Imperative===", + "", + "", + "", + "", + "12 times table", + "", + "", + "", + "", + "
", + "", + "
", + "", + "{{out}} (minus the style):", + "
x123456789101112
1123456789101112
2 4681012141618202224
3 9121518212427303336
4 162024283236404448
5 2530354045505560
6 36424854606672
7 495663707784
8 6472808896
9 819099108
10 100110120
11 121132
12 144
", + "", + "", + "===Functional (ES5)===", + "", + "(function (m, n) {", + " ", + " // [m..n]", + " function range(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(function (x, i) {", + " return m + i;", + " });", + " }", + " ", + " // Monadic bind (chain) for lists", + " function mb(xs, f) {", + " return [].concat.apply([], xs.map(f));", + " }", + " ", + " var rng = range(m, n),", + " ", + " lstTable = [['x'].concat( rng )]", + " .concat(mb(rng, function (x) {", + " return [[x].concat(mb(rng, function (y) {", + " ", + " return y < x ? [''] : [x * y]; // triangle only", + " ", + " }))]}));", + " ", + " /* FORMATTING OUTPUT */", + " ", + " // [[a]] -> bool -> s -> s", + " function wikiTable(lstRows, blnHeaderRow, strStyle) {", + " return '{| class=\"wikitable\" ' + (", + " strStyle ? 'style=\"' + strStyle + '\"' : ''", + " ) + lstRows.map(function (lstRow, iRow) {", + " var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');", + " ", + " return '\\n|-\\n' + strDelim + ' ' + lstRow.map(function (v) {", + " return typeof v === 'undefined' ? ' ' : v;", + " }).join(' ' + strDelim + strDelim + ' ');", + " }).join('') + '\\n|}';", + " }", + " ", + " // Formatted as WikiTable", + " return wikiTable(", + " lstTable, true,", + " 'text-align:center;width:33em;height:33em;table-layout:fixed;'", + " ) + '\\n\\n' +", + " ", + " // or simply stringified as JSON", + " JSON.stringify(lstTable);", + " ", + "})(1, 12);", + "", + "{{out}}", + "", + "{| class=\"wikitable\" style=\"text-align:center;width:33em;height:33em;table-layout:fixed;\"", + "|-", + "! x !! 1 !! 2 !! 3 !! 4 !! 5 !! 6 !! 7 !! 8 !! 9 !! 10 !! 11 !! 12", + "|-", + "| 1 || 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 || 10 || 11 || 12", + "|-", + "| 2 || || 4 || 6 || 8 || 10 || 12 || 14 || 16 || 18 || 20 || 22 || 24", + "|-", + "| 3 || || || 9 || 12 || 15 || 18 || 21 || 24 || 27 || 30 || 33 || 36", + "|-", + "| 4 || || || || 16 || 20 || 24 || 28 || 32 || 36 || 40 || 44 || 48", + "|-", + "| 5 || || || || || 25 || 30 || 35 || 40 || 45 || 50 || 55 || 60", + "|-", + "| 6 || || || || || || 36 || 42 || 48 || 54 || 60 || 66 || 72", + "|-", + "| 7 || || || || || || || 49 || 56 || 63 || 70 || 77 || 84", + "|-", + "| 8 || || || || || || || || 64 || 72 || 80 || 88 || 96", + "|-", + "| 9 || || || || || || || || || 81 || 90 || 99 || 108", + "|-", + "| 10 || || || || || || || || || || 100 || 110 || 120", + "|-", + "| 11 || || || || || || || || || || || 121 || 132", + "|-", + "| 12 || || || || || || || || || || || || 144", + "|}", + "", + "[[\"x\",1,2,3,4,5,6,7,8,9,10,11,12],", + " [1,1,2,3,4,5,6,7,8,9,10,11,12],", + " [2,\"\",4,6,8,10,12,14,16,18,20,22,24],", + " [3,\"\",\"\",9,12,15,18,21,24,27,30,33,36],", + " [4,\"\",\"\",\"\",16,20,24,28,32,36,40,44,48],", + " [5,\"\",\"\",\"\",\"\",25,30,35,40,45,50,55,60],", + " [6,\"\",\"\",\"\",\"\",\"\",36,42,48,54,60,66,72],", + " [7,\"\",\"\",\"\",\"\",\"\",\"\",49,56,63,70,77,84],", + " [8,\"\",\"\",\"\",\"\",\"\",\"\",\"\",64,72,80,88,96],", + " [9,\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",81,90,99,108],", + " [10,\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",100,110,120],", + " [11,\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",121,132],", + " [12,\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",144]]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f29", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function (m, n) {\n \n // [m..n]\n function range(m, n) {\n return Array.apply(null, Array(n - m + 1)).map(function (x, i) {\n return m + i;\n });\n }\n \n // Monadic bind (chain) for lists\n function mb(xs, f) {\n return [].concat.apply([], xs.map(f));\n }\n \n var rng = range(m, n),\n \n lstTable = [['x'].concat( rng )]\n .concat(mb(rng, function (x) {\n return [[x].concat(mb(rng, function (y) {\n \n return y < x ? [''] : [x * y]; // triangle only\n \n }))]}));\n \n /* FORMATTING OUTPUT */\n \n // [[a]] -> bool -> s -> s\n function wikiTable(lstRows, blnHeaderRow, strStyle) {\n return '{| class=\"wikitable\" ' + (\n strStyle ? 'style=\"' + strStyle + '\"' : ''\n ) + lstRows.map(function (lstRow, iRow) {\n var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');\n \n return '\\n|-\\n' + strDelim + ' ' + lstRow.map(function (v) {\n return typeof v === 'undefined' ? ' ' : v;\n }).join(' ' + strDelim + strDelim + ' ');\n }).join('') + '\\n|}';\n }\n \n // Formatted as WikiTable\n return wikiTable(\n lstTable, true,\n 'text-align:center;width:33em;height:33em;table-layout:fixed;'\n ) + '\\n\\n' +\n \n // or simply stringified as JSON\n JSON.stringify(lstTable);\n \n})(1, 12);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Multiplicative order", + "type": "Waypoint", + "description": [ + "

The multiplicative order of a relative to m is the least positive integer n such that a^n is 1 (modulo m).

", + "Example:", + "

The multiplicative order of 37 relative to 1000 is 100 because 37^100 is 1 (modulo 1000), and no number smaller than 100 would do.

", + "

One possible algorithm that is efficient also for large numbers is the following: By the Chinese Remainder Theorem, it's enough to calculate the multiplicative order for each prime exponent p^k of m, and

", + "

combine the results with the least common multiple operation.

Now the order of a with regard to p^k must divide Φ(p^k). Call this number t, and determine it's factors q^e. Since each multiple of the order will also yield 1 when used as exponent for a, it's enough to find the least d such that (q^d)*(t/(q^e)) yields 1 when used as exponent.

", + "Task:", + "

Implement a routine to calculate the multiplicative order along these lines. You may assume that routines to determine the factorization into prime powers are available in some library.

----

An algorithm for the multiplicative order can be found in Bach & Shallit, Algorithmic Number Theory, Volume I: Efficient Algorithms, The MIT Press, 1996:

Exercise 5.8, page 115:

Suppose you are given a prime p and a complete factorization

", + "

of p-1. Show how to compute the order of an

", + "

element a in (Z/(p))* using O((lg p)4/(lg lg p)) bit

", + "

operations.

Solution, page 337:

Let the prime factorization of p-1 be q1e1q2e2...qkek . We use the following observation:

", + "

if x^((p-1)/qifi) = 1 (mod p) ,

", + "

and fi=ei or x^((p-1)/qifi+1) != 1 (mod p) , then qiei-fi||ordp x. (This follows by combining Exercises 5.1 and 2.10.)

Hence it suffices to find, for each i , the exponent fi such that the condition above holds.

This can be done as follows: first compute q1e1, q2e2, ... ,

", + "

qkek . This can be done using O((lg p)2) bit operations. Next, compute y1=(p-1)/q1e1, ... , yk=(p-1)/qkek .

", + "

This can be done using O((lg p)2) bit operations. Now, using the binary method,

", + "

compute x1=ay1(mod p), ... , xk=ayk(mod p) .

", + "

This can be done using O(k(lg p)3) bit operations, and k=O((lg p)/(lg lg p)) by Theorem 8.8.10.

", + "

Finally, for each i , repeatedly raise xi to the qi-th power (mod p) (as many as ei-1 times), checking to see when 1 is obtained.

", + "

This can be done using O((lg p)3) steps.

", + "

The total cost is dominated by O(k(lg p)3) , which is O((lg p)4/(lg lg p)).

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f2a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Multisplit", + "type": "Waypoint", + "description": [ + "

It is often necessary to split a string into pieces

", + "

based on several different (potentially multi-character) separator strings,

", + "

while still retaining the information about which separators were present in the input.

This is particularly useful when doing small parsing tasks.

", + "

The task is to write code to demonstrate this.

The function (or procedure or method, as appropriate) should

", + "

take an input string and an ordered collection of separators.

The order of the separators is significant:

", + "

The delimiter order represents priority in matching, with the first defined delimiter having the highest priority.

", + "

In cases where there would be an ambiguity as to

", + "

which separator to use at a particular point

", + "

(e.g., because one separator is a prefix of another)

", + "

the separator with the highest priority should be used.

", + "

Delimiters can be reused and the output from the function should be an ordered sequence of substrings.

Test your code using the input string “a!===b=!=c” and the separators “==”, “!=” and “=”.

For these inputs the string should be parsed as \"a\" (!=) \"\" (==) \"b\" (=) \"\" (!=) \"c\", where matched delimiters are shown in parentheses, and separated strings are quoted, so our resulting output is \"a\", empty string, \"b\", empty string, \"c\".

", + "

Note that the quotation marks are shown for clarity and do not form part of the output.

Extra Credit: provide information that indicates which separator was matched at each separation point and where in the input string that separator was matched.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Based on Ruby example.", + "{{libheader|Underscore.js}}", + "RegExp.escape = function(text) {", + " return text.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\");", + "}", + "", + "multisplit = function(string, seps) {", + " var sep_regex = RegExp(_.map(seps, function(sep) { return RegExp.escape(sep); }).join('|'));", + " return string.split(sep_regex);", + "}", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f2b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "RegExp.escape = function(text) {\n return text.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\");\n}\n\nmultisplit = function(string, seps) {\n var sep_regex = RegExp(_.map(seps, function(sep) { return RegExp.escape(sep); }).join('|'));\n return string.split(sep_regex);\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Munching squares", + "type": "Waypoint", + "description": [ + "

Render a graphical pattern where each pixel is colored by the value of 'x xor y' from an arbitrary color table.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f2c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Mutual recursion", + "type": "Waypoint", + "description": [ + "

Two functions are said to be mutually recursive if the first calls the second,

", + "

and in turn the second calls the first.

Write two mutually recursive functions that compute members of the Hofstadter Female and Male sequences defined as:

", + "

", + "

$

", + "

\\begin{align}

", + "

F(0)&=1\\ ;\\ M(0)=0 \\\\

", + "

F(n)&=n-M(F(n-1)), \\quad n>0 \\\\

", + "

M(n)&=n-F(M(n-1)), \\quad n>0.

", + "

\\end{align}

", + "

$

", + "
(If a language does not allow for a solution using mutually recursive functions ", + "

then state this rather than give a solution by other means).

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function f(num) {", + " return (num === 0) ? 1 : num - m(f(num - 1));", + "}", + "", + "function m(num) {", + " return (num === 0) ? 0 : num - f(m(num - 1));", + "}", + "", + "function range(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(", + " function (x, i) { return m + i; }", + " );", + "}", + "", + "var a = range(0, 19);", + "", + "//return a new array of the results and join with commas to print", + "console.log(a.map(function (n) { return f(n); }).join(', '));", + "console.log(a.map(function (n) { return m(n); }).join(', '));", + "{{out}}", + "
1,1,2,2,3,3,4,5,5,6,6,7,8,8,9,9,10,11,11,12",
+      "0,0,1,2,2,3,4,4,5,6,6,7,7,8,9,9,10,11,11,12
", + "", + "ES6 implementation", + "var f = num => (num === 0) ? 1 : num - m(f(num - 1));", + "var m = num => (num === 0) ? 0 : num - f(m(num - 1));", + "", + "function range(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(", + " function (x, i) { return m + i; }", + " );", + "}", + "", + "var a = range(0, 19);", + "", + "//return a new array of the results and join with commas to print", + "console.log(a.map(n => f(n)).join(', '));", + "console.log(a.map(n => m(n)).join(', '));", + "", + "More ES6 implementation", + "", + "var range = (m, n) => Array(... Array(n - m + 1)).map((x, i) => m + i)", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f2d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function f(num) {\n return (num === 0) ? 1 : num - m(f(num - 1));\n}\n\nfunction m(num) {\n return (num === 0) ? 0 : num - f(m(num - 1));\n}\n\nfunction range(m, n) {\n return Array.apply(null, Array(n - m + 1)).map(\n function (x, i) { return m + i; }\n );\n}\n\nvar a = range(0, 19);\n\n//return a new array of the results and join with commas to print\nconsole.log(a.map(function (n) { return f(n); }).join(', '));\nconsole.log(a.map(function (n) { return m(n); }).join(', '));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Narcissistic decimal number", + "type": "Waypoint", + "description": [ + "

A Narcissistic decimal number is a non-negative integer, $n$, that is equal to the sum of the $m$-th powers of each of the digits in the decimal representation of $n$, where $m$ is the number of digits in the decimal representation of $n$.

Narcissistic (decimal) numbers are sometimes called Armstrong numbers, named after Michael F. Armstrong.

", + "An example:", + "

:::* if $n$ is 153

", + "

:::* then $m$, (the number of decimal digits) is 3

", + "

:::* we have 13 + 53 + 33 = 1 + 125 + 27 = 153

", + "

:::* and so 153 is a narcissistic decimal number

", + "Task:", + "

Generate and show here the first 25 narcissistic decimal numbers.

", + "

Note: $0^1 = 0$, the first in the series.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "{{trans|Java}}", + "function isNarc(x) {", + " var str = x.toString(),", + " i,", + " sum = 0,", + " l = str.length;", + " if (x < 0) {", + " return false;", + " } else {", + " for (i = 0; i < l; i++) {", + " sum += Math.pow(str.charAt(i), l);", + " }", + " }", + " return sum == x;", + "}", + "function main(){", + " var n = []; ", + " for (var x = 0, count = 0; count < 25; x++){", + " if (isNarc(x)){", + " n.push(x);", + " count++;", + " }", + " }", + " return n.join(' '); ", + "}", + "{{out}}", + "
\"0 1 2 3 4 5 6 7 8 9 153 370 371 407 1634 8208 9474 54748 92727 93084 548834 1741725 4210818 9800817 9926315\"
", + "", + "===ES6===", + "====Exhaustive search (integer series)====", + "(() => {", + " 'use strict';", + " ", + " // digits :: Int -> [Int]", + " const digits = n => n.toString()", + " .split('')", + " .map(x => parseInt(x, 10));", + " ", + " // pow :: Int -> Int -> Int", + " const pow = Math.pow;", + " ", + " // isNarc :: Int -> Bool", + " const isNarc = n => {", + " const", + " ds = digits(n),", + " len = ds.length;", + " ", + " return ds.reduce((a, x) =>", + " a + pow(x, len), 0) === n;", + " };", + " ", + " // until :: (a -> Bool) -> (a -> a) -> a -> a", + " const until = (p, f, x) => {", + " let v = x;", + " while (!p(v)) v = f(v);", + " return v;", + " };", + " ", + " return until(", + " x => x.narc.length > 24,", + " x => ({", + " n: x.n + 1,", + " narc: (isNarc(x.n) ? x.narc.concat(x.n) : x.narc)", + " }), {", + " n: 0,", + " narc: []", + " }", + " )", + " .narc", + "})();", + "{{Out}}", + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834, 1741725, 4210818, 9800817, 9926315]", + "", + "", + "====Reduced search (unordered digit combinations)====", + "{{Trans|Haskell}}", + "As summing the nth power of the digits is unaffected by digit order, we can reduce the search space by filtering digit combinations of given length and arbitrary order, rather than filtering a full integer sequence.", + "", + "In this way we can find the 25th narcissistic number after '''length(concatMap(digitPowerSums, enumFromTo(0, 7))) === 19447''' tests – an improvement on the exhaustive trawl through '''9926315''' integers.", + "", + "(Generating the unordered digit combinations directly as power sums allows faster testing later, and needs less space)", + "(() => {", + " 'use strict';", + "", + " // DAFFODILS --------------------------------------------------------------", + "", + " // narcissiOfLength :: Int -> [Int]", + " const narcissiOfLength = n =>", + " n > 0 ? filter(curry(isDaffodil)(n), digitPowerSums(n)) : [0];", + "", + " // Do the decimal digits of N, each raised to the power E, sum to N itself ?", + "", + "// isDaffodil :: Int -> Int -> Bool", + "const isDaffodil = (e, n) => {", + " const", + " powerSum = (n, xs) => xs.reduce((a, x) => a + Math.pow(x, n), 0),", + " digitList = n => (n > 0) ? (", + " cons((n % 10), digitList(Math.floor(n / 10)))", + " ) : [],", + " ds = digitList(n);", + " return e === ds.length && n === powerSum(e, ds);", + "};", + "", + " // The subset of integers of n digits that actually need daffodil checking:", + "", + " // (Flattened leaves of a tree of unique digit combinations, in which", + " // order is not significant. Digit sequence doesn't affect power summing)", + "", + " // digitPowerSums :: Int -> [Int]", + " const digitPowerSums = nDigits => {", + " const", + " digitPowers = map(x => [x, pow(x, nDigits)], enumFromTo(0, 9)),", + " treeGrowth = (n, parentPairs) => (n > 0) ? (", + " treeGrowth(n - 1,", + " isNull(parentPairs) ? (", + " digitPowers", + " ) : concatMap(([parentDigit, parentSum]) =>", + " map(([leafDigit, leafSum]) => //", + " [leafDigit, parentSum + leafSum],", + " take(parentDigit + 1, digitPowers)", + " ),", + " parentPairs", + " ))", + " ) : parentPairs;", + " return map(snd, treeGrowth(nDigits, []));", + " };", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // enumFromTo :: Int -> Int -> Maybe Int -> [Int]", + " const enumFromTo = (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));", + " };", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // cons :: a -> [a] -> [a]", + " const cons = (x, xs) => [x].concat(xs);", + "", + " // 2 or more arguments", + " // curry :: Function -> Function", + " const curry = (f, ...args) => {", + " const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :", + " function () {", + " return go(xs.concat([].slice.apply(arguments)));", + " };", + " return go([].slice.call(args, 1));", + " };", + "", + " // filter :: (a -> Bool) -> [a] -> [a]", + " const filter = (f, xs) => xs.filter(f);", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = curry((f, xs) => xs.map(f));", + "", + " // isNull :: [a] -> Bool", + " const isNull = xs => (xs instanceof Array) ? xs.length < 1 : undefined;", + "", + " // length :: [a] -> Int", + " const length = xs => xs.length;", + "", + " // pow :: Int -> Int -> Int", + " const pow = Math.pow", + "", + " // take :: Int -> [a] -> [a]", + " const take = (n, xs) => xs.slice(0, n);", + "", + " // show ::", + " // (a -> String) f, Num n =>", + " // a -> maybe f -> maybe n -> String", + " const show = JSON.stringify;", + "", + " // snd :: (a, b) -> b", + " const snd = tpl => Array.isArray(tpl) ? tpl[1] : undefined;", + "", + "", + " // TEST -------------------------------------------------------------------", + "", + " // return length(concatMap(digitPowerSums, enumFromTo(0, 7)));", + "", + " return show(", + " //digitPowerSums(3)", + " concatMap(narcissiOfLength, enumFromTo(0, 7))", + " );", + "})();", + "{{Out}}", + "(Tested in Atom editor, using Script package)", + "
[0,1,2,3,4,5,6,7,8,9,153,370,371,407,1634,8208,9474,54748,92727,93084,548834,1741725,4210818,9800817,9926315]",
+      "[Finished in 0.118s]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f30", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function isNarc(x) {\n var str = x.toString(),\n i,\n sum = 0,\n l = str.length;\n if (x < 0) {\n return false;\n } else {\n for (i = 0; i < l; i++) {\n sum += Math.pow(str.charAt(i), l);\n }\n }\n return sum == x;\n}\nfunction main(){\n var n = []; \n for (var x = 0, count = 0; count < 25; x++){\n if (isNarc(x)){\n n.push(x);\n count++;\n }\n }\n return n.join(' '); \n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Narcissist", + "type": "Waypoint", + "description": [ + "

Quoting from the Esolangs wiki page:

", + "

A narcissist (or Narcissus program) is the decision-problem version of a quine.

", + "
", + "

A quine, when run, takes no input, but produces a copy of its own source code at its output. In contrast, a narcissist reads a string of symbols from its input, and produces no output except a \"1\" or \"accept\" if that string matches its own source code, or a \"0\" or \"reject\" if it does not.

", + "

For concreteness, in this task we shall assume that symbol = character.

The narcissist should be able to cope with any finite input, whatever its length.

Any form of output is allowed, as long as the program always halts, and \"accept\", \"reject\" and \"not yet finished\" are distinguishable.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|SpiderMonkey|1.7.0}}", + "Based upon [[Quine#Using_eval|one of the quines]]. Outputs 'true' if source is equal to inputted line (newline terminated), 'false' otherwise.", + "var code='var q=String.fromCharCode(39);print(\"var code=\" + q + code + q + \"; eval(code)\" == readline())'; eval(code)", + "", + "{{works with|JScript}}", + "var oFSO = new ActiveXObject(\"Scripting.FileSystemObject\");", + "function readfile(fname) {", + "\tvar h = oFSO.OpenTextFile(fname, 1, false);", + "\tvar result = h.ReadAll();", + "\th.Close();", + "\treturn result;", + "}", + "", + "if (0 === WScript.Arguments.UnNamed.Count) {", + "\tWScript.Echo(WScript.ScriptName,\"filename\");", + "\tWScript.Quit();", + "}", + "", + "// first read self ", + "var self = readfile(WScript.ScriptFullName);", + "// read whatever file is given on commmand line", + "var whatever = readfile(WScript.Arguments.UnNamed(0));", + "", + "// compare and contrast", + "WScript.Echo(self === whatever ? \"Accept\" : \"Reject\");", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f31", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var code='var q=String.fromCharCode(39);print(\"var code=\" + q + code + q + \"; eval(code)\" == readline())'; eval(code)\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Natural sorting", + "type": "Waypoint", + "description": [ + "

Natural sorting is the sorting of text that does more than rely on the

", + "

order of individual characters codes to make the finding of

", + "

individual strings easier for a human reader.

There is no \"one true way\" to do this, but for the purpose of this task 'natural' orderings might include:

", + "

1. Ignore leading, trailing and multiple adjacent spaces

", + "

2. Make all whitespace characters equivalent.

", + "

3. Sorting without regard to case.

", + "

4. Sorting numeric portions of strings in numeric order. That is split the string into fields on numeric boundaries, then sort on each field, with the rightmost fields being the most significant, and numeric fields of integers treated as numbers.

", + "

: foo9.txt before foo10.txt

", + "

: As well as ... x9y99 before x9y100, before x10y0

", + "

: ... (for any number of groups of integers in a string).

", + "

5. Title sorts: without regard to a leading, very common, word such

", + "

: as 'The' in \"The thirty-nine steps\".

", + "

6. Sort letters without regard to accents.

", + "

7. Sort ligatures as separate letters.

", + "

8. Replacements:

", + "

: Sort german scharfes S (ß) as ss

", + "

: Sort ſ, LATIN SMALL LETTER LONG S as s

", + "

: Sort ʒ, LATIN SMALL LETTER EZH as s

", + "

: ...

Task Description", + "Implement the first four of the eight given features in a natural sorting routine/function/method...", + "Test each feature implemented separately with an ordered list of test strings from the 'Sample inputs' section below, and make sure your naturally sorted output is in the same order as other language outputs such as Python. ", + "Print and display your output.", + "For extra credit implement more than the first four.", + "

Note: It is not necessary to have individual control of which features are active in the natural sorting routine at any time.

Sample input:
",
+      "Ignoring leading spacesText strings:",
+      "['ignore leading spaces: 2-2', ' ignore leading spaces: 2-1', '  ignore leading spaces: 2+0', '   ignore leading spaces: 2+1']Ignoring multiple adjacent spaces (m.a.s)Text strings:",
+      "['ignore m.a.s spaces: 2-2', 'ignore m.a.s  spaces: 2-1', 'ignore m.a.s   spaces: 2+0', 'ignore m.a.s    spaces: 2+1']",
+      "Equivalent whitespace charactersText strings:",
+      "['Equiv. spaces: 3-3', 'Equiv.\\rspaces: 3-2', 'Equiv.\\x0cspaces: 3-1', 'Equiv.\\x0bspaces: 3+0', 'Equiv.\\nspaces: 3+1', 'Equiv.\\tspaces: 3+2']Case Indepenent sortText strings:",
+      "['cASE INDEPENENT: 3-2', 'caSE INDEPENENT: 3-1', 'casE INDEPENENT: 3+0', 'case INDEPENENT: 3+1']Numeric fields as numericsText strings:",
+      "['foo100bar99baz0.txt', 'foo100bar10baz0.txt', 'foo1000bar99baz10.txt', 'foo1000bar99baz9.txt']Title sortsText strings:",
+      "['The Wind in the Willows', 'The 40th step more', 'The 39 steps', 'Wanda']Equivalent accented characters (and case)Text strings:",
+      "[u'Equiv. \\xfd accents: 2-2', u'Equiv. \\xdd accents: 2-1', u'Equiv. y accents: 2+0', u'Equiv. Y accents: 2+1']",
+      "Separated ligaturesText strings:",
+      "[u'\\u0132 ligatured ij', 'no ligature']Character replacementsText strings:",
+      "[u'Start with an \\u0292: 2-2', u'Start with an \\u017f: 2-1', u'Start with an \\xdf: 2+0', u'Start with an s: 2+1']
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "Implements the first four rules. Rule 4 works for digits up to 20 characters.", + "", + "", + "var nsort = function(input) {", + " var e = function(s) {", + " return (' ' + s + ' ').replace(/[\\s]+/g, ' ').toLowerCase().replace(/[\\d]+/, function(d) {", + " d = '' + 1e20 + d;", + " return d.substring(d.length - 20);", + " });", + " };", + " return input.sort(function(a, b) {", + " return e(a).localeCompare(e(b));", + " });", + "};", + "", + "console.log(nsort([", + " \"file10.txt\",", + " \"\\nfile9.txt\",", + " \"File11.TXT\",", + " \"file12.txt\"", + "]));", + "// -> ['\\nfile9.txt', 'file10.txt', 'File11.TXT', 'file12.txt']", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f32", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nvar nsort = function(input) {\n var e = function(s) {\n return (' ' + s + ' ').replace(/[\\s]+/g, ' ').toLowerCase().replace(/[\\d]+/, function(d) {\n d = '' + 1e20 + d;\n return d.substring(d.length - 20);\n });\n };\n return input.sort(function(a, b) {\n return e(a).localeCompare(e(b));\n });\n};\n\nconsole.log(nsort([\n \"file10.txt\",\n \"\\nfile9.txt\",\n \"File11.TXT\",\n \"file12.txt\"\n]));\n// -> ['\\nfile9.txt', 'file10.txt', 'File11.TXT', 'file12.txt']\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Nautical bell", + "type": "Waypoint", + "description": [ + "Task

Write a small program that emulates a nautical bell producing a ringing bell pattern at certain times throughout the day.

The bell timing should be in accordance with Greenwich Mean Time, unless locale dictates otherwise.

It is permissible for the program to daemonize, or to slave off a scheduler, and it is permissible to use alternative notification methods (such as producing a written notice \"Two Bells Gone\"), if these are more usual for the system type.

", + "Cf.:", + "Sleep" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f33", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Non-continuous subsequences", + "type": "Waypoint", + "description": [ + "

Consider some sequence of elements. (It differs from a mere set of elements by having an ordering among members.)

A subsequence contains some subset of the elements of this sequence, in the same order.

A continuous subsequence is one in which no elements are missing between the first and last elements of the subsequence.

Note: Subsequences are defined structurally, not by their contents.

", + "

So a sequence a,b,c,d will always have the same subsequences and continuous subsequences, no matter which values are substituted; it may even be the same value.

Task: Find all non-continuous subsequences for a given sequence.

Example: For the sequence 1,2,3,4, there are five non-continuous subsequences, namely:

", + "

:::* 1,3

", + "

:::* 1,4

", + "

:::* 2,4

", + "

:::* 1,3,4

", + "

:::* 1,2,4

Goal: There are different ways to calculate those subsequences. Demonstrate algorithm(s) that are natural for the language.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Uses powerset() function from [[Power Set#JavaScript|here]]. Uses a JSON stringifier from http://www.json.org/js.html", + "", + "{{works with|SpiderMonkey}}", + "function non_continuous_subsequences(ary) {", + " var non_continuous = new Array();", + " for (var i = 0; i < ary.length; i++) {", + " if (! is_array_continuous(ary[i])) {", + " non_continuous.push(ary[i]);", + " }", + " }", + " return non_continuous;", + "}", + "", + "function is_array_continuous(ary) {", + " if (ary.length < 2)", + " return true;", + " for (var j = 1; j < ary.length; j++) {", + " if (ary[j] - ary[j-1] != 1) {", + " return false;", + " }", + " }", + " return true;", + "}", + "", + "load('json2.js'); /* http://www.json.org/js.html */", + "", + "print(JSON.stringify( non_continuous_subsequences( powerset([1,2,3,4]))));", + "", + "{{out}}", + "
[[1,3],[1,4],[2,4],[1,2,4],[1,3,4]]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f35", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function non_continuous_subsequences(ary) {\n var non_continuous = new Array();\n for (var i = 0; i < ary.length; i++) {\n if (! is_array_continuous(ary[i])) {\n non_continuous.push(ary[i]);\n }\n }\n return non_continuous;\n}\n\nfunction is_array_continuous(ary) {\n if (ary.length < 2)\n return true;\n for (var j = 1; j < ary.length; j++) {\n if (ary[j] - ary[j-1] != 1) {\n return false;\n }\n }\n return true;\n}\n\nload('json2.js'); /* http://www.json.org/js.html */\n\nprint(JSON.stringify( non_continuous_subsequences( powerset([1,2,3,4]))));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Non-decimal radices/Convert", + "type": "Waypoint", + "description": [ + "

Number base conversion is when you express a stored integer in an integer base, such as in octal (base 8) or binary (base 2). It also is involved when you take a string representing a number in a given base and convert it to the stored integer form. Normally, a stored integer is in binary, but that's typically invisible to the user, who normally enters or sees stored integers as decimal.

", + "Task:", + "

Write a function (or identify the built-in function) which is passed a non-negative integer to convert, and another integer representing the base.

It should return a string containing the digits of the resulting number, without leading zeros except for the number 0 itself.

For the digits beyond 9, one should use the lowercase English alphabet, where the digit a = 9+1, b = a+1, etc.

For example: the decimal number 26 expressed in base 16 would be 1a.

Write a second function which is passed a string and an integer base, and it returns an integer representing that string interpreted in that base.

The programs may be limited by the word size or other such constraint of a given language. There is no need to do error checking for negatives, bases less than 2, or inappropriate digits.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "k = 26", + "s = k.toString(16) //gives 1a", + "i = parseInt('1a',16) //gives 26", + "//optional special case for hex:", + "i = +('0x'+s) //hexadecimal base 16, if s='1a' then i=26.", + "", + "Converts a number of arbitrary length from any base to any base", + "Limitation: Any base or number that causes accumulator to overflow will lose precision!!", + "Debugging or following the process is easy as it is kept in the expected base string format and order.", + "", + "var baselist = \"0123456789abcdefghijklmnopqrstuvwxyz\", listbase = [];", + "for(var i = 0; i < baselist.length; i++) listbase[baselist[i]] = i; // Generate baselist reverse", + "function basechange(snumber, frombase, tobase)", + "{", + " var i, t, to = new Array(Math.ceil(snumber.length * Math.log(frombase) / Math.log(tobase))), accumulator;", + " if(1 < frombase < baselist.length || 1 < tobase < baselist.length) console.error(\"Invalid or unsupported base!\");", + " while(snumber[0] == baselist[0] && snumber.length > 1) snumber = snumber.substr(1); // Remove leading zeros character", + " console.log(\"Number is\", snumber, \"in base\", frombase, \"to base\", tobase, \"result should be\",", + " parseInt(snumber, frombase).toString(tobase));", + " for(i = snumber.length - 1, inexp = 1; i > -1; i--, inexp *= frombase)", + " for(accumulator = listbase[snumber[i]] * inexp, t = to.length - 1; accumulator > 0 || t >= 0; t--)", + " {", + " accumulator += listbase[to[t] || 0];", + " to[t] = baselist[(accumulator % tobase) || 0];", + " accumulator = Math.floor(accumulator / tobase);", + " }", + " return to.join('');", + "}", + "console.log(\"Result:\", basechange(\"zzzzzzzzzz\", 36, 10));", + "Using BigInteger, can convert any base.", + "", + "// Tom Wu jsbn.js http://www-cs-students.stanford.edu/~tjw/jsbn/", + "var baselist = \"0123456789abcdefghijklmnopqrstuvwxyz\", listbase = [];", + "for(var i = 0; i < baselist.length; i++) listbase[baselist[i]] = i; // Generate baselist reverse", + "function baseconvert(snumber, frombase, tobase) // String number in base X to string number in base Y, arbitrary length, base", + "{", + " var i, t, to, accum = new BigInteger(), inexp = new BigInteger('1', 10), tb = new BigInteger(),", + " fb = new BigInteger(), tmp = new BigInteger();", + " console.log(\"Number is\", snumber, \"in base\", frombase, \"to base\", tobase, \"result should be\",", + " frombase < 37 && tobase < 37 ? parseInt(snumber, frombase).toString(tobase) : 'too large');", + " while(snumber[0] == baselist[0] && snumber.length > 1) snumber = snumber.substr(1); // Remove leading zeros", + " tb.fromInt(tobase);", + " fb.fromInt(frombase);", + " for(i = snumber.length - 1, to = new Array(Math.ceil(snumber.length * Math.log(frombase) / Math.log(tobase))); i > -1; i--)", + " {", + " accum = inexp.clone();", + " accum.dMultiply(listbase[snumber[i]]);", + " for(t = to.length - 1; accum.compareTo(BigInteger.ZERO) > 0 || t >= 0; t--)", + " {", + " tmp.fromInt(listbase[to[t]] || 0);", + " accum = accum.add(tmp);", + " to[t] = baselist[accum.mod(tb).intValue()];", + " accum = accum.divide(tb);", + " }", + " inexp = inexp.multiply(fb);", + " }", + " while(to[0] == baselist[0] && to.length > 1) to = to.slice(1); // Remove leading zeros", + " return to.join('');", + "}", + "", + "", + "===ES6===", + "", + "For more flexibility with digit variants (upper and lower case hex, digits in other languages/scripts etc) we can define '''toBase'''(intBase, n) in terms of a more general '''inBaseDigits'''(strDigits, n) which derives the base from the number of digits to be used.", + "", + "(() => {", + " 'use strict';", + "", + " // toBase :: Int -> Int -> String", + " const toBase = (intBase, n) =>", + " intBase < 36 && intBase > 0 ?", + " inBaseDigits('0123456789abcdef'.substr(0, intBase), n) : [];", + "", + "", + " // inBaseDigits :: String -> Int -> [String]", + " const inBaseDigits = (digits, n) => {", + " const intBase = digits.length;", + "", + " return unfoldr(maybeResidue => {", + " const [divided, remainder] = quotRem(maybeResidue.new, intBase);", + "", + " return {", + " valid: divided > 0,", + " value: digits[remainder],", + " new: divided", + " };", + " }, n)", + " .reverse()", + " .join('');", + " };", + "", + "", + " // GENERIC FUNCTIONS", + "", + " // unfoldr :: (b -> Maybe (a, b)) -> b -> [a]", + " const unfoldr = (mf, v) => {", + " var xs = [];", + " return (until(", + " m => !m.valid,", + " m => {", + " const m2 = mf(m);", + " return (", + " xs = xs.concat(m2.value),", + " m2", + " );", + " }, {", + " valid: true,", + " value: v,", + " new: v,", + " }", + " ), xs);", + " };", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " const curry = f => a => b => f(a, b);", + "", + " // until :: (a -> Bool) -> (a -> a) -> a -> a", + " const until = (p, f, x) => {", + " let v = x;", + " while (!p(v)) v = f(v);", + " return v;", + " }", + "", + " // quotRem :: Integral a => a -> a -> (a, a)", + " const quotRem = (m, n) => [Math.floor(m / n), m % n];", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x, null, 2);", + "", + "", + " // OTHER FUNCTIONS DERIVABLE FROM inBaseDigits", + "", + " // inLowerHex :: Int -> String", + " const inLowerHex = curry(inBaseDigits)('0123456789abcdef');", + "", + " /// inUpperHex :: Int -> String", + " const inUpperHex = curry(inBaseDigits)('0123456789ABCDEF');", + "", + " // inOctal :: Int -> String", + " const inOctal = curry(inBaseDigits)('01234567');", + "", + " // inDevanagariDecimal :: Int -> String", + " const inDevanagariDecimal = curry(inBaseDigits)('०१२३४५६७८९');", + "", + "", + " // TESTS", + " // testNumber :: [Int]", + " const testNumbers = [255, 240];", + "", + " return testNumbers.map(n => show({", + " binary: toBase(2, n),", + " base5: toBase(5, n),", + " hex: toBase(16, n),", + " upperHex: inUpperHex(n),", + " octal: inOctal(n),", + " devanagariDecimal: inDevanagariDecimal(n)", + " }));", + "})();", + "", + "{{Out}}", + "
{",
+      "  \"binary\": \"11111111\",",
+      "  \"base5\": \"2010\",",
+      "  \"hex\": \"ff\",",
+      "  \"upperHex\": \"FF\",",
+      "  \"octal\": \"377\",",
+      "  \"devanagariDecimal\": \"२५५\"",
+      "}, {",
+      "  \"binary\": \"11110000\",",
+      "  \"base5\": \"1430\",",
+      "  \"hex\": \"f0\",",
+      "  \"upperHex\": \"F0\",",
+      "  \"octal\": \"360\",",
+      "  \"devanagariDecimal\": \"२४०\"",
+      "}
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f36", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "k = 26\ns = k.toString(16) //gives 1a\ni = parseInt('1a',16) //gives 26\n//optional special case for hex:\ni = +('0x'+s) //hexadecimal base 16, if s='1a' then i=26.\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Non-decimal radices/Input", + "type": "Waypoint", + "description": [ + "

It is common to have a string containing a number written in some format, with the most common ones being decimal, hexadecimal, octal and binary. Such strings are found in many places (user interfaces, configuration files, XML data, network protocols, etc.)

This task requires parsing of such a string (which may be assumed to contain nothing else) using the language's built-in facilities if possible. Parsing of decimal strings is required, parsing of other formats is optional but should be shown (i.e., if the language can parse in base-19 then that should be illustrated).

The solutions may assume that the base of the number in the string is known. In particular, if your language has a facility to guess the base of a number by looking at a prefix (e.g. \"0x\" for hexadecimal) or other distinguishing syntax as it parses it, please show that.

The reverse operation is in task Non-decimal radices/Output

For general number base conversion, see Non-decimal radices/Convert.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "For base 10 and 16 (\"0x\"-prefixed), (but not 8), it is fastest to parse strings using the unary plus (+) operator:", + "+\"0123459\"; // 123459", + "+\"0xabcf123\"; // 180154659", + "", + "// also supports negative numbers, but not for hex:", + "+\"-0123459\"; // -123459", + "+\"-0xabcf123\"; // NaN", + "See http://www.jibbering.com/faq/notes/type-conversion/#tcNumber for more information.", + "", + "The parseInt(''string'',''radix'') core function is the reverse of the ''number''.toString(''radix'') method. The following is taken from [http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/parseInt#Example.3a_Using_parseInt Mozilla's JavaScript 1.5 reference].", + "", + "
The following examples all return 15:", + "", + "parseInt(\" 0xF\", 16);", + "parseInt(\" F\", 16);", + "parseInt(\"17\", 8);", + "parseInt(021, 8);", + "parseInt(\"015\", 10);", + "parseInt(15.99, 10);", + "parseInt(\"FXX123\", 16);", + "parseInt(\"1111\", 2);", + "parseInt(\"15*3\", 10);", + "parseInt(\"15e2\", 10);", + "parseInt(\"15px\", 10);", + "parseInt(\"12\", 13);", + "", + "The following examples all return NaN:", + "", + "parseInt(\"Hello\", 8); // Not a number at all", + "parseInt(\"546\", 2); // Digits are not valid for binary representations", + "", + "The following examples all return -15:", + "", + "parseInt(\"-F\", 16);", + "parseInt(\"-0F\", 16);", + "parseInt(\"-0XF\", 16);", + "parseInt(-10, 16);", + "parseInt(-15.1, 10)", + "parseInt(\" -17\", 8);", + "parseInt(\" -15\", 10);", + "parseInt(\"-1111\", 2);", + "parseInt(\"-15e1\", 10);", + "parseInt(\"-12\", 13);", + "", + "The following example returns 224:", + "", + "parseInt(\"0e0\", 16);", + "", + "Although it is optional, most implementations interpret a numeric string beginning with a leading '0' as octal. The following may have an octal result.", + "", + "parseInt(\"0e0\"); // 0", + "parseInt(\"08\"); // 0, '8' is not an octal digit.
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f37", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "+\"0123459\"; // 123459\n+\"0xabcf123\"; // 180154659\n\n// also supports negative numbers, but not for hex:\n+\"-0123459\"; // -123459\n+\"-0xabcf123\"; // NaN\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Non-decimal radices/Output", + "type": "Waypoint", + "description": [ + "

Programming languages often have built-in routines to convert a non-negative integer for printing in different number bases. Such common number bases might include binary, Octal and Hexadecimal.

", + "Task:", + "

Print a small range of integers in some different bases, as supported by standard routines of your programming language.

", + "Note:", + "

This is distinct from Number base conversion as a user-defined conversion function is not asked for.)

The reverse operation is Common number base parsing.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "The number.toString(radix) method produces a string representation of a number in any radix between 2 and 36.", + "", + "var bases = [2, 8, 10, 16, 24];", + "for (var n = 0; n <= 33; n++) {", + " var row = [];", + " for (var i = 0; i < bases.length; i++)", + " row.push( n.toString(bases[i]) );", + " print(row.join(', '));", + "}", + "", + "outputs", + "
0, 0, 0, 0, 0",
+      "1, 1, 1, 1, 1",
+      "10, 2, 2, 2, 2",
+      "11, 3, 3, 3, 3",
+      "100, 4, 4, 4, 4",
+      "101, 5, 5, 5, 5",
+      "110, 6, 6, 6, 6",
+      "111, 7, 7, 7, 7",
+      "1000, 10, 8, 8, 8",
+      "1001, 11, 9, 9, 9",
+      "1010, 12, 10, a, a",
+      "1011, 13, 11, b, b",
+      "1100, 14, 12, c, c",
+      "1101, 15, 13, d, d",
+      "1110, 16, 14, e, e",
+      "1111, 17, 15, f, f",
+      "10000, 20, 16, 10, g",
+      "10001, 21, 17, 11, h",
+      "10010, 22, 18, 12, i",
+      "10011, 23, 19, 13, j",
+      "10100, 24, 20, 14, k",
+      "10101, 25, 21, 15, l",
+      "10110, 26, 22, 16, m",
+      "10111, 27, 23, 17, n",
+      "11000, 30, 24, 18, 10",
+      "11001, 31, 25, 19, 11",
+      "11010, 32, 26, 1a, 12",
+      "11011, 33, 27, 1b, 13",
+      "11100, 34, 28, 1c, 14",
+      "11101, 35, 29, 1d, 15",
+      "11110, 36, 30, 1e, 16",
+      "11111, 37, 31, 1f, 17",
+      "100000, 40, 32, 20, 18",
+      "100001, 41, 33, 21, 19
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f38", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var bases = [2, 8, 10, 16, 24];\nfor (var n = 0; n <= 33; n++) {\n var row = [];\n for (var i = 0; i < bases.length; i++)\n row.push( n.toString(bases[i]) );\n print(row.join(', '));\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Nonoblock", + "type": "Waypoint", + "description": [ + "

Nonoblock is a chip off the old Nonogram puzzle.

Given:", + "The number of cells in a row.", + "The size of each, (space separated), connected block of cells to fit in the row, in left-to right order.", + "

The task is to

", + "show all possible positions ", + "and the number of positions of the blocks for the following cases", + "

within the row. On this page. Using a \"neat\" diagram of the block positions.

Enumerate the following configurations:", + "5 cells and [2, 1] blocks", + "5 cells and [] blocks (no blocks)", + "10 cells and [8] blocks", + "15 cells and [2, 3, 2, 3] blocks", + "5 cells and [2, 3] blocks (Should give some indication of this not being possible).", + "Example:", + "

Given a row of five cells and a block of two cells followed

", + "

by a block of 1 cell - in that order, the example could be shown as:

|_|_|_|_|_| # 5 cells and [2, 1] blocks

And would expand to the following 3 possible rows of block positions:

|A|A|_|B|_|

", + "

|A|A|_|_|B|

", + "

|_|A|A|_|B|

", + "

Note how the sets of blocks are always separated by a space.

Note also that it is not necessary for each block to have a separate letter.

", + "

Output approximating

This:

|#|#|_|#|_|

", + "

|#|#|_|_|#|

", + "

|_|#|#|_|#|

Or even this:

##.#.

", + "

##..#

", + "

.##.#

Would also work.

An algorithm:", + "Find the minimum space to the right that is needed to legally hold all but the leftmost block of cells (with a space between blocks remember).", + "The leftmost cell can legitimately be placed in all positions from the LHS up to a RH position that allows enough room for the rest of the blocks.", + "for each position of the LH block recursively compute the position of the rest of the blocks in the remaining space to the right of the current placement of the LH block.(This is the algorithm used in the Nonoblock#Python solution). Reference:", + "The blog post Nonogram puzzle solver (part 1) Inspired this task and donated its Nonoblock#Python solution." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f39", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Nonogram solver", + "type": "Waypoint", + "description": [ + "

A nonogram is a puzzle that provides

", + "

numeric clues used to fill in a grid of cells,

", + "

establishing for each cell whether it is filled or not.

", + "

The puzzle solution is typically a picture of some kind.

Each row and column of a rectangular grid is annotated with the lengths

", + "

of its distinct runs of occupied cells.

", + "

Using only these lengths you should find one valid configuration

", + "

of empty and occupied cells, or show a failure message.

Example", + "
Problem:                 Solution:. . . . . . . .  3       . # # # . . . .  3",
+      ". . . . . . . .  2 1     # # . # . . . .  2 1",
+      ". . . . . . . .  3 2     . # # # . . # #  3 2",
+      ". . . . . . . .  2 2     . . # # . . # #  2 2",
+      ". . . . . . . .  6       . . # # # # # #  6",
+      ". . . . . . . .  1 5     # . # # # # # .  1 5",
+      ". . . . . . . .  6       # # # # # # . .  6",
+      ". . . . . . . .  1       . . . . # . . .  1",
+      ". . . . . . . .  2       . . . # # . . .  2",
+      "1 3 1 7 5 3 4 3          1 3 1 7 5 3 4 3",
+      "2 1 5 1                  2 1 5 1
", + "

The problem above could be represented by two lists of lists:

", + "
x = 3], [2,1], [3,2], [2,2], [6], [1,5], [6], [1], [2",
+      "y = 1,2], [3,1], [1,5], [7,1], [5], [3], [4], [3
", + "

A more compact representation of the same problem uses strings,

", + "

where the letters represent the numbers, A=1, B=2, etc:

", + "
x = \"C BA CB BB F AE F A B\"",
+      "y = \"AB CA AE GA E C D C\"
Task", + "

For this task, try to solve the 4 problems below, read from a “nonogram_problems.txt” file that has this content

", + "

(the blank lines are separators):

", + "
C BA CB BB F AE F A B",
+      "AB CA AE GA E C D CF CAC ACAC CN AAA AABB EBB EAA ECCC HCCC",
+      "D D AE CD AE A DA BBB CC AAB BAA AAB DA AAB AAA BAB AAA CD BBA DACA BDA ACC BD CCAC CBBAC BBBBB BAABAA ABAD AABB BBH BBBD ABBAAA CCEA AACAAB BCACC ACBH DCH ADBE ADBB DBE ECE DAA DB CC",
+      "BC CAC CBAB BDD CDBDE BEBDF ADCDFA DCCFB DBCFC ABDBA BBF AAF BADB DBF AAAAD BDG CEF CBDB BBB FCE BCB BEA BH BEK AABAF ABAC BAA BFB OD JH BADCF Q Q R AN AAN EI H G",
+      "E CB BAB AAA AAA AC BB ACC ACCA AGB AIA AJ AJ ACE AH BAF CAG DAG FAH FJ GJ ADK ABK BL CM

Extra credit: generate nonograms with unique solutions, of desired height and width.

", + "

This task is the problem n.98 of the \"99 Prolog Problems\" by Werner Hett (also thanks to Paul Singleton for the idea and the examples).

", + " Related tasks", + "Nonoblock.", + "See also", + "Arc Consistency Algorithm", + "http://www.haskell.org/haskellwiki/99_questions/Solutions/98 (Haskell)", + "http://twanvl.nl/blog/haskell/Nonograms (Haskell)", + "http://picolisp.com/5000/!wiki?99p98 (PicoLisp)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f3a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "N-queens problem", + "type": "Waypoint", + "description": [ + "

Solve the eight queens puzzle.

", + "

You can extend the problem to solve the puzzle with a board of size NxN.

For the number of solutions for small values of N, see oeis.org sequence A170.

", + "Related tasks:", + "A* search algorithm", + "Solve a Hidato puzzle", + "Solve a Holy Knight's tour", + "Knight's tour", + "Solve a Hopido puzzle", + "Solve a Numbrix puzzle", + "Solve the no connection puzzle" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f3b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "N'th", + "type": "Waypoint", + "description": [ + "

Write a function/method/subroutine/... that when given an integer greater than or equal to zero returns a string of the number followed by an apostrophe then the ordinal suffix.

", + "Example returns would include 1'st 2'nd 3'rd 11'th 111'th 1001'st 1012'thTask:", + "

Use your routine to show here the output for at least the following (inclusive) ranges of integer inputs:

", + "

0..25, 250..265, 1000..1025

Note: apostrophes are now optional to allow correct apostrophe-less English.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "console.log(function () {", + "", + " var lstSuffix = 'th st nd rd th th th th th th'.split(' '),", + "", + " fnOrdinalForm = function (n) {", + " return n.toString() + (", + " 11 <= n % 100 && 13 >= n % 100 ?", + " \"th\" : lstSuffix[n % 10]", + " );", + " },", + "", + " range = function (m, n) {", + " return Array.apply(", + " null, Array(n - m + 1)", + " ).map(function (x, i) {", + " return m + i;", + " });", + " };", + "", + " return [[0, 25], [250, 265], [1000, 1025]].map(function (tpl) {", + " return range.apply(null, tpl).map(fnOrdinalForm).join(' ');", + " }).join('\\n\\n');", + " ", + "}());", + "", + "", + "{{Out}}", + "", + "0th 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 12th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 25th", + "", + "250th 251st 252nd 253rd 254th 255th 256th 257th 258th 259th 260th 261st 262nd 263rd 264th 265th", + "", + "1000th 1001st 1002nd 1003rd 1004th 1005th 1006th 1007th 1008th 1009th 1010th 1011th 1012th 1013th 1014th 1015th 1016th 1017th 1018th 1019th 1020th 1021st 1022nd 1023rd 1024th 1025th", + "", + "", + "===ES6===", + "", + "(function (lstTestRanges) {", + " 'use strict'", + "", + " let lstSuffix = 'th st nd rd th th th th th th'.split(' '),", + "", + " // ordinalString :: Int -> String", + " ordinalString = n =>", + " n.toString() + (", + " 11 <= n % 100 && 13 >= n % 100 ?", + " \"th\" : lstSuffix[n % 10]", + " ),", + " ", + " // range :: Int -> Int -> [Int]", + " range = (m, n) =>", + " Array.from({", + " length: (n - m) + 1", + " }, (_, i) => m + i);", + " ", + "", + " return lstTestRanges", + " .map(tpl => range", + " .apply(null, tpl)", + " .map(ordinalString)", + " );", + "", + "})([[0, 25], [250, 265], [1000, 1025]]);", + "", + "", + "{{Out}}", + "
[[\"0th\", \"1st\", \"2nd\", \"3rd\", \"4th\", \"5th\", \"6th\", \"7th\", \"8th\", ",
+      "\"9th\", \"10th\", \"11th\", \"12th\", \"13th\", \"14th\", \"15th\", \"16th\", ",
+      "\"17th\", \"18th\", \"19th\", \"20th\", \"21st\", \"22nd\", \"23rd\", \"24th\", \"25th\"], ",
+      "[\"250th\", \"251st\", \"252nd\", \"253rd\", \"254th\", \"255th\", \"256th\", \"257th\", ",
+      "\"258th\", \"259th\", \"260th\", \"261st\", \"262nd\", \"263rd\", \"264th\", \"265th\"], ",
+      "[\"1000th\", \"1001st\", \"1002nd\", \"1003rd\", \"1004th\", \"1005th\", \"1006th\", ",
+      "\"1007th\", \"1008th\", \"1009th\", \"1010th\", \"1011th\", \"1012th\", \"1013th\", ",
+      "\"1014th\", \"1015th\", \"1016th\", \"1017th\", \"1018th\", \"1019th\", \"1020th\", ",
+      "\"1021st\", \"1022nd\", \"1023rd\", \"1024th\", \"1025th\"]]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f3c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "console.log(function () {\n\n var lstSuffix = 'th st nd rd th th th th th th'.split(' '),\n\n fnOrdinalForm = function (n) {\n return n.toString() + (\n 11 <= n % 100 && 13 >= n % 100 ?\n \"th\" : lstSuffix[n % 10]\n );\n },\n\n range = function (m, n) {\n return Array.apply(\n null, Array(n - m + 1)\n ).map(function (x, i) {\n return m + i;\n });\n };\n\n return [[0, 25], [250, 265], [1000, 1025]].map(function (tpl) {\n return range.apply(null, tpl).map(fnOrdinalForm).join(' ');\n }).join('\\n\\n');\n \n}());\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Nth root", + "type": "Waypoint", + "description": [ + "Task:

Implement the algorithm to compute the principal nth root $\\sqrt[n]A$ of a positive real number A, as explained at the Wikipedia page.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Gives the ''n'':nth root of ''num'', with precision ''prec''. (''n'' defaults to 2 [e.g. sqrt], ''prec'' defaults to 12.)", + "", + "function nthRoot(num, nArg, precArg) {", + " var n = nArg || 2;", + " var prec = precArg || 12;", + " ", + " var x = 1; // Initial guess.", + " for (var i=0; i", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f3d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function nthRoot(num, nArg, precArg) {\n var n = nArg || 2;\n var prec = precArg || 12;\n \n var x = 1; // Initial guess.\n for (var i=0; ireplaceMe is a function.');" + ] + }, + { + "title": "Number names", + "type": "Waypoint", + "description": [ + "Task:", + "

Show how to spell out a number in English.

You can use a preexisting implementation or roll your own, but you should support inputs up to at least one million (or the maximum value of your language's default bounded integer type, if that's less).

Support for inputs other than positive integers (like zero, negative integers, and floating-point numbers) is optional.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f3f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Numerical integration/Gauss-Legendre Quadrature", + "type": "Waypoint", + "description": [ + "

{|border=1 cellspacing=0 cellpadding=3

", + "

|In a general Gaussian quadrature rule, an definite integral of $f(x)$ is first approximated over the interval $[-1,1]$ by a polynomial approximable function $g(x)$ and a known weighting function $W(x)$.

", + "

|$\\int_{-1}^1 f(x) \\, dx = \\int_{-1}^1 W(x) g(x) \\, dx$

", + "

|-

", + "

|Those are then approximated by a sum of function values at specified points $x_i$ multiplied by some weights $w_i$:

", + "

|$\\int_{-1}^1 W(x) g(x) \\, dx \\approx \\sum_{i=1}^n w_i g(x_i)$

", + "

|-

", + "

|In the case of Gauss-Legendre quadrature, the weighting function $W(x) = 1$, so we can approximate an integral of $f(x)$ with:

", + "

|$\\int_{-1}^1 f(x)\\,dx \\approx \\sum_{i=1}^n w_i f(x_i)$

", + "

|}

", + "

For this, we first need to calculate the nodes and the weights, but after we have them, we can reuse them for numerious integral evaluations, which greatly speeds up the calculation compared to more simple numerical integration methods.

{|border=1 cellspacing=0 cellpadding=3

", + "

|The $n$ evaluation points $x_i$ for a n-point rule, also called \"nodes\", are roots of n-th order Legendre Polynomials $P_n(x)$. Legendre polynomials are defined by the following recursive rule:

", + "

|$P_0(x) = 1$

", + "

$P_1(x) = x$

", + "

$nP_{n}(x) = (2n-1)xP_{n-1}(x)-(n-1)P_{n-2}(x)$

", + "

|-

", + "

|There is also a recursive equation for their derivative:

", + "

|$P_{n}'(x) = \\frac{n}{x^2-1} \\left( x P_n(x) - P_{n-1}(x) \\right)$

", + "

|-

", + "

|The roots of those polynomials are in general not analytically solvable, so they have to be approximated numerically, for example by Newton-Raphson iteration:

", + "

|$x_{n+1} = x_n - \\frac{f(x_n)}{f'(x_n)}$

", + "

|-

", + "

|The first guess $x_0$ for the $i$-th root of a $n$-order polynomial $P_n$ can be given by

", + "

|$x_0 = \\cos \\left( \\pi \\, \\frac{i - \\frac{1}{4}}{n+\\frac{1}{2}} \\right)$

", + "

|-

", + "

|After we get the nodes $x_i$, we compute the appropriate weights by:

", + "

|$w_i = \\frac{2}{\\left( 1-x_i^2 \\right) [P'_n(x_i)]^2}$

", + "

|-

", + "

|After we have the nodes and the weights for a n-point quadrature rule, we can approximate an integral over any interval $[a,b]$ by

", + "

|$\\int_a^b f(x)\\,dx \\approx \\frac{b-a}{2} \\sum_{i=1}^n w_i f\\left(\\frac{b-a}{2}x_i + \\frac{a+b}{2}\\right)$

", + "

|}

", + "

Task description

Similar to the task Numerical Integration, the task here is to calculate the definite integral of a function $f(x)$, but by applying an n-point Gauss-Legendre quadrature rule, as described here, for example. The input values should be an function f to integrate, the bounds of the integration interval a and b, and the number of gaussian evaluation points n. An reference implementation in Common Lisp is provided for comparison.

To demonstrate the calculation, compute the weights and nodes for an 5-point quadrature rule and then use them to compute:

", + "

$\\int_{-3}^{3} \\exp(x) \\, dx \\approx \\sum_{i=1}^5 w_i \\; \\exp(x_i) \\approx 20.036$

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f41", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Numerical integration", + "type": "Waypoint", + "description": [ + "

Write functions to calculate the definite integral of a function ƒ(x) using all five of the following methods:

", + "

:* rectangular

", + "

:::* left

", + "

:::* right

", + "

:::* midpoint

", + "

:* trapezium

", + "

:* Simpson's

", + "

Your functions should take in the upper and lower bounds (a and b), and the number of approximations to make in that range (n).

Assume that your example already has a function that gives values for ƒ(x).

Simpson's method is defined by the following pseudo-code:

", + "
",
+      "h := (b - a) / n",
+      "sum1 := f(a + h/2)",
+      "sum2 := 0loop on i from 1 to (n - 1)",
+      "    sum1 := sum1 + f(a + h * i + h/2)",
+      "    sum2 := sum2 + f(a + h * i)answer := (h / 6) * (f(a) + f(b) + 4*sum1 + 2*sum2)",
+      "

Demonstrate your function by showing the results for:

", + " ƒ(x) = x3, where x is [0,1], with 100 approximations. The exact result is 1/4, or 0.25.", + " ƒ(x) = 1/x, where x is [1,100], with 1,000 approximations. The exact result is the natural log of 100, or about 4.605170", + " ƒ(x) = x, where x is [0,5000], with 5,000,000 approximations. The exact result is 12,500,000.", + " ƒ(x) = x, where x is [0,6000], with 6,000,000 approximations. The exact result is 18,000,000.", + "

See also

", + "Active object for integrating a function of real time.", + "Numerical integration/Gauss-Legendre Quadrature for another integration method." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f42", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Numeric error propagation", + "type": "Waypoint", + "description": [ + "

If f, a, and b are values with uncertainties σf, σa, and σb, and c is a constant;

", + "then if f is derived from a, b, and c in the following ways, ", + "then σf can be calculated as follows:

;Addition/Subtraction

", + "

* If f = a ± c, or f = c ± a then σf = σa

", + "

* If f = a ± b then σf2 = σa2 + σb2

;Multiplication/Division

", + "

* If f = ca or f = ac then σf = |cσa|

", + "

* If f = ab or f = a / b then σf2 = f2( (σa / a)2 + (σb / b)2)

;Exponentiation

", + "

* If f = ac then σf = |fc(σa / a)|

", + "

Caution:

", + "

:This implementation of error propagation does not address issues of dependent and independent values. It is assumed that a and b are independent and so the formula for multiplication should not be applied to a*a for example. See the talk page for some of the implications of this issue.

", + "Task details:", + "Add an uncertain number type to your language that can support addition, subtraction, multiplication, division, and exponentiation between numbers with an associated error term together with 'normal' floating point numbers without an associated error term. Implement enough functionality to perform the following calculations.", + "Given coordinates and their errors:x1 = 100 ± 1.1y1 = 50 ± 1.2x2 = 200 ± 2.2y2 = 100 ± 2.3 if point p1 is located at (x1, y1) and p2 is at (x2, y2); calculate the distance between the two points using the classic Pythagorean formula: d = √ (x1 - x2)² + (y1 - y2)² ", + "Print and display both d and its error.", + "

References:", + "A Guide to Error Propagation B. Keeney, 2005.", + "Propagation of uncertainty Wikipedia.Related task:", + " Quaternion type" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f43", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Odd word problem", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a program that solves the odd word problem with the restrictions given below.

", + "Description:", + "

You are promised an input stream consisting of English letters and punctuations.

It is guaranteed that:

", + "the words (sequence of consecutive letters) are delimited by one and only one punctuation,", + "the stream will begin with a word,", + "the words will be at least one letter long, and ", + "a full stop (a period, [.]) appears after, and only after, the last word.Example:", + "

A stream with six words:

", + "

: what,is,the;meaning,of:life.

", + "

The task is to reverse the letters in every other word while leaving punctuations intact, producing:

", + "

: what,si,the;gninaem,of:efil.

", + "

while observing the following restrictions:

", + "Only I/O allowed is reading or writing one character at a time, which means: no reading in a string, no peeking ahead, no pushing characters back into the stream, and no storing characters in a global variable for later use;", + "You are not to explicitly save characters in a collection data structure, such as arrays, strings, hash tables, etc, for later reversal;", + "You are allowed to use recursions, closures, continuations, threads, co-routines, etc., even if their use implies the storage of multiple characters.Test cases:", + "

Work on both the \"life\" example given above, and also the text:

", + "

: we,are;not,in,kansas;any,more.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f45", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Old lady swallowed a fly", + "type": "Waypoint", + "description": [ + "Task:", + "

Present a program which emits the lyrics to the song I Knew an Old Lady Who Swallowed a Fly, taking advantage of the repetitive structure of the song's lyrics.

This song has multiple versions with slightly different lyrics, so all these programs might not emit identical output.

", + "Related task:", + " 99 Bottles of Beer" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f46", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Optional parameters", + "type": "Waypoint", + "description": [ + "Task:", + "

Define a function/method/subroutine which sorts a sequence (\"table\") of sequences (\"rows\") of strings (\"cells\"), by one of the strings. Besides the input to be sorted, it shall have the following optional parameters:

", + "

{|

", + "

|

", + "

----

", + " ordering", + "

A function specifying the ordering of strings; lexicographic by default.

", + " column", + "

An integer specifying which string of each row to compare; the first by default.

", + " reverse", + "

Reverses the ordering.

", + "

----

", + "

|}

This task should be considered to include both positional and named optional parameters, as well as overloading on argument count as in Java or selector name as in Smalltalk, or, in the extreme, using different function names. Provide these variations of sorting in whatever way is most natural to your language. If the language supports both methods naturally, you are encouraged to describe both.

Do not implement a sorting algorithm; this task is about the interface. If you can't use a built-in sort routine, just omit the implementation (with a comment).

See also:

", + "Named Arguments" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "See [[Named parameters#JavaScript]], to pass named parameters one uses an object with properties set:", + "function sorter(table, options) {", + " opts = {}", + " opts.ordering = options.ordering || 'lexicographic';", + " opts.column = options.column || 0;", + " opts.reverse = options.reverse || false;", + " ", + " // ...", + "}", + "", + "sorter(the_data, {reverse: true, ordering: 'numeric'});", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f4c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function sorter(table, options) {\n opts = {}\n opts.ordering = options.ordering || 'lexicographic';\n opts.column = options.column || 0;\n opts.reverse = options.reverse || false;\n \n // ...\n}\n\nsorter(the_data, {reverse: true, ordering: 'numeric'});\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Order disjoint list items", + "type": "Waypoint", + "description": [ + "

Given M as a list of items and another list N of items chosen from M, create M' as a list with the first occurrences of items from N sorted to be in one of the set of indices of their original occurrence in M but in the order given by their order in N.

That is, items in N are taken from M without replacement, then the corresponding positions in M' are filled by successive items from N.

", + "For example:", + "

if M is 'the cat sat on the mat'

", + "

And N is 'mat cat'

", + "

Then the result M' is 'the mat sat on the cat'.

The words not in N are left in their original positions.

", + "

If there are duplications then only the first instances in M up to as many as are mentioned in N are potentially re-ordered.

", + "For example:", + "

M = 'A B C A B C A B C'

", + "

N = 'C A C A'

Is ordered as:

", + "

M' = 'C B A C B A A B C'

", + "

Show the output, here, for at least the following inputs:

", + "
",
+      "Data M: 'the cat sat on the mat' Order N: 'mat cat'",
+      "Data M: 'the cat sat on the mat' Order N: 'cat mat'",
+      "Data M: 'A B C A B C A B C'      Order N: 'C A C A'",
+      "Data M: 'A B C A B D A B E'      Order N: 'E A D A'",
+      "Data M: 'A B'                    Order N: 'B'      ",
+      "Data M: 'A B'                    Order N: 'B A'    ",
+      "Data M: 'A B B A'                Order N: 'B A'",
+      "
", + "Cf:", + "Sort disjoint sublist" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES6===", + "", + "Accumulating a segmentation of M over a fold/reduce, and zipping with N:", + "", + "(() => {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // deleteFirst :: a -> [a] -> [a]", + " const deleteFirst = (x, xs) =>", + " xs.length > 0 ? (", + " x === xs[0] ? (", + " xs.slice(1)", + " ) : [xs[0]].concat(deleteFirst(x, xs.slice(1)))", + " ) : [];", + "", + " // flatten :: Tree a -> [a]", + " const flatten = t => (t instanceof Array ? concatMap(flatten, t) : [t]);", + "", + " // unwords :: [String] -> String", + " const unwords = xs => xs.join(' ');", + "", + " // words :: String -> [String]", + " const words = s => s.split(/\\s+/);", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) => {", + " const ny = ys.length;", + " return (xs.length <= ny ? xs : xs.slice(0, ny))", + " .map((x, i) => f(x, ys[i]));", + " };", + "", + " //------------------------------------------------------------------------", + "", + " // ORDER DISJOINT LIST ITEMS", + "", + " // disjointOrder :: [String] -> [String] -> [String]", + " const disjointOrder = (ms, ns) =>", + " flatten(", + " zipWith(", + " (a, b) => a.concat(b),", + " segments(ms, ns),", + " ns.concat('')", + " )", + " );", + "", + " // segments :: [String] -> [String] -> [String]", + " const segments = (ms, ns) => {", + " const dct = ms.reduce((a, x) => {", + " const wds = a.words,", + " blnFound = wds.indexOf(x) !== -1;", + "", + " return {", + " parts: a.parts.concat(blnFound ? [a.current] : []),", + " current: blnFound ? [] : a.current.concat(x),", + " words: blnFound ? deleteFirst(x, wds) : wds,", + " };", + " }, {", + " words: ns,", + " parts: [],", + " current: []", + " });", + "", + " return dct.parts.concat([dct.current]);", + " };", + "", + " // -----------------------------------------------------------------------", + " // FORMATTING TEST OUTPUT", + "", + " // transpose :: [[a]] -> [[a]]", + " const transpose = xs =>", + " xs[0].map((_, iCol) => xs.map((row) => row[iCol]));", + "", + " // maximumBy :: (a -> a -> Ordering) -> [a] -> a", + " const maximumBy = (f, xs) =>", + " xs.reduce((a, x) => a === undefined ? x : (", + " f(x, a) > 0 ? x : a", + " ), undefined);", + "", + " // 2 or more arguments", + " // curry :: Function -> Function", + " const curry = (f, ...args) => {", + " const intArgs = f.length,", + " go = xs =>", + " xs.length >= intArgs ? (", + " f.apply(null, xs)", + " ) : function () {", + " return go(xs.concat([].slice.apply(arguments)));", + " };", + " return go([].slice.call(args, 1));", + " };", + "", + " // justifyLeft :: Int -> Char -> Text -> Text", + " const justifyLeft = (n, cFiller, strText) =>", + " n > strText.length ? (", + " (strText + replicateS(n, cFiller))", + " .substr(0, n)", + " ) : strText;", + "", + " // replicateS :: Int -> String -> String", + " const replicateS = (n, s) => {", + " let v = s,", + " o = '';", + " if (n < 1) return o;", + " while (n > 1) {", + " if (n & 1) o = o.concat(v);", + " n >>= 1;", + " v = v.concat(v);", + " }", + " return o.concat(v);", + " };", + "", + " // -----------------------------------------------------------------------", + "", + " // TEST", + " return transpose(transpose([{", + " M: 'the cat sat on the mat',", + " N: 'mat cat'", + " }, {", + " M: 'the cat sat on the mat',", + " N: 'cat mat'", + " }, {", + " M: 'A B C A B C A B C',", + " N: 'C A C A'", + " }, {", + " M: 'A B C A B D A B E',", + " N: 'E A D A'", + " }, {", + " M: 'A B',", + " N: 'B'", + " }, {", + " M: 'A B',", + " N: 'B A'", + " }, {", + " M: 'A B B A',", + " N: 'B A'", + " }].map(dct => [", + " dct.M, dct.N,", + " unwords(disjointOrder(words(dct.M), words(dct.N)))", + " ]))", + " .map(col => {", + " const width = maximumBy((a, b) => a.length > b.length, col)", + " .length;", + " return col.map(curry(justifyLeft)(width, ' '));", + " }))", + " .map(", + " ([a, b, c]) => a + ' -> ' + b + ' -> ' + c", + " )", + " .join('\\n');", + "})();", + "", + "{{Out}}", + "
the cat sat on the mat  ->  mat cat  ->  the mat sat on the cat ",
+      "the cat sat on the mat  ->  cat mat  ->  the cat sat on the mat ",
+      "A B C A B C A B C       ->  C A C A  ->  C B A C B A A B C      ",
+      "A B C A B D A B E       ->  E A D A  ->  E B C A B D A B A      ",
+      "A B                     ->  B        ->  A B                    ",
+      "A B                     ->  B A      ->  B A                    ",
+      "A B B A                 ->  B A      ->  B A B A                
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f4d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // GENERIC FUNCTIONS\n\n // concatMap :: (a -> [b]) -> [a] -> [b]\n const concatMap = (f, xs) => [].concat.apply([], xs.map(f));\n\n // deleteFirst :: a -> [a] -> [a]\n const deleteFirst = (x, xs) =>\n xs.length > 0 ? (\n x === xs[0] ? (\n xs.slice(1)\n ) : [xs[0]].concat(deleteFirst(x, xs.slice(1)))\n ) : [];\n\n // flatten :: Tree a -> [a]\n const flatten = t => (t instanceof Array ? concatMap(flatten, t) : [t]);\n\n // unwords :: [String] -> String\n const unwords = xs => xs.join(' ');\n\n // words :: String -> [String]\n const words = s => s.split(/\\s+/);\n\n // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]\n const zipWith = (f, xs, ys) => {\n const ny = ys.length;\n return (xs.length <= ny ? xs : xs.slice(0, ny))\n .map((x, i) => f(x, ys[i]));\n };\n\n //------------------------------------------------------------------------\n\n // ORDER DISJOINT LIST ITEMS\n\n // disjointOrder :: [String] -> [String] -> [String]\n const disjointOrder = (ms, ns) =>\n flatten(\n zipWith(\n (a, b) => a.concat(b),\n segments(ms, ns),\n ns.concat('')\n )\n );\n\n // segments :: [String] -> [String] -> [String]\n const segments = (ms, ns) => {\n const dct = ms.reduce((a, x) => {\n const wds = a.words,\n blnFound = wds.indexOf(x) !== -1;\n\n return {\n parts: a.parts.concat(blnFound ? [a.current] : []),\n current: blnFound ? [] : a.current.concat(x),\n words: blnFound ? deleteFirst(x, wds) : wds,\n };\n }, {\n words: ns,\n parts: [],\n current: []\n });\n\n return dct.parts.concat([dct.current]);\n };\n\n // -----------------------------------------------------------------------\n // FORMATTING TEST OUTPUT\n\n // transpose :: [[a]] -> [[a]]\n const transpose = xs =>\n xs[0].map((_, iCol) => xs.map((row) => row[iCol]));\n\n // maximumBy :: (a -> a -> Ordering) -> [a] -> a\n const maximumBy = (f, xs) =>\n xs.reduce((a, x) => a === undefined ? x : (\n f(x, a) > 0 ? x : a\n ), undefined);\n\n // 2 or more arguments\n // curry :: Function -> Function\n const curry = (f, ...args) => {\n const intArgs = f.length,\n go = xs =>\n xs.length >= intArgs ? (\n f.apply(null, xs)\n ) : function () {\n return go(xs.concat([].slice.apply(arguments)));\n };\n return go([].slice.call(args, 1));\n };\n\n // justifyLeft :: Int -> Char -> Text -> Text\n const justifyLeft = (n, cFiller, strText) =>\n n > strText.length ? (\n (strText + replicateS(n, cFiller))\n .substr(0, n)\n ) : strText;\n\n // replicateS :: Int -> String -> String\n const replicateS = (n, s) => {\n let v = s,\n o = '';\n if (n < 1) return o;\n while (n > 1) {\n if (n & 1) o = o.concat(v);\n n >>= 1;\n v = v.concat(v);\n }\n return o.concat(v);\n };\n\n // -----------------------------------------------------------------------\n\n // TEST\n return transpose(transpose([{\n M: 'the cat sat on the mat',\n N: 'mat cat'\n }, {\n M: 'the cat sat on the mat',\n N: 'cat mat'\n }, {\n M: 'A B C A B C A B C',\n N: 'C A C A'\n }, {\n M: 'A B C A B D A B E',\n N: 'E A D A'\n }, {\n M: 'A B',\n N: 'B'\n }, {\n M: 'A B',\n N: 'B A'\n }, {\n M: 'A B B A',\n N: 'B A'\n }].map(dct => [\n dct.M, dct.N,\n unwords(disjointOrder(words(dct.M), words(dct.N)))\n ]))\n .map(col => {\n const width = maximumBy((a, b) => a.length > b.length, col)\n .length;\n return col.map(curry(justifyLeft)(width, ' '));\n }))\n .map(\n ([a, b, c]) => a + ' -> ' + b + ' -> ' + c\n )\n .join('\\n');\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Ordered Partitions", + "type": "Waypoint", + "description": [ + "

In this task we want to find the ordered partitions into fixed-size blocks. This task is related to Combinations in that it has to do with discrete mathematics and moreover a helper function to compute combinations is (probably) needed to solve this task.

$partitions(\\mathit{arg}_1,\\mathit{arg}_2,...,\\mathit{arg}_n)$ should generate all distributions of the elements in $\\{1,...,\\Sigma_{i=1}^n\\mathit{arg}_i\\}$ into $n$ blocks of respective size $\\mathit{arg}_1,\\mathit{arg}_2,...,\\mathit{arg}_n$.

Example 1: $partitions(2,0,2)$ would create:

",
+      "{({1, 2}, {}, {3, 4}), ",
+      " ({1, 3}, {}, {2, 4}), ",
+      " ({1, 4}, {}, {2, 3}), ",
+      " ({2, 3}, {}, {1, 4}), ",
+      " ({2, 4}, {}, {1, 3}), ",
+      " ({3, 4}, {}, {1, 2})}",
+      "

Example 2: $partitions(1,1,1)$ would create:

",
+      "{({1}, {2}, {3}), ",
+      " ({1}, {3}, {2}), ",
+      " ({2}, {1}, {3}), ",
+      " ({2}, {3}, {1}), ",
+      " ({3}, {1}, {2}), ",
+      " ({3}, {2}, {1})}",
+      "

Note that the number of elements in the list is

", + "

${\\mathit{arg}_1+\\mathit{arg}_2+...+\\mathit{arg}_n \\choose \\mathit{arg}_1} \\cdot {\\mathit{arg}_2+\\mathit{arg}_3+...+\\mathit{arg}_n \\choose \\mathit{arg}_2} \\cdot \\ldots \\cdot {\\mathit{arg}_n \\choose \\mathit{arg}_n}$

", + "

(see the definition of the binomial coefficient if you are not familiar with this notation) and the number of elements remains the same regardless of how the argument is permuted

", + "

(i.e. the multinomial coefficient). Also, $partitions(1,1,1)$ creates the permutations of $\\{1,2,3\\}$ and thus there would be $3! = 6$ elements in the list.

Note: Do not use functions that are not in the standard library of the programming language you use. Your file should be written so that it can be executed on the command line and by default outputs the result of $partitions(2,0,2)$. If the programming language does not support polyvariadic functions pass a list as an argument.

Notation

Here are some explanatory remarks on the notation used in the task description:

$\\{1, \\ldots, n\\}$ denotes the set of consecutive numbers from $1$ to $n$, e.g. $\\{1,2,3\\}$ if $n = 3$. $\\Sigma$ is the mathematical notation for summation, e.g. $\\Sigma_{i=1}^3 i = 6$ (see also [http://en.wikipedia.org/wiki/Summation#Capital-sigma_notation]). $\\mathit{arg}_1,\\mathit{arg}_2,...,\\mathit{arg}_n$ are the arguments — natural numbers — that the sought function receives.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Functional (ES 5)===", + "", + "{{trans|Haskell}}", + "", + "(function () {", + " 'use strict';", + "", + " // [n] -> [[[n]]]", + " function partitions(a1, a2, a3) {", + " var n = a1 + a2 + a3;", + "", + " return combos(range(1, n), n, [a1, a2, a3]);", + " }", + "", + " function combos(s, n, xxs) {", + " if (!xxs.length) return [[]];", + "", + " var x = xxs[0],", + " xs = xxs.slice(1);", + "", + " return mb( choose(s, n, x), function (l_rest) {", + " return mb( combos(l_rest[1], (n - x), xs), function (r) {", + " // monadic return/injection requires 1 additional", + " // layer of list nesting:", + " return [ [l_rest[0]].concat(r) ];", + " ", + " })});", + " }", + "", + " function choose(aa, n, m) {", + " if (!m) return [[[], aa]];", + "", + " var a = aa[0],", + " as = aa.slice(1);", + "", + " return n === m ? (", + " [[aa, []]]", + " ) : (", + " choose(as, n - 1, m - 1).map(function (xy) {", + " return [[a].concat(xy[0]), xy[1]];", + " }).concat(choose(as, n - 1, m).map(function (xy) {", + " return [xy[0], [a].concat(xy[1])];", + " }))", + " );", + " }", + " ", + " // GENERIC", + "", + " // Monadic bind (chain) for lists", + " function mb(xs, f) {", + " return [].concat.apply([], xs.map(f));", + " }", + "", + " // [m..n]", + " function range(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(function (x, i) {", + " return m + i;", + " });", + " }", + " ", + " // EXAMPLE", + "", + " return partitions(2, 0, 2);", + "", + "})();", + "", + "{{Out}}", + "", + "[[[1, 2], [], [3, 4]], ", + " [[1, 3], [], [2, 4]],", + " [[1, 4], [], [2, 3]],", + " [[2, 3], [], [1, 4]],", + " [[2, 4], [], [1, 3]],", + " [[3, 4], [], [1, 2]]]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f4e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function () {\n 'use strict';\n\n // [n] -> [[[n]]]\n function partitions(a1, a2, a3) {\n var n = a1 + a2 + a3;\n\n return combos(range(1, n), n, [a1, a2, a3]);\n }\n\n function combos(s, n, xxs) {\n if (!xxs.length) return [[]];\n\n var x = xxs[0],\n xs = xxs.slice(1);\n\n return mb( choose(s, n, x), function (l_rest) {\n return mb( combos(l_rest[1], (n - x), xs), function (r) {\n // monadic return/injection requires 1 additional\n // layer of list nesting:\n return [ [l_rest[0]].concat(r) ];\n \n })});\n }\n\n function choose(aa, n, m) {\n if (!m) return [[[], aa]];\n\n var a = aa[0],\n as = aa.slice(1);\n\n return n === m ? (\n [[aa, []]]\n ) : (\n choose(as, n - 1, m - 1).map(function (xy) {\n return [[a].concat(xy[0]), xy[1]];\n }).concat(choose(as, n - 1, m).map(function (xy) {\n return [xy[0], [a].concat(xy[1])];\n }))\n );\n }\n \n // GENERIC\n\n // Monadic bind (chain) for lists\n function mb(xs, f) {\n return [].concat.apply([], xs.map(f));\n }\n\n // [m..n]\n function range(m, n) {\n return Array.apply(null, Array(n - m + 1)).map(function (x, i) {\n return m + i;\n });\n }\n \n // EXAMPLE\n\n return partitions(2, 0, 2);\n\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Ordered words", + "type": "Waypoint", + "description": [ + "

An ordered word is a word in which the letters appear in alphabetic order.

Examples include abbey and dirt.

", + "

Find and display all the ordered words in the dictionary unixdict.txt that have the longest word length.

(Examples that access the dictionary file locally assume that you have downloaded this file yourself.)

The display needs to be shown on this page.

", + "


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Using [http://nodejs.org/ node.js]:", + "", + "var fs = require('fs'), print = require('sys').print;", + "fs.readFile('./unixdict.txt', 'ascii', function (err, data) {", + " var is_ordered = function(word){return word.split('').sort().join('') === word;},", + " ordered_words = data.split('\\n').filter(is_ordered).sort(function(a, b){return a.length - b.length}).reverse(),", + " longest = [], curr = len = ordered_words[0].length, lcv = 0;", + " while (curr === len){", + " longest.push(ordered_words[lcv]);", + " curr = ordered_words[++lcv].length;", + " };", + " print(longest.sort().join(', ') + '\\n');", + "});", + "", + "Output:", + "
abbott, accent, accept, access, accost, almost, bellow, billow, biopsy, chilly, choosy, choppy, effort, floppy, glossy, knotty
", + "", + "Alternative version (also using Node.js):", + "", + "var http = require('http');", + "", + "http.get({", + " host: 'www.puzzlers.org',", + " path: '/pub/wordlists/unixdict.txt'", + "}, function(res) {", + " var data = '';", + " res.on('data', function(chunk) {", + " data += chunk;", + " });", + " res.on('end', function() {", + " var words = data.split('\\n');", + " var max = 0;", + " var ordered = [];", + " words.forEach(function(word) {", + " if (word.split('').sort().join('') != word) return;", + " if (word.length == max) {", + " ordered.push(word);", + " } else if (word.length > max) {", + " ordered = [word];", + " max = word.length;", + " }", + " });", + " console.log(ordered.join(', '));", + " });", + "});", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f4f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var fs = require('fs'), print = require('sys').print;\nfs.readFile('./unixdict.txt', 'ascii', function (err, data) {\n var is_ordered = function(word){return word.split('').sort().join('') === word;},\n ordered_words = data.split('\\n').filter(is_ordered).sort(function(a, b){return a.length - b.length}).reverse(),\n longest = [], curr = len = ordered_words[0].length, lcv = 0;\n while (curr === len){\n longest.push(ordered_words[lcv]);\n curr = ordered_words[++lcv].length;\n };\n print(longest.sort().join(', ') + '\\n');\n});\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Order two numerical lists", + "type": "Waypoint", + "description": [ + "

Write a function that orders two lists or arrays filled with numbers.

", + "

The function should accept two lists as arguments and return true if the first list should be ordered before the second, and false otherwise.

The order is determined by lexicographic order: Comparing the first element of each list.

", + "

If the first elements are equal, then the second elements should be compared, and so on, until one of the list has no more elements.

", + "

If the first list runs out of elements the result is true.

", + "

If the second list or both run out of elements the result is false.

Note: further clarification of lexicographical ordering is expounded on the talk page here and here.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES6===", + "", + "<= is already defined for numeric lists in JavaScript", + "", + "(() => {", + " 'use strict';", + "", + " // <= is already defined for lists in JS", + "", + " // compare :: [a] -> [a] -> Bool", + " const compare = (xs, ys) => xs <= ys;", + "", + "", + " // TEST", + " return [", + " compare([1, 2, 1, 3, 2], [1, 2, 0, 4, 4, 0, 0, 0]),", + " compare([1, 2, 0, 4, 4, 0, 0, 0], [1, 2, 1, 3, 2])", + " ];", + "", + " // --> [false, true]", + "})()", + "", + "", + "{{Out}}", + "[false, true]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f50", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // <= is already defined for lists in JS\n\n // compare :: [a] -> [a] -> Bool\n const compare = (xs, ys) => xs <= ys;\n\n\n // TEST\n return [\n compare([1, 2, 1, 3, 2], [1, 2, 0, 4, 4, 0, 0, 0]),\n compare([1, 2, 0, 4, 4, 0, 0, 0], [1, 2, 1, 3, 2])\n ];\n\n // --> [false, true]\n})()\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Palindrome detection", + "type": "Waypoint", + "description": [ + "

A palindrome is a phrase which reads the same backward and forward.

", + "

Write a function or program that checks whether a given sequence of characters (or, if you prefer, bytes)

", + "

is a palindrome.

For extra credit:

", + "Support Unicode characters.", + "Write a second function (possibly as a wrapper to the first) which detects inexact palindromes, i.e. phrases that are palindromes if white-space and punctuation is ignored and case-insensitive comparison is used.It might be useful for this task to know how to reverse a string.", + "This task's entries might also form the subjects of the task Test a function.", + "


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function isPalindrome(str) {", + " return str === str.split(\"\").reverse().join(\"\");", + "}", + "", + "console.log(isPalindrome(\"ingirumimusnocteetconsumimurigni\"));", + "", + "ES6 implementation", + "var isPal = str => str === str.split(\"\").reverse().join(\"\");", + "", + "", + "Or, adding a wrapper function to prepare the test data:", + "", + "(function (strSample) {", + "", + " // isPalindrome :: String -> Bool", + " let isPalindrome = s =>", + " s.split('')", + " .reverse()", + " .join('') === s;", + "", + "", + "", + " // TESTING ", + "", + " // lowerCaseNoSpace :: String -> String", + " let lowerCaseNoSpace = s =>", + " concatMap(c => c !== ' ' ? [c.toLowerCase()] : [],", + " s.split(''))", + " .join(''),", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + "", + " return isPalindrome(", + " lowerCaseNoSpace(strSample)", + " );", + "", + "", + "})(\"In girum imus nocte et consumimur igni\");", + "", + "", + "{{Out}}", + "
true
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f51", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function isPalindrome(str) {\n return str === str.split(\"\").reverse().join(\"\");\n}\n\nconsole.log(isPalindrome(\"ingirumimusnocteetconsumimurigni\"));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Pangram checker", + "type": "Waypoint", + "description": [ + "

A pangram is a sentence that contains all the letters of the English alphabet at least once.

For example: The quick brown fox jumps over the lazy dog.

", + "Task:", + "

Write a function or method to check a sentence to see if it is a pangram (or not) and show its use.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Iterative====", + "", + "function isPangram(s) {", + " var letters = \"zqxjkvbpygfwmucldrhsnioate\"", + " // sorted by frequency ascending (http://en.wikipedia.org/wiki/Letter_frequency)", + " s = s.toLowerCase().replace(/[^a-z]/g,'')", + " for (var i = 0; i < 26; i++)", + " if (s.indexOf(letters[i]) < 0) return false", + " return true", + "}", + "", + "console.log(isPangram(\"is this a pangram\")) // false", + "console.log(isPangram(\"The quick brown fox jumps over the lazy dog\")) // true", + "", + "===ES6===", + "====Functional====", + "", + "(() => {", + " 'use strict';", + "", + " // isPangram :: String -> Bool", + " let isPangram = s => {", + " let lc = s.toLowerCase();", + "", + " return 'abcdefghijklmnopqrstuvwxyz'", + " .split('')", + " .filter(c => lc.indexOf(c) === -1)", + " .length === 0;", + " };", + "", + " // TEST", + " return [", + " 'is this a pangram',", + " 'The quick brown fox jumps over the lazy dog'", + " ].map(isPangram);", + "", + "})();", + "", + "{{Out}}", + "
[false, true]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f52", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function isPangram(s) {\n var letters = \"zqxjkvbpygfwmucldrhsnioate\"\n // sorted by frequency ascending (http://en.wikipedia.org/wiki/Letter_frequency)\n s = s.toLowerCase().replace(/[^a-z]/g,'')\n for (var i = 0; i < 26; i++)\n if (s.indexOf(letters[i]) < 0) return false\n return true\n}\n\nconsole.log(isPangram(\"is this a pangram\")) // false\nconsole.log(isPangram(\"The quick brown fox jumps over the lazy dog\")) // true\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Paraffins", + "type": "Waypoint", + "description": [ + "

This organic chemistry task is essentially to implement a tree enumeration algorithm.

", + "Task:", + "

Enumerate, without repetitions and in order of increasing size, all possible paraffin molecules (also known as alkanes).

", + "

Paraffins are built up using only carbon atoms, which has four bonds, and hydrogen, which has one bond. All bonds for each atom must be used, so it is easiest to think of an alkane as linked carbon atoms forming the \"backbone\" structure, with adding hydrogen atoms linking the remaining unused bonds.

In a paraffin, one is allowed neither double bonds (two bonds between the same pair of atoms), nor cycles of linked carbons. So all paraffins with n carbon atoms share the empirical formula CnH2n+2

But for all n ≥ 4 there are several distinct molecules (\"isomers\") with the same formula but different structures.

The number of isomers rises rather rapidly when n increases.

In counting isomers it should be borne in mind that the four bond positions on a given carbon atom can be freely interchanged and bonds rotated (including 3-D \"out of the paper\" rotations when it's being observed on a flat diagram), so rotations or re-orientations of parts of the molecule (without breaking bonds) do not give different isomers. So what seem at first to be different molecules may in fact turn out to be different orientations of the same molecule.

", + "Example:", + "

With n = 3 there is only one way of linking the carbons despite the different orientations the molecule can be drawn; and with n = 4 there are two configurations:

", + "

::* a straight chain: (CH3)(CH2)(CH2)(CH3)

", + "

::* a branched chain: (CH3)(CH(CH3))(CH3)

", + "

Due to bond rotations, it doesn't matter which direction the branch points in.

The phenomenon of \"stereo-isomerism\" (a molecule being different from its mirror image due to the actual 3-D arrangement of bonds) is ignored for the purpose of this task.

The input is the number n of carbon atoms of a molecule (for instance 17).

The output is how many different different paraffins there are with n carbon atoms (for instance 24,894 if n = 17).

The sequence of those results is visible in the Sloane encyclopedia. The sequence is (the index starts from zero, and represents the number of carbon atoms):

1, 1, 1, 1, 2, 3, 5, 9, 18, 35, 75, 159, 355, 802, 1858, 4347, 10359,

", + "

24894, 60523, 148284, 366319, 910726, 2278658, 5731580, 14490245,

", + "

36797588, 93839412, 240215803, 617105614, 1590507121, 4111846763,

", + "

10660307791, 27711253769, ...

", + "Extra credit:", + "

Show the paraffins in some way.

A flat 1D representation, with arrays or lists is enough, for instance:

*Main> all_paraffins 1

", + "

[CCP H H H H]

", + "Main> all_paraffins 2 [BCP (C H H H) (C H H H)]", + "Main> all_paraffins 3 [CCP H H (C H H H) (C H H H)]", + "Main> all_paraffins 4 [BCP (C H H (C H H H)) (C H H (C H H H)),CCP H (C H H H) (C H H H)", + "

(C H H H)]

", + "Main> all_paraffins 5 [CCP H H (C H H (C H H H)) (C H H (C H H H)),CCP H (C H H H)", + "

(C H H H) (C H H (C H H H)),CCP (C H H H) (C H H H) (C H H H)

", + "

(C H H H)]

", + "Main> all_paraffins 6 [BCP (C H H (C H H (C H H H))) (C H H (C H H (C H H H))),BCP", + "

(C H H (C H H (C H H H))) (C H (C H H H) (C H H H)),BCP (C H

", + "

(C H H H) (C H H H)) (C H (C H H H) (C H H H)),CCP H (C H H H)

", + "

(C H H (C H H H)) (C H H (C H H H)),CCP (C H H H) (C H H H)

", + "

(C H H H) (C H H (C H H H))]

Showing a basic 2D ASCII-art representation of the paraffins is better; for instance (molecule names aren't necessary):

", + "
 Methane         Ethane              Propane              Isobutane"
+    ],
+    "null": [
+      "    H             H   H             H   H   H             H   H   H",
+      "    |             |   |             |   |   |             |   |   |",
+      "H - C - H     H - C - C - H     H - C - C - C - H     H - C - C - C - H",
+      "    |             |   |             |   |   |             |   |   |",
+      "    H             H   H             H   H   H             H   |   H",
+      "                                                              |",
+      "                                                          H - C - H",
+      "                                                              |",
+      "                                                              H
", + "
Links:
", + "
  • A paper that explains the problem and its solution in a functional language:
http://www.cs.wright.edu/~tkprasad/courses/cs776/paraffins-turner.pdf
  • A Haskell implementation:
https://github.com/ghc/nofib/blob/master/imaginary/paraffins/Main.hs
  • A Scheme implementation:
http://www.ccs.neu.edu/home/will/Twobit/src/paraffins.scm
  • A Fortress implementation:
http://java.net/projects/projectfortress/sources/sources/content/ProjectFortress/demos/turnersParaffins0.fss?rev=3005", + "

", + "" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f53", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Parallel Brute Force", + "type": "Waypoint", + "description": [ + "Task:

Find, through brute force, the five-letter passwords corresponding with the following SHA-256 hashes:

1. 1115dd800feaacefdf481f1f9070374a2a81e27880f187396db67958b207cbad

", + "

2. 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b

", + "

3. 74e1bb62f8dabb8125a58852b63bdf6eaef667cb56ac7f7cdba6d7305c50a22f

Your program should naively iterate through all possible passwords consisting only of five lower-case ASCII English letters. It should use concurrent or parallel processing, if your language supports that feature. You may calculate SHA-256 hashes by calling a library or through a custom implementation. Print each matching password, along with its SHA-256 hash.

Related task: SHA-256

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f54", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Parallel calculations", + "type": "Waypoint", + "description": [ + "

Many programming languages allow you to specify computations to be run in parallel.

", + "

While Concurrent computing is focused on concurrency,

", + "

the purpose of this task is to distribute time-consuming calculations

", + "

on as many CPUs as possible.

Assume we have a collection of numbers, and want to find the one

", + "

with the largest minimal prime factor

", + "

(that is, the one that contains relatively large factors).

", + "

To speed up the search, the factorization should be done

", + "

in parallel using separate threads or processes,

", + "

to take advantage of multi-core CPUs.

Show how this can be formulated in your language.

", + "

Parallelize the factorization of those numbers,

", + "

then search the returned list of numbers and factors

", + "

for the largest minimal factor,

", + "

and return that number and its prime factors.

For the prime number decomposition

", + "

you may use the solution of the Prime decomposition task.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "This code demonstrates Web Workers. This should work on current versions of Firefox, Safari, Chrome and Opera.", + "", + "This first portion should be placed in a file called \"parallel_worker.js\". This file contains the logic used by every worker created.", + "", + "var onmessage = function(event) { ", + " postMessage({\"n\" : event.data.n,", + " \"factors\" : factor(event.data.n),", + " \"id\" : event.data.id});", + "};", + "", + "function factor(n) {", + " var factors = [];", + " for(p = 2; p <= n; p++) {", + " if((n % p) == 0) {", + " factors[factors.length] = p;", + " n /= p;", + " }", + " }", + " return factors;", + "}", + "", + "", + "For each number a worker is spawned. Once the final worker completes its task (worker_count is reduced to 0), the reduce function is called to determine which number is the answer.", + "", + "var numbers = [12757923, 12878611, 12757923, 15808973, 15780709, 197622519];", + "var workers = [];", + "var worker_count = 0;", + "", + "var results = [];", + "", + "for(var i = 0; i < numbers.length; i++) {", + " worker_count++;", + " workers[i] = new Worker(\"parallel_worker.js\");", + " workers[i].onmessage = accumulate;", + " workers[i].postMessage({n: numbers[i], id: i});", + "}", + "", + "function accumulate(event) {", + " n = event.data.n;", + " factors = event.data.factors;", + " id = event.data.id;", + " console.log(n + \" : \" + factors);", + " results[id] = {n:n, factors:factors};", + " // Cleanup - kill the worker and countdown until all work is done", + " workers[id].terminate();", + " worker_count--;", + " if(worker_count == 0)", + "\treduce();", + "}", + "", + "function reduce() {", + " answer = 0;", + " for(i = 1; i < results.length; i++) {", + "\tmin = results[i].factors[0];", + "\tlargest_min = results[answer].factors[0];", + "\tif(min > largest_min)", + "\t answer = i;", + " }", + " n = results[answer].n;", + " factors = results[answer].factors;", + " console.log(\"The number with the relatively largest factors is: \" + n + \" : \" + factors);", + "}", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f55", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nvar onmessage = function(event) { \n postMessage({\"n\" : event.data.n,\n \"factors\" : factor(event.data.n),\n \"id\" : event.data.id});\n};\n\nfunction factor(n) {\n var factors = [];\n for(p = 2; p <= n; p++) {\n if((n % p) == 0) {\n factors[factors.length] = p;\n n /= p;\n }\n }\n return factors;\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Parse an IP Address", + "type": "Waypoint", + "description": [ + "

The purpose of this task is to demonstrate parsing of text-format IP addresses, using IPv4 and IPv6.

Taking the following as inputs:

", + "

{| border=\"1\" cellspacing=\"0\" cellpadding=2

", + "

|-

", + "

|127.0.0.1

", + "

|The \"localhost\" IPv4 address

", + "

|-

", + "

|127.0.0.1:80

", + "

|The \"localhost\" IPv4 address, with a specified port (80)

", + "

|-

", + "

|::1

", + "

|The \"localhost\" IPv6 address

", + "

|-

", + "

|[::1]:80

", + "

|The \"localhost\" IPv6 address, with a specified port (80)

", + "

|-

", + "

|2605:2700:0:3::4713:93e3

", + "

|Rosetta Code's primary server's public IPv6 address

", + "

|-

", + "

|[2605:2700:0:3::4713:93e3]:80

", + "

|Rosetta Code's primary server's public IPv6 address, with a specified port (80)

", + "

|}

Emit each described IP address as a hexadecimal integer representing the address, the address space, and the port number specified, if any. In languages where variant result types are clumsy, the result should be ipv4 or ipv6 address number, something which says which address space was represented, port number and something that says if the port was specified.

For example 127.0.0.1 has the address number 7F000001 (2130706433 decimal) in the ipv4 address space. ::ffff:127.0.0.1 represents the same address in the ipv6 address space where it has the address number FFFF7F000001 (281472812449793 decimal). Meanwhile ::1 has address number 1 and serves the same purpose in the ipv6 address space that 127.0.0.1 serves in the ipv4 address space.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f58", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Parsing/RPN calculator algorithm", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a stack-based evaluator for an expression in reverse Polish notation (RPN) that also shows the changes in the stack as each individual token is processed as a table.

", + "Assume an input of a correct, space separated, string of tokens of an RPN expression", + "Test with the RPN expression generated from the Parsing/Shunting-yard algorithm task: 3 4 2 * 1 5 - 2 3 ^ ^ / + ", + "Print or display the output hereNotes:", + " ^ means exponentiation in the expression above.", + " / means division.See also:", + " Parsing/Shunting-yard algorithm for a method of generating an RPN from an infix expression.", + " Several solutions to 24 game/Solve make use of RPN evaluators (although tracing how they work is not a part of that task).", + " Parsing/RPN to infix conversion.", + " Arithmetic evaluation." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var e = '3 4 2 * 1 5 - 2 3 ^ ^ / +'", + "var s=[], e=e.split(' ')", + "for (var i in e) {", + "\tvar t=e[i], n=+t", + "\tif (n == t)", + "\t\ts.push(n)", + "\telse {", + "\t\tvar o2=s.pop(), o1=s.pop()", + "\t\tswitch (t) {", + "\t\t\tcase '+': s.push(o1+o2); break;", + "\t\t\tcase '-': s.push(o1-o2); break;", + "\t\t\tcase '*': s.push(o1*o2); break;", + "\t\t\tcase '/': s.push(o1/o2); break;", + "\t\t\tcase '^': s.push(Math.pow(o1,o2)); break;", + "\t\t}", + "\t}", + "\tdocument.write(t, ': ', s, '
')", + "}
", + "{{out}}", + "
",
+      "3: 3",
+      "4: 3,4",
+      "2: 3,4,2",
+      "*: 3,8",
+      "1: 3,8,1",
+      "5: 3,8,1,5",
+      "-: 3,8,-4",
+      "2: 3,8,-4,2",
+      "3: 3,8,-4,2,3",
+      "^: 3,8,-4,8",
+      "^: 3,8,65536",
+      "/: 3,0.0001220703125",
+      "+: 3.0001220703125",
+      "
", + "==== With checks and messages ====", + "var e = '3 4 2 * 1 5 - 2 3 ^ ^ / +'", + "eval: {", + "\tdocument.write(e, '
')", + "\tvar s=[], e=e.split(' ')", + "\tfor (var i in e) {", + "\t\tvar t=e[i], n=+t", + "\t\tif (!t) continue", + "\t\tif (n == t)", + "\t\t\ts.push(n)", + "\t\telse {", + "\t\t\tif ('+-*/^'.indexOf(t) == -1) {", + "\t\t\t\tdocument.write(t, ': ', s, '
', 'Unknown operator!
')", + "\t\t\t\tbreak eval", + "\t\t\t}", + "\t\t\tif (s.length<2) {", + "\t\t\t\tdocument.write(t, ': ', s, '
', 'Insufficient operands!
')", + "\t\t\t\tbreak eval", + "\t\t\t}", + "\t\t\tvar o2=s.pop(), o1=s.pop()", + "\t\t\tswitch (t) {", + "\t\t\t\tcase '+': s.push(o1+o2); break", + "\t\t\t\tcase '-': s.push(o1-o2); break", + "\t\t\t\tcase '*': s.push(o1*o2); break", + "\t\t\t\tcase '/': s.push(o1/o2); break", + "\t\t\t\tcase '^': s.push(Math.pow(o1,o2))", + "\t\t\t}", + "\t\t}", + "\t\tdocument.write(t, ': ', s, '
')", + "\t}", + "\tif (s.length>1) {", + "\t\tdocument.write('Insufficient operators!
')", + "\t}", + "}
", + "{{out}}", + "
",
+      "3 4 2 * 1 5 - 2 3 ^ ^ / +",
+      "3: 3",
+      "4: 3,4",
+      "2: 3,4,2",
+      "*: 3,8",
+      "1: 3,8,1",
+      "5: 3,8,1,5",
+      "-: 3,8,-4",
+      "2: 3,8,-4,2",
+      "3: 3,8,-4,2,3",
+      "^: 3,8,-4,8",
+      "^: 3,8,65536",
+      "/: 3,0.0001220703125",
+      "+: 3.0001220703125",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f59", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var e = '3 4 2 * 1 5 - 2 3 ^ ^ / +'\nvar s=[], e=e.split(' ')\nfor (var i in e) {\n\tvar t=e[i], n=+t\n\tif (n == t)\n\t\ts.push(n)\n\telse {\n\t\tvar o2=s.pop(), o1=s.pop()\n\t\tswitch (t) {\n\t\t\tcase '+': s.push(o1+o2); break;\n\t\t\tcase '-': s.push(o1-o2); break;\n\t\t\tcase '*': s.push(o1*o2); break;\n\t\t\tcase '/': s.push(o1/o2); break;\n\t\t\tcase '^': s.push(Math.pow(o1,o2)); break;\n\t\t}\n\t}\n\tdocument.write(t, ': ', s, '
')\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Parsing/RPN to infix conversion", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a program that takes an RPN representation of an expression formatted as a space separated sequence of tokens and generates the equivalent expression in infix notation.

Assume an input of a correct, space separated, string of tokens", + "Generate a space separated output string representing the same expression in infix notation", + "Show how the major datastructure of your algorithm changes with each new token parsed.", + "Test with the following input RPN strings then print and display the output here.{|", + "

! RPN input !! sample output

", + "

|- || align=\"center\"

", + "

| 3 4 2 * 1 5 - 2 3 ^ ^ / +|| 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3

", + "

|- || align=\"center\"

", + "

| 1 2 + 3 4 + ^ 5 6 + ^|| ( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )

", + "

|}

Operator precedence and operator associativity is given in this table:{|

! operator !! precedence !! associativity !! operation

", + "

|- || align=\"center\"

", + "

| ^ || 4 || right || exponentiation

", + "

|- || align=\"center\"

", + "

| * || 3 || left || multiplication

", + "

|- || align=\"center\"

", + "

| / || 3 || left || division

", + "

|- || align=\"center\"

", + "

| + || 2 || left || addition

", + "

|- || align=\"center\"

", + "

| - || 2 || left || subtraction

", + "

|}

", + "See also:", + " Parsing/Shunting-yard algorithm for a method of generating an RPN from an infix expression.", + " Parsing/RPN calculator algorithm for a method of calculating a final value from this output RPN expression.", + " Postfix to infix from the RubyQuiz site." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Needs EcmaScript 6 support (e.g. Chrome).", + "", + "const Associativity = {", + " /** a / b / c = (a / b) / c */", + " left: 0,", + " /** a ^ b ^ c = a ^ (b ^ c) */", + " right: 1,", + " /** a + b + c = (a + b) + c = a + (b + c) */", + " both: 2,", + "};", + "const operators = {", + " '+': { precedence: 2, associativity: Associativity.both },", + " '-': { precedence: 2, associativity: Associativity.left },", + " '*': { precedence: 3, associativity: Associativity.both },", + " '/': { precedence: 3, associativity: Associativity.left },", + " '^': { precedence: 4, associativity: Associativity.right },", + "};", + "class NumberNode {", + " constructor(text) { this.text = text; }", + " toString() { return this.text; }", + "}", + "class InfixNode {", + " constructor(fnname, operands) {", + " this.fnname = fnname;", + " this.operands = operands;", + " }", + " toString(parentPrecedence = 0) {", + " const op = operators[this.fnname];", + " const leftAdd = op.associativity === Associativity.right ? 0.01 : 0;", + " const rightAdd = op.associativity === Associativity.left ? 0.01 : 0;", + " if (this.operands.length !== 2) throw Error(\"invalid operand count\");", + " const result = this.operands[0].toString(op.precedence + leftAdd)", + " +` ${this.fnname} ${this.operands[1].toString(op.precedence + rightAdd)}`;", + " if (parentPrecedence > op.precedence) return `( ${result} )`;", + " else return result;", + " }", + "}", + "function rpnToTree(tokens) {", + " const stack = [];", + " console.log(`input = ${tokens}`);", + " for (const token of tokens.split(\" \")) {", + " if (token in operators) {", + " const op = operators[token], arity = 2; // all of these operators take 2 arguments", + " if (stack.length < arity) throw Error(\"stack error\");", + " stack.push(new InfixNode(token, stack.splice(stack.length - arity)));", + " }", + " else stack.push(new NumberNode(token));", + " console.log(`read ${token}, stack = [${stack.join(\", \")}]`);", + " }", + " if (stack.length !== 1) throw Error(\"stack error \" + stack);", + " return stack[0];", + "}", + "const tests = [", + " [\"3 4 2 * 1 5 - 2 3 ^ ^ / +\", \"3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3\"],", + " [\"1 2 + 3 4 + ^ 5 6 + ^\", \"( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )\"],", + " [\"1 2 3 + +\", \"1 + 2 + 3\"] // test associativity (1+(2+3)) == (1+2+3)", + "];", + "for (const [inp, oup] of tests) {", + " const realOup = rpnToTree(inp).toString();", + " console.log(realOup === oup ? \"Correct!\" : \"Incorrect!\");", + "}", + "", + "Output:", + "
input = 3 4 2 * 1 5 - 2 3 ^ ^ / +",
+      "read 3, stack = [3]",
+      "read 4, stack = [3, 4]",
+      "read 2, stack = [3, 4, 2]",
+      "read *, stack = [3, 4 * 2]",
+      "read 1, stack = [3, 4 * 2, 1]",
+      "read 5, stack = [3, 4 * 2, 1, 5]",
+      "read -, stack = [3, 4 * 2, 1 - 5]",
+      "read 2, stack = [3, 4 * 2, 1 - 5, 2]",
+      "read 3, stack = [3, 4 * 2, 1 - 5, 2, 3]",
+      "read ^, stack = [3, 4 * 2, 1 - 5, 2 ^ 3]",
+      "read ^, stack = [3, 4 * 2, ( 1 - 5 ) ^ 2 ^ 3]",
+      "read /, stack = [3, 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3]",
+      "read +, stack = [3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3]",
+      "Correct!",
+      "input = 1 2 + 3 4 + ^ 5 6 + ^",
+      "read 1, stack = [1]",
+      "read 2, stack = [1, 2]",
+      "read +, stack = [1 + 2]",
+      "read 3, stack = [1 + 2, 3]",
+      "read 4, stack = [1 + 2, 3, 4]",
+      "read +, stack = [1 + 2, 3 + 4]",
+      "read ^, stack = [( 1 + 2 ) ^ ( 3 + 4 )]",
+      "read 5, stack = [( 1 + 2 ) ^ ( 3 + 4 ), 5]",
+      "read 6, stack = [( 1 + 2 ) ^ ( 3 + 4 ), 5, 6]",
+      "read +, stack = [( 1 + 2 ) ^ ( 3 + 4 ), 5 + 6]",
+      "read ^, stack = [( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )]",
+      "Correct!",
+      "input = 1 2 3 + +",
+      "read 1, stack = [1]",
+      "read 2, stack = [1, 2]",
+      "read 3, stack = [1, 2, 3]",
+      "read +, stack = [1, 2 + 3]",
+      "read +, stack = [1 + 2 + 3]",
+      "Correct!
", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f5a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "const Associativity = {\n /** a / b / c = (a / b) / c */\n left: 0,\n /** a ^ b ^ c = a ^ (b ^ c) */\n right: 1,\n /** a + b + c = (a + b) + c = a + (b + c) */\n both: 2,\n};\nconst operators = {\n '+': { precedence: 2, associativity: Associativity.both },\n '-': { precedence: 2, associativity: Associativity.left },\n '*': { precedence: 3, associativity: Associativity.both },\n '/': { precedence: 3, associativity: Associativity.left },\n '^': { precedence: 4, associativity: Associativity.right },\n};\nclass NumberNode {\n constructor(text) { this.text = text; }\n toString() { return this.text; }\n}\nclass InfixNode {\n constructor(fnname, operands) {\n this.fnname = fnname;\n this.operands = operands;\n }\n toString(parentPrecedence = 0) {\n const op = operators[this.fnname];\n const leftAdd = op.associativity === Associativity.right ? 0.01 : 0;\n const rightAdd = op.associativity === Associativity.left ? 0.01 : 0;\n if (this.operands.length !== 2) throw Error(\"invalid operand count\");\n const result = this.operands[0].toString(op.precedence + leftAdd)\n +` ${this.fnname} ${this.operands[1].toString(op.precedence + rightAdd)}`;\n if (parentPrecedence > op.precedence) return `( ${result} )`;\n else return result;\n }\n}\nfunction rpnToTree(tokens) {\n const stack = [];\n console.log(`input = ${tokens}`);\n for (const token of tokens.split(\" \")) {\n if (token in operators) {\n const op = operators[token], arity = 2; // all of these operators take 2 arguments\n if (stack.length < arity) throw Error(\"stack error\");\n stack.push(new InfixNode(token, stack.splice(stack.length - arity)));\n }\n else stack.push(new NumberNode(token));\n console.log(`read ${token}, stack = [${stack.join(\", \")}]`);\n }\n if (stack.length !== 1) throw Error(\"stack error \" + stack);\n return stack[0];\n}\nconst tests = [\n [\"3 4 2 * 1 5 - 2 3 ^ ^ / +\", \"3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3\"],\n [\"1 2 + 3 4 + ^ 5 6 + ^\", \"( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )\"],\n [\"1 2 3 + +\", \"1 + 2 + 3\"] // test associativity (1+(2+3)) == (1+2+3)\n];\nfor (const [inp, oup] of tests) {\n const realOup = rpnToTree(inp).toString();\n console.log(realOup === oup ? \"Correct!\" : \"Incorrect!\");\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Parsing/Shunting-yard algorithm", + "type": "Waypoint", + "description": [ + "Task:", + "

Given the operator characteristics and input from the Shunting-yard algorithm page and tables, use the algorithm to show the changes in the operator stack and RPN output

", + "

as each individual token is processed.

Assume an input of a correct, space separated, string of tokens representing an infix expression", + "Generate a space separated output string representing the RPN", + "Test with the input string:::: 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3 ", + "print and display the output here.", + "Operator precedence is given in this table:{|

! operator !! precedence !! associativity !! operation

", + "

|- || align=\"center\"

", + "

| ^ || 4 || right || exponentiation

", + "

|- || align=\"center\"

", + "

| * || 3 || left || multiplication

", + "

|- || align=\"center\"

", + "

| / || 3 || left || division

", + "

|- || align=\"center\"

", + "

| + || 2 || left || addition

", + "

|- || align=\"center\"

", + "

| - || 2 || left || subtraction

", + "

|}

", + "Extra credit", + "

Add extra text explaining the actions and an optional comment for the action on receipt of each token.

", + "Note", + "

The handling of functions and arguments is not required.

", + "See also:", + "Parsing/RPN calculator algorithm for a method of calculating a final value from this output RPN expression.", + "Parsing/RPN to infix conversion." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function Stack() {", + " this.dataStore = [];", + " this.top = 0;", + " this.push = push;", + " this.pop = pop;", + " this.peek = peek;", + " this.length = length;", + "}", + " ", + "function push(element) {", + " this.dataStore[this.top++] = element;", + "}", + " ", + "function pop() {", + " return this.dataStore[--this.top];", + "}", + " ", + "function peek() {", + " return this.dataStore[this.top-1];", + "}", + " ", + "function length() {", + " return this.top;", + "}", + " ", + "var infix = \"3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3\";", + "infix = infix.replace(/\\s+/g, ''); // remove spaces, so infix[i]!=\" \"", + "", + "var s = new Stack();", + "var ops = \"-+/*^\";", + "var precedence = {\"^\":4, \"*\":3, \"/\":3, \"+\":2, \"-\":2};", + "var associativity = {\"^\":\"Right\", \"*\":\"Left\", \"/\":\"Left\", \"+\":\"Left\", \"-\":\"Left\"};", + "var token;", + "var postfix = \"\";", + "var o1, o2;", + "", + "for (var i = 0; i < infix.length; i++) {", + " token = infix[i];", + " if (token >= \"0\" && token <= \"9\") { // if token is operand (here limited to 0 <= x <= 9)", + " postfix += token + \" \";", + " }", + " else if (ops.indexOf(token) != -1) { // if token is an operator", + " o1 = token;", + " o2 = s.peek();", + " while (ops.indexOf(o2)!=-1 && ( // while operator token, o2, on top of the stack", + " // and o1 is left-associative and its precedence is less than or equal to that of o2", + " (associativity[o1] == \"Left\" && (precedence[o1] <= precedence[o2]) ) || ", + " // the algorithm on wikipedia says: or o1 precedence < o2 precedence, but I think it should be", + " // or o1 is right-associative and its precedence is less than that of o2", + " (associativity[o1] == \"Right\" && (precedence[o1] < precedence[o2])) ", + " )){", + " postfix += o2 + \" \"; // add o2 to output queue", + " s.pop(); // pop o2 of the stack", + " o2 = s.peek(); // next round", + " }", + " s.push(o1); // push o1 onto the stack", + " }", + " else if (token == \"(\") { // if token is left parenthesis", + " s.push(token); // then push it onto the stack", + " }", + " else if (token == \")\") { // if token is right parenthesis ", + " while (s.peek() != \"(\"){ // until token at top is (", + " postfix += s.pop() + \" \";", + " }", + " s.pop(); // pop (, but not onto the output queue", + " }", + "}", + "while (s.length()>0){", + " postfix += s.pop() + \" \";", + "}", + "print(postfix);", + "", + "Output:", + "", + "
infix:   3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3",
+      "postfix: 3 4 2 * 1 5 - 2 3 ^ ^ / + 
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f5b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function Stack() {\n this.dataStore = [];\n this.top = 0;\n this.push = push;\n this.pop = pop;\n this.peek = peek;\n this.length = length;\n}\n \nfunction push(element) {\n this.dataStore[this.top++] = element;\n}\n \nfunction pop() {\n return this.dataStore[--this.top];\n}\n \nfunction peek() {\n return this.dataStore[this.top-1];\n}\n \nfunction length() {\n return this.top;\n}\n \nvar infix = \"3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3\";\ninfix = infix.replace(/\\s+/g, ''); // remove spaces, so infix[i]!=\" \"\n\nvar s = new Stack();\nvar ops = \"-+/*^\";\nvar precedence = {\"^\":4, \"*\":3, \"/\":3, \"+\":2, \"-\":2};\nvar associativity = {\"^\":\"Right\", \"*\":\"Left\", \"/\":\"Left\", \"+\":\"Left\", \"-\":\"Left\"};\nvar token;\nvar postfix = \"\";\nvar o1, o2;\n\nfor (var i = 0; i < infix.length; i++) {\n token = infix[i];\n if (token >= \"0\" && token <= \"9\") { // if token is operand (here limited to 0 <= x <= 9)\n postfix += token + \" \";\n }\n else if (ops.indexOf(token) != -1) { // if token is an operator\n o1 = token;\n o2 = s.peek();\n while (ops.indexOf(o2)!=-1 && ( // while operator token, o2, on top of the stack\n // and o1 is left-associative and its precedence is less than or equal to that of o2\n (associativity[o1] == \"Left\" && (precedence[o1] <= precedence[o2]) ) || \n // the algorithm on wikipedia says: or o1 precedence < o2 precedence, but I think it should be\n // or o1 is right-associative and its precedence is less than that of o2\n (associativity[o1] == \"Right\" && (precedence[o1] < precedence[o2])) \n )){\n postfix += o2 + \" \"; // add o2 to output queue\n s.pop(); // pop o2 of the stack\n o2 = s.peek(); // next round\n }\n s.push(o1); // push o1 onto the stack\n }\n else if (token == \"(\") { // if token is left parenthesis\n s.push(token); // then push it onto the stack\n }\n else if (token == \")\") { // if token is right parenthesis \n while (s.peek() != \"(\"){ // until token at top is (\n postfix += s.pop() + \" \";\n }\n s.pop(); // pop (, but not onto the output queue\n }\n}\nwhile (s.length()>0){\n postfix += s.pop() + \" \";\n}\nprint(postfix);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Pascal matrix generation", + "type": "Waypoint", + "description": [ + "

A pascal matrix is a two-dimensional square matrix holding numbers from Pascal's triangle, also known as binomial coefficients and which can be shown as nCr.

Shown below are truncated 5-by-5 matrices M[i, j] for i,j in range 0..4.

A Pascal upper-triangular matrix that is populated with jCi:

", + "
",
+      "[[1, 1, 1, 1, 1],",
+      " [0, 1, 2, 3, 4],",
+      " [0, 0, 1, 3, 6],",
+      " [0, 0, 0, 1, 4],",
+      " [0, 0, 0, 0, 1]]",
+      "

A Pascal lower-triangular matrix that is populated with iCj (the transpose of the upper-triangular matrix):

", + "
",
+      "[[1, 0, 0, 0, 0],",
+      " [1, 1, 0, 0, 0],",
+      " [1, 2, 1, 0, 0],",
+      " [1, 3, 3, 1, 0],",
+      " [1, 4, 6, 4, 1]]",
+      "

A Pascal symmetric matrix that is populated with i+jCi:

", + "
",
+      "[[1, 1, 1, 1, 1],",
+      " [1, 2, 3, 4, 5],",
+      " [1, 3, 6, 10, 15],",
+      " [1, 4, 10, 20, 35],",
+      " [1, 5, 15, 35, 70]]",
+      "
", + "Task:", + "

Write functions capable of generating each of the three forms of n-by-n matrices.

Use those functions to display upper, lower, and symmetric Pascal 5-by-5 matrices on this page.

The output should distinguish between different matrices and the rows of each matrix (no showing a list of 25 numbers assuming the reader should split it into rows).

", + "Note: ", + "

The Cholesky decomposition of a Pascal symmetric matrix is the Pascal lower-triangle matrix of the same size.

", + " " + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "In terms of a binomial coefficient, and a function on a coordinate pair.", + "{{Trans|Haskell}}", + "===ES6===", + "(() => {", + " 'use strict';", + "", + " // PASCAL MATRIX ---------------------------------------------------------", + "", + " // (Function on a coordinate pair) -> Matrix size -> Matrix rows", + " // pascalMatrix :: ((Int, Int) -> (Int, Int)) -> Int -> [[Int]]", + " const pascalMatrix = (f, n) =>", + " chunksOf(n, map(compose(bc, f), range([", + " [0, 0],", + " [n - 1, n - 1]", + " ])));", + "", + " // Binomial coefficient", + " // bc :: (Int, Int) -> Int", + " const bc = ([n, k]) => enumFromTo(1, k)", + " .reduce((a, x) => Math.floor((a * (n - x + 1)) / x), 1);", + "", + "", + " // GENERIC FUNCTIONS -----------------------------------------------------", + "", + " // chunksOf :: Int -> [a] -> [[a]]", + " const chunksOf = (n, xs) =>", + " xs.reduce((a, _, i, xs) =>", + " i % n ? a : a.concat([xs.slice(i, i + n)]), []);", + "", + " // show ::", + " // (a -> String) f, Num n =>", + " // a -> maybe f -> maybe n -> String", + " const show = JSON.stringify;", + "", + " // swap :: (a, b) -> (b, a)", + " const swap = ([a, b]) => [b, a];", + "", + " // compose :: (b -> c) -> (a -> b) -> (a -> c)", + " const compose = (f, g) => x => f(g(x));", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " const curry = f => a => b => f(a, b);", + "", + " // cons :: a -> [a] -> [a]", + " const cons = (x, xs) => [x].concat(xs);", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // id :: a -> a", + " const id = x => x;", + "", + " // A list of functions applied to a list of arguments", + " // <*> :: [(a -> b)] -> [a] -> [b]", + " const ap = (fs, xs) => //", + " [].concat.apply([], fs.map(f => //", + " [].concat.apply([], xs.map(x => [f(x)]))));", + "", + " // Map each element of a structure to an action,", + " // evaluate these actions from left to right,", + " // and collect the results.", + " // traverse :: (a -> [b]) -> [a] -> [[b]]", + " const traverse = (f, xs) => {", + " const cons_f = (a, x) => ap(f(x)", + " .map(curry(cons)), a);", + " return xs.reduceRight(cons_f, [", + " []", + " ]);", + " };", + "", + " // Evaluate left to right, and collect the results", + " // sequence :: Monad m => [m a] -> m [a]", + " const sequence = xs => traverse(id, xs);", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " const enumFromTo = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // range :: Ix a => (a, a) -> [a]", + " const range = ([a, b]) => {", + " const [as, bs] = a instanceof Array ? [a, b] : [", + " [a],", + " [b]", + " ],", + " an = as.length;", + " return (an === bs.length) ? (", + " an > 1 ? (", + " sequence(as.map((_, i) => enumFromTo(as[i], bs[i])))", + " ) : enumFromTo(a, b)", + " ) : undefined;", + " };", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) => {", + " const ny = ys.length;", + " return (xs.length <= ny ? xs : xs.slice(0, ny))", + " .map((x, i) => f(x, ys[i]));", + " };", + "", + " // concat :: [[a]] -> [a] | [String] -> String", + " const concat = xs => {", + " if (xs.length > 0) {", + " const unit = typeof xs[0] === 'string' ? '' : [];", + " return unit.concat.apply(unit, xs);", + " } else return [];", + " };", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + "", + " // TEST ------------------------------------------------------------------", + " const matrixSize = 5;", + "", + " return unlines(", + " zipWith(", + " (s, xs) => unlines(concat([", + " [s], xs.map(show), ['']", + " ])), [\"Lower\", \"Upper\", \"Symmetric\"],", + " ap(", + " map(", + " f => curry(pascalMatrix)(f), [", + " id, // Lower", + " swap, // Upper", + " ([a, b]) => [a + b, a] // Symmetric", + " ]", + " ), [matrixSize]", + " )", + " )", + " );", + "})();", + "{{Out}}", + "
Lower",
+      "[1,0,0,0,0]",
+      "[1,1,0,0,0]",
+      "[1,2,1,0,0]",
+      "[1,3,3,1,0]",
+      "[1,4,6,4,1]",
+      "",
+      "Upper",
+      "[1,1,1,1,1]",
+      "[0,1,2,3,4]",
+      "[0,0,1,3,6]",
+      "[0,0,0,1,4]",
+      "[0,0,0,0,1]",
+      "",
+      "Symmetric",
+      "[1,1,1,1,1]",
+      "[1,2,3,4,5]",
+      "[1,3,6,10,15]",
+      "[1,4,10,20,35]",
+      "[1,5,15,35,70]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f5d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // PASCAL MATRIX ---------------------------------------------------------\n\n // (Function on a coordinate pair) -> Matrix size -> Matrix rows\n // pascalMatrix :: ((Int, Int) -> (Int, Int)) -> Int -> [[Int]]\n const pascalMatrix = (f, n) =>\n chunksOf(n, map(compose(bc, f), range([\n [0, 0],\n [n - 1, n - 1]\n ])));\n\n // Binomial coefficient\n // bc :: (Int, Int) -> Int\n const bc = ([n, k]) => enumFromTo(1, k)\n .reduce((a, x) => Math.floor((a * (n - x + 1)) / x), 1);\n\n\n // GENERIC FUNCTIONS -----------------------------------------------------\n\n // chunksOf :: Int -> [a] -> [[a]]\n const chunksOf = (n, xs) =>\n xs.reduce((a, _, i, xs) =>\n i % n ? a : a.concat([xs.slice(i, i + n)]), []);\n\n // show ::\n // (a -> String) f, Num n =>\n // a -> maybe f -> maybe n -> String\n const show = JSON.stringify;\n\n // swap :: (a, b) -> (b, a)\n const swap = ([a, b]) => [b, a];\n\n // compose :: (b -> c) -> (a -> b) -> (a -> c)\n const compose = (f, g) => x => f(g(x));\n\n // curry :: ((a, b) -> c) -> a -> b -> c\n const curry = f => a => b => f(a, b);\n\n // cons :: a -> [a] -> [a]\n const cons = (x, xs) => [x].concat(xs);\n\n // map :: (a -> b) -> [a] -> [b]\n const map = (f, xs) => xs.map(f);\n\n // id :: a -> a\n const id = x => x;\n\n // A list of functions applied to a list of arguments\n // <*> :: [(a -> b)] -> [a] -> [b]\n const ap = (fs, xs) => //\n [].concat.apply([], fs.map(f => //\n [].concat.apply([], xs.map(x => [f(x)]))));\n\n // Map each element of a structure to an action,\n // evaluate these actions from left to right,\n // and collect the results.\n // traverse :: (a -> [b]) -> [a] -> [[b]]\n const traverse = (f, xs) => {\n const cons_f = (a, x) => ap(f(x)\n .map(curry(cons)), a);\n return xs.reduceRight(cons_f, [\n []\n ]);\n };\n\n // Evaluate left to right, and collect the results\n // sequence :: Monad m => [m a] -> m [a]\n const sequence = xs => traverse(id, xs);\n\n // enumFromTo :: Int -> Int -> [Int]\n const enumFromTo = (m, n) =>\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i);\n\n // range :: Ix a => (a, a) -> [a]\n const range = ([a, b]) => {\n const [as, bs] = a instanceof Array ? [a, b] : [\n [a],\n [b]\n ],\n an = as.length;\n return (an === bs.length) ? (\n an > 1 ? (\n sequence(as.map((_, i) => enumFromTo(as[i], bs[i])))\n ) : enumFromTo(a, b)\n ) : undefined;\n };\n\n // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]\n const zipWith = (f, xs, ys) => {\n const ny = ys.length;\n return (xs.length <= ny ? xs : xs.slice(0, ny))\n .map((x, i) => f(x, ys[i]));\n };\n\n // concat :: [[a]] -> [a] | [String] -> String\n const concat = xs => {\n if (xs.length > 0) {\n const unit = typeof xs[0] === 'string' ? '' : [];\n return unit.concat.apply(unit, xs);\n } else return [];\n };\n\n // unlines :: [String] -> String\n const unlines = xs => xs.join('\\n');\n\n\n // TEST ------------------------------------------------------------------\n const matrixSize = 5;\n\n return unlines(\n zipWith(\n (s, xs) => unlines(concat([\n [s], xs.map(show), ['']\n ])), [\"Lower\", \"Upper\", \"Symmetric\"],\n ap(\n map(\n f => curry(pascalMatrix)(f), [\n id, // Lower\n swap, // Upper\n ([a, b]) => [a + b, a] // Symmetric\n ]\n ), [matrixSize]\n )\n )\n );\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Pascal's triangle/Puzzle", + "type": "Waypoint", + "description": [ + "

This puzzle involves a Pascals Triangle, also known as a Pyramid of Numbers.

", + "
",
+      "           [ 151]",
+      "          [  ][  ]",
+      "        [40][  ][  ]",
+      "      [  ][  ][  ][  ]",
+      "    [ X][11][ Y][ 4][ Z]",
+      "
", + "

Each brick of the pyramid is the sum of the two bricks situated below it.

", + "

Of the three missing numbers at the base of the pyramid,

", + "

the middle one is the sum of the other two (that is, Y = X + Z).

", + "Task:", + "

Write a program to find a solution to this puzzle.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f5e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Pascal's triangle", + "type": "Waypoint", + "description": [ + "

Pascal's triangle is an arithmetic and geometric figure first imagined by Blaise Pascal.

Its first few rows look like this:

", + "

1

", + "

1 1

", + "

1 2 1

", + "

1 3 3 1

", + "

where each element of each row is either 1 or the sum of the two elements right above it.

For example, the next row of the triangle would be:

", + "

:: 1 (since the first element of each row doesn't have two elements above it)

", + "

:: 4 (1 + 3)

", + "

:: 6 (3 + 3)

", + "

:: 4 (3 + 1)

", + "

:: 1 (since the last element of each row doesn't have two elements above it)

So the triangle now looks like this:

", + "

1

", + "

1 1

", + "

1 2 1

", + "

1 3 3 1

", + "

1 4 6 4 1

Each row n (starting with row 0 at the top) shows the coefficients of the binomial expansion of (x + y)n.

", + "Task:", + "

Write a function that prints out the first n rows of the triangle (with f(1) yielding the row consisting of only the element 1).

This can be done either by summing elements from the previous rows or using a binary coefficient or combination function.

Behavior for n ≤ 0 does not need to be uniform, but should be noted.

", + "See also:", + "Evaluate binomial coefficients" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Imperative====", + "{{works with|SpiderMonkey}}", + "{{works with|V8}}", + "// Pascal's triangle object", + "function pascalTriangle (rows) {", + "", + "\t// Number of rows the triangle contains", + "\tthis.rows = rows;", + "", + "\t// The 2D array holding the rows of the triangle", + "\tthis.triangle = new Array();", + "\tfor (var r = 0; r < rows; r++) {", + "\t\tthis.triangle[r] = new Array();", + "\t\tfor (var i = 0; i <= r; i++) {", + "\t\t\tif (i == 0 || i == r)", + "\t\t\t\tthis.triangle[r][i] = 1;", + "\t\t\telse", + "\t\t\t\tthis.triangle[r][i] = this.triangle[r-1][i-1]+this.triangle[r-1][i];", + "\t\t}", + "\t}", + "", + "\t// Method to print the triangle", + "\tthis.print = function(base) {", + "\t\tif (!base)", + "\t\t\tbase = 10;", + "", + "\t\t// Private method to calculate digits in number", + "\t\tvar digits = function(n,b) {", + "\t\t\tvar d = 0;", + "\t\t\twhile (n >= 1) {", + "\t\t\t\td++;", + "\t\t\t\tn /= b;", + "\t\t\t}", + "\t\t\treturn d;", + "\t\t}", + "", + "\t\t// Calculate max spaces needed", + "\t\tvar spacing = digits(this.triangle[this.rows-1][Math.round(this.rows/2)],base);", + "", + "\t\t// Private method to add spacing between numbers", + "\t\tvar insertSpaces = function(s) {", + "\t\t\tvar buf = \"\";", + "\t\t\twhile (s > 0) {", + "\t\t\t\ts--;", + "\t\t\t\tbuf += \" \";", + "\t\t\t}", + "\t\t\treturn buf;", + "\t\t}", + "", + "\t\t// Print the triangle line by line", + "\t\tfor (var r = 0; r < this.triangle.length; r++) {", + "\t\t\tvar l = \"\";", + "\t\t\tfor (var s = 0; s < Math.round(this.rows-1-r); s++) {", + "\t\t\t\tl += insertSpaces(spacing);", + "\t\t\t}", + "\t\t\tfor (var i = 0; i < this.triangle[r].length; i++) {", + "\t\t\t\tif (i != 0)", + "\t\t\t\t\tl += insertSpaces(spacing-Math.ceil(digits(this.triangle[r][i],base)/2));", + "\t\t\t\tl += this.triangle[r][i].toString(base);", + "\t\t\t\tif (i < this.triangle[r].length-1)", + "\t\t\t\t\tl += insertSpaces(spacing-Math.floor(digits(this.triangle[r][i],base)/2));", + "\t\t\t}", + "\t\t\tprint(l);", + "\t\t}", + "\t}", + "", + "}", + "", + "// Display 4 row triangle in base 10", + "var tri = new pascalTriangle(4);", + "tri.print();", + "// Display 8 row triangle in base 16", + "tri = new pascalTriangle(8);", + "tri.print(16);", + "Output:", + "
$ d8 pascal.js ",
+      "   1",
+      "  1 1",
+      " 1 2 1",
+      "1 3 3 1",
+      "              1",
+      "            1   1",
+      "          1   2   1",
+      "        1   3   3   1",
+      "      1   4   6   4   1",
+      "    1   5   a   a   5   1",
+      "  1   6   f   14  f   6   1",
+      "1   7   15  23  23  15  7   1
", + "", + "====Functional====", + "{{Trans|Haskell}} ", + "(function (n) {", + " 'use strict';", + "", + " // PASCAL TRIANGLE --------------------------------------------------------", + "", + " // pascal :: Int -> [[Int]]", + " function pascal(n) {", + " return foldl(function (a) {", + " var xs = a.slice(-1)[0]; // Previous row", + " return append(a, [zipWith(", + " function (a, b) {", + " return a + b;", + " },", + " append([0], xs),", + " append(xs, [0])", + " )]);", + " }, [", + " [1] // Initial seed row", + " ], enumFromTo(1, n - 1));", + " };", + "", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // (++) :: [a] -> [a] -> [a]", + " function append(xs, ys) {", + " return xs.concat(ys);", + " };", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " function enumFromTo(m, n) {", + " return Array.from({", + " length: Math.floor(n - m) + 1", + " }, function (_, i) {", + " return m + i;", + " });", + " };", + "", + " // foldl :: (b -> a -> b) -> b -> [a] -> b", + " function foldl(f, a, xs) {", + " return xs.reduce(f, a);", + " };", + "", + " // foldr (a -> b -> b) -> b -> [a] -> b", + " function foldr(f, a, xs) {", + " return xs.reduceRight(f, a);", + " };", + "", + " // map :: (a -> b) -> [a] -> [b]", + " function map(f, xs) {", + " return xs.map(f);", + " };", + "", + " // min :: Ord a => a -> a -> a", + " function min(a, b) {", + " return b < a ? b : a;", + " };", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " function zipWith(f, xs, ys) {", + " return Array.from({", + " length: min(xs.length, ys.length)", + " }, function (_, i) {", + " return f(xs[i], ys[i]);", + " });", + " };", + "", + " // TEST and FORMAT --------------------------------------------------------", + " var lstTriangle = pascal(n);", + "", + " // [[a]] -> bool -> s -> s", + " function wikiTable(lstRows, blnHeaderRow, strStyle) {", + " return '{| class=\"wikitable\" ' + (strStyle ? 'style=\"' + strStyle +", + " '\"' : '') + lstRows.map(function (lstRow, iRow) {", + " var strDelim = blnHeaderRow && !iRow ? '!' : '|';", + " return '\\n|-\\n' + strDelim + ' ' + lstRow.map(function (v) {", + " return typeof v === 'undefined' ? ' ' : v;", + " })", + " .join(' ' + strDelim + strDelim + ' ');", + " })", + " .join('') + '\\n|}';", + " }", + "", + " var lstLastLine = lstTriangle.slice(-1)[0],", + " lngBase = lstLastLine.length * 2 - 1,", + " nWidth = lstLastLine.reduce(function (a, x) {", + " var d = x.toString()", + " .length;", + " return d > a ? d : a;", + " }, 1) * lngBase;", + "", + " return [wikiTable(lstTriangle.map(function (lst) {", + " return lst.join(';;')", + " .split(';');", + " })", + " .map(function (line, i) {", + " var lstPad = Array((lngBase - line.length) / 2);", + " return lstPad.concat(line)", + " .concat(lstPad);", + " }), false, 'text-align:center;width:' + nWidth + 'em;height:' + nWidth +", + " 'em;table-layout:fixed;'), JSON.stringify(lstTriangle)].join('\\n\\n');", + "})(7);", + "{{Out}}", + "{| class=\"wikitable\" style=\"text-align:center;width:26em;height:26em;table-layout:fixed;\"", + "|-", + "| || || || || || || 1 || || || || || || ", + "|-", + "| || || || || || 1 || || 1 || || || || || ", + "|-", + "| || || || || 1 || || 2 || || 1 || || || || ", + "|-", + "| || || || 1 || || 3 || || 3 || || 1 || || || ", + "|-", + "| || || 1 || || 4 || || 6 || || 4 || || 1 || || ", + "|-", + "| || 1 || || 5 || || 10 || || 10 || || 5 || || 1 || ", + "|-", + "| 1 || || 6 || || 15 || || 20 || || 15 || || 6 || || 1", + "|}", + "", + "[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1],[1,5,10,10,5,1],[1,6,15,20,15,6,1]]", + "", + "===ES6===", + "(() => {", + " 'use strict';", + "", + " // PASCAL'S TRIANGLE ------------------------------------------------------", + "", + " // pascal :: Int -> [[Int]]", + " const pascal = n =>", + " foldl(a => {", + " const xs = a.slice(-1)[0]; // Previous row", + " return append(a, [", + " zipWith(", + " (a, b) => a + b,", + " append([0], xs),", + " append(xs, [0])", + " )", + " ]);", + " }, [", + " [1] // Initial seed row", + " ], enumFromTo(1, n - 1));", + "", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // (++) :: [a] -> [a] -> [a]", + " const append = (xs, ys) => xs.concat(ys);", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " const enumFromTo = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // foldl :: (b -> a -> b) -> b -> [a] -> b", + " const foldl = (f, a, xs) => xs.reduce(f, a);", + "", + " // foldr (a -> b -> b) -> b -> [a] -> b", + " const foldr = (f, a, xs) => xs.reduceRight(f, a);", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // min :: Ord a => a -> a -> a", + " const min = (a, b) => b < a ? b : a;", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) =>", + " Array.from({", + " length: min(xs.length, ys.length)", + " }, (_, i) => f(xs[i], ys[i]));", + "", + " // TEST -------------------------------------------------------------------", + " return foldr((a, x) => {", + " const strIndent = a.indent;", + " return {", + " rows: strIndent + map(n => (' ' + n)", + " .slice(-4), x)", + " .join('') + '\\n' + a.rows,", + " indent: strIndent + ' '", + " };", + " }, {", + " rows: '',", + " indent: ''", + " }, pascal(7))", + " .rows;", + "})();", + "{{Out}}", + "
               1",
+      "             1   1",
+      "           1   2   1",
+      "         1   3   3   1",
+      "       1   4   6   4   1",
+      "     1   5  10  10   5   1",
+      "   1   6  15  20  15   6   1",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f5f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// Pascal's triangle object\nfunction pascalTriangle (rows) {\n\n\t// Number of rows the triangle contains\n\tthis.rows = rows;\n\n\t// The 2D array holding the rows of the triangle\n\tthis.triangle = new Array();\n\tfor (var r = 0; r < rows; r++) {\n\t\tthis.triangle[r] = new Array();\n\t\tfor (var i = 0; i <= r; i++) {\n\t\t\tif (i == 0 || i == r)\n\t\t\t\tthis.triangle[r][i] = 1;\n\t\t\telse\n\t\t\t\tthis.triangle[r][i] = this.triangle[r-1][i-1]+this.triangle[r-1][i];\n\t\t}\n\t}\n\n\t// Method to print the triangle\n\tthis.print = function(base) {\n\t\tif (!base)\n\t\t\tbase = 10;\n\n\t\t// Private method to calculate digits in number\n\t\tvar digits = function(n,b) {\n\t\t\tvar d = 0;\n\t\t\twhile (n >= 1) {\n\t\t\t\td++;\n\t\t\t\tn /= b;\n\t\t\t}\n\t\t\treturn d;\n\t\t}\n\n\t\t// Calculate max spaces needed\n\t\tvar spacing = digits(this.triangle[this.rows-1][Math.round(this.rows/2)],base);\n\n\t\t// Private method to add spacing between numbers\n\t\tvar insertSpaces = function(s) {\n\t\t\tvar buf = \"\";\n\t\t\twhile (s > 0) {\n\t\t\t\ts--;\n\t\t\t\tbuf += \" \";\n\t\t\t}\n\t\t\treturn buf;\n\t\t}\n\n\t\t// Print the triangle line by line\n\t\tfor (var r = 0; r < this.triangle.length; r++) {\n\t\t\tvar l = \"\";\n\t\t\tfor (var s = 0; s < Math.round(this.rows-1-r); s++) {\n\t\t\t\tl += insertSpaces(spacing);\n\t\t\t}\n\t\t\tfor (var i = 0; i < this.triangle[r].length; i++) {\n\t\t\t\tif (i != 0)\n\t\t\t\t\tl += insertSpaces(spacing-Math.ceil(digits(this.triangle[r][i],base)/2));\n\t\t\t\tl += this.triangle[r][i].toString(base);\n\t\t\t\tif (i < this.triangle[r].length-1)\n\t\t\t\t\tl += insertSpaces(spacing-Math.floor(digits(this.triangle[r][i],base)/2));\n\t\t\t}\n\t\t\tprint(l);\n\t\t}\n\t}\n\n}\n\n// Display 4 row triangle in base 10\nvar tri = new pascalTriangle(4);\ntri.print();\n// Display 8 row triangle in base 16\ntri = new pascalTriangle(8);\ntri.print(16);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Pathological floating point problems", + "type": "Waypoint", + "description": [ + "

Most programmers are familiar with the inexactness of floating point calculations in a binary processor.

The classic example being:

", + "
",
+      "0.1 + 0.2 =  0.30000000000000004",
+      "

In many situations the amount of error in such calculations is very small and can be overlooked or eliminated with rounding.

There are pathological problems however, where seemingly simple, straight-forward calculations are extremely sensitive to even tiny amounts of imprecision.

This task's purpose is to show how your language deals with such classes of problems.

", + "

A sequence that seems to converge to a wrong limit.

Consider the sequence:

", + "

::::: v1 = 2

", + "

::::: v2 = -4

", + "

::::: vn = 111 - 1130 / vn-1 + 3000 / (vn-1 * vn-2)

", + "

As n grows larger, the series should converge to 6 but small amounts of error will cause it to approach 100.

", + "Task 1:", + "

Display the values of the sequence where n = 3, 4, 5, 6, 7, 8, 20, 30, 50 & 100 to at least 16 decimal places.

", + "
",
+      "    n = 3     18.5",
+      "    n = 4      9.378378",
+      "    n = 5      7.801153",
+      "    n = 6      7.154414",
+      "    n = 7      6.806785",
+      "    n = 8      6.5926328",
+      "    n = 20     6.0435521101892689",
+      "    n = 30     6.006786093031205758530554",
+      "    n = 50     6.0001758466271871889456140207471954695237",
+      "    n = 100    6.000000019319477929104086803403585715024350675436952458072592750856521767230266",
+      "
", + "Task 2:", + "

The Chaotic Bank Society is offering a new investment account to their customers.

You first deposit $e - 1 where e is 2.7182818... the base of natural logarithms.

After each year, your account balance will be multiplied by the number of years that have passed, and $1 in service charges will be removed.

So ...

", + "

:* after 1 year, your balance will be multiplied by 1 and $1 will be removed for service charges.

", + "

:* after 2 years your balance will be doubled and $1 removed.

", + "

:* after 3 years your balance will be tripled and $1 removed.

", + "

:* ...

", + "

:* after 10 years, multiplied by 10 and $1 removed, and so on.

", + "

What will your balance be after 25 years?

", + "

Starting balance: $e-1

", + "

Balance = (Balance * year) - 1 for 25 years

", + "

Balance after 25 years: $0.0399387296732302

", + "Task 3, extra credit:", + "

Siegfried Rump's example. Consider the following function, designed by Siegfried Rump in 1988.

", + "

::::: f(a,b) = 333.75b6 + a2( 11a2b2 - b6 - 121b4 - 2 ) + 5.5b8 + a/(2b)

", + "

::::: compute f(a,b) where a=77617.0 and b=33096.0

", + "

::::: f(77617.0, 33096.0) = -0.827396059946821

", + "

Demonstrate how to solve at least one of the first two problems, or both, and the third if you're feeling particularly jaunty.

", + "See also;", + " Floating-Point Arithmetic Section 1.3.2 Difficult problems." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f61", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Pattern matching", + "type": "Waypoint", + "description": [ + "

Some languages offer direct support for algebraic data types and pattern matching on them. While this of course can always be simulated with manual tagging and conditionals, it allows for terse code which is easy to read, and can represent the algorithm directly.

As an example, implement insertion in a red-black-tree. A red-black-tree is a binary tree where each internal node has a color attribute red or black. Moreover, no red node can have a red child, and every path from the root to an empty node must contain the same number of black nodes. As a consequence, the tree is balanced, and must be re-balanced after an insertion.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f62", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Penney's game", + "type": "Waypoint", + "description": [ + "

Penney's game is a game where two players bet on being the first to see a particular sequence of heads or tails in consecutive tosses of a fair coin.

It is common to agree on a sequence length of three then one player will openly choose a sequence, for example:

", + "

Heads, Tails, Heads, or HTH for short.

", + "

The other player on seeing the first players choice will choose his sequence. The coin is tossed and the first player to see his sequence in the sequence of coin tosses wins.

", + "Example:", + "

One player might choose the sequence HHT and the other THT.

Successive coin tosses of HTTHT gives the win to the second player as the last three coin tosses are his sequence.

", + "Task", + "

Create a program that tosses the coin, keeps score and plays Penney's game against a human opponent.

", + "Who chooses and shows their sequence of three should be chosen randomly.", + "If going first, the computer should randomly choose its sequence of three.", + "If going second, the computer should automatically play the optimum sequence.", + "Successive coin tosses should be shown.", + "

Show output of a game where the computer chooses first and a game where the user goes first here on this page.

", + "See also", + "The Penney Ante Part 1 (Video).", + "The Penney Ante Part 2 (Video)." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f63", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Pentagram", + "type": "Waypoint", + "description": [ + "

A pentagram is a star polygon, consisting of a central pentagon of which each side forms the base of an isosceles triangle. The vertex of each triangle, a point of the star, is 36 degrees.

", + "Task:", + "

Draw (or print) a regular pentagram, in any orientation. Use a different color (or token) for stroke and fill, and background. For the fill it should be assumed that all points inside the triangles and the pentagon are inside the pentagram.

", + "See also", + "Angle sum of a pentagram" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f64", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Percolation/Bond percolation", + "type": "Waypoint", + "description": [ + "

Given an $M \\times N$ rectangular array of cells numbered $\\mathrm{cell}[0..M-1, 0..N-1]$, assume $M$ is horizontal and $N$ is downwards. Each $\\mathrm{cell}[m, n]$ is bounded by (horizontal) walls $\\mathrm{hwall}[m, n]$ and $\\mathrm{hwall}[m+1, n]$; (vertical) walls $\\mathrm{vwall}[m, n]$ and $\\mathrm{vwall}[m, n+1]$

Assume that the probability of any wall being present is a constant $p$ where

", + "

$0.0 \\le p \\le 1.0$

", + "

Except for the outer horizontal walls at $m = 0$ and $m = M$ which are always present.

The task:", + "

Simulate pouring a fluid onto the top surface ($n = 0$) where the fluid will enter any empty cell it is adjacent to if there is no wall between where it currently is and the cell on the other side of the (missing) wall.

The fluid does not move beyond the horizontal constraints of the grid.

The fluid may move “up” within the confines of the grid of cells. If the fluid reaches a bottom cell that has a missing bottom wall then the fluid can be said to 'drip' out the bottom at that point.

Given $p$ repeat the percolation $t$ times to estimate the proportion of times that the fluid can percolate to the bottom for any given $p$.

Show how the probability of percolating through the random grid changes with $p$ going from $0.0$ to $1.0$ in $0.1$ increments and with the number of repetitions to estimate the fraction at any given $p$ as $t = 100$.

Use an $M=10, N=10$ grid of cells for all cases.

Optionally depict fluid successfully percolating through a grid graphically.

Show all output on this page.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f66", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Percolation/Mean cluster density", + "type": "Waypoint", + "description": [ + "

Let $c$ be a 2D boolean square matrix of $n \\times n$ values of either 1 or 0 where the

", + "

probability of any value being 1 is $p$, (and of 0 is therefore $1-p$).

", + "

We define a cluster of 1's as being a group of 1's connected vertically or

", + "

horizontally (i.e., using the Von Neumann neighborhood rule) and bounded by either $0$ or by the limits of the matrix.

", + "

Let the number of such clusters in such a randomly constructed matrix be $C_n$.

Percolation theory states that $K(p)$ (the mean cluster density) will satisfy $K(p) = C_n / n^2$ as $n$ tends to infinity. For $p = 0.5$, $K(p)$ is found numerically to approximate $0.065770$...

Task

Show the effect of varying $n$ on the accuracy of simulated $K(p)$ for $p = 0.5$ and

", + "

for values of $n$ up to at least $1000$.

", + "

Any calculation of $C_n$ for finite $n$ is subject to randomness, so an approximation should be

", + "

computed as the average of $t$ runs, where $t$ ≥ $5$.

For extra credit, graphically show clusters in a $15\\times 15$, $p=0.5$ grid.

Show your output here.

See also", + "s-Cluster on Wolfram mathworld." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f67", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Percolation/Mean run density", + "type": "Waypoint", + "description": [ + "

Let $v$ be a vector of $n$ values of either 1 or 0 where the probability of any

", + "

value being 1 is $p$; the probability of a value being 0 is therefore $1-p$.

", + "

Define a run of 1s as being a group of consecutive 1s in the vector bounded

", + "

either by the limits of the vector or by a 0. Let the number of such runs in a given

", + "

vector of length $n$ be $R_n$.

For example, the following vector has $R_{10} = 3$

", + "
",
+      "[1 1 0 0 0 1 0 1 1 1]",
+      " ^^^       ^   ^^^^^",
+      "
", + "

Percolation theory states that

$K(p) = \\lim_{n\\to\\infty} R_n / n = p(1 - p)$

Task

Any calculation of $R_n / n$ for finite $n$ is subject to randomness so should be

", + "

computed as the average of $t$ runs, where $t \\ge 100$.

For values of $p$ of 0.1, 0.3, 0.5, 0.7, and 0.9, show the effect of varying $n$

", + "

on the accuracy of simulated $K(p)$.

Show your output here.

See also", + "s-Run on Wolfram mathworld." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f68", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Percolation/Site percolation", + "type": "Waypoint", + "description": [ + "

Given an $M \\times N$ rectangular array of cells numbered $\\mathrm{cell}[0..M-1, 0..N-1]$assume $M$ is horizontal and $N$ is downwards.

Assume that the probability of any cell being filled is a constant $p$ where

", + "

$0.0 \\le p \\le 1.0$

The task:", + "

Simulate creating the array of cells with probability $p$ and then

", + "

testing if there is a route through adjacent filled cells from any on row $0$ to any on row $N$, i.e. testing for site percolation.

Given $p$ repeat the percolation $t$ times to estimate the proportion of times that the fluid can percolate to the bottom for any given $p$.

Show how the probability of percolating through the random grid changes with $p$ going from $0.0$ to $1.0$ in $0.1$ increments and with the number of repetitions to estimate the fraction at any given $p$ as $t >= 100$.

Use an $M=15, N=15$ grid of cells for all cases.

Optionally depict a percolation through a cell grid graphically.

Show all output on this page.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f69", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Perfect numbers", + "type": "Waypoint", + "description": [ + "

Write a function which says whether a number is perfect.

", + "

A perfect number is a positive integer that is the sum of its proper positive divisors excluding the number itself.

Equivalently, a perfect number is a number that is half the sum of all of its positive divisors (including itself).

", + "

Note: The faster Lucas-Lehmer test is used to find primes of the form 2n-1, all known perfect numbers can be derived from these primes

", + "

using the formula (2n - 1) × 2n - 1.

It is not known if there are any odd perfect numbers (any that exist are larger than 102000).

", + "See also:", + "Rational Arithmetic", + "Perfect numbers on OEIS", + "Odd Perfect showing the current status of bounds on odd perfect numbers." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Imperative===", + "", + "{{trans|Java}}", + "function is_perfect(n)", + "{", + " var sum = 1, i, sqrt=Math.floor(Math.sqrt(n));", + " for (i = sqrt-1; i>1; i--)", + " {", + " if (n % i == 0) {", + " sum += i + n/i;", + " }", + " }", + " if(n % sqrt == 0)", + " sum += sqrt + (sqrt*sqrt == n ? 0 : n/sqrt);", + " return sum === n;", + "}", + "", + "", + "var i;", + "for (i = 1; i < 10000; i++)", + "{", + " if (is_perfect(i))", + " print(i);", + "}", + "", + "{{Out}}", + "
6",
+      "28",
+      "496",
+      "8128
", + "", + "===Functional===", + "", + "====ES5====", + "", + "Naive version (brute force)", + "", + "(function (nFrom, nTo) {", + "", + " function perfect(n) {", + " return n === range(1, n - 1).reduce(", + " function (a, x) {", + " return n % x ? a : a + x;", + " }, 0", + " );", + " }", + "", + " function range(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(function (x, i) {", + " return m + i;", + " });", + " }", + "", + " return range(nFrom, nTo).filter(perfect);", + "", + "})(1, 10000);", + "", + "Output:", + "", + "[6, 28, 496, 8128]", + "", + "Much faster (more efficient factorisation)", + "", + "(function (nFrom, nTo) {", + "", + " function perfect(n) {", + " var lows = range(1, Math.floor(Math.sqrt(n))).filter(function (x) {", + " return (n % x) === 0;", + " });", + "", + " return n > 1 && lows.concat(lows.map(function (x) {", + " return n / x;", + " })).reduce(function (a, x) {", + " return a + x;", + " }, 0) / 2 === n;", + " }", + "", + " function range(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(function (x, i) {", + " return m + i;", + " });", + " }", + "", + " return range(nFrom, nTo).filter(perfect)", + "", + "})(1, 10000);", + "", + "Output:", + "", + "[6, 28, 496, 8128]", + "", + "Note that the filter function, though convenient and well optimised, is not strictly necessary.", + "We can always replace it with a more general monadic bind (chain) function, which is essentially just concat map", + "(Monadic return/inject for lists is simply lambda x --> [x], inlined here, and fail is [].)", + "", + "(function (nFrom, nTo) {", + "", + " // MONADIC CHAIN (bind) IN LIEU OF FILTER", + " // ( monadic return for lists is just lambda x -> [x] )", + "", + " return chain(", + " rng(nFrom, nTo),", + " ", + " function mPerfect(n) {", + " return (chain(", + " rng(1, Math.floor(Math.sqrt(n))),", + " function (y) {", + " return (n % y) === 0 && n > 1 ? [y, n / y] : [];", + " }", + " ).reduce(function (a, x) {", + " return a + x;", + " }, 0) / 2 === n) ? [n] : [];", + " }", + " ", + " );", + "", + " /******************************************************************/", + "", + " // Monadic bind (chain) for lists", + " function chain(xs, f) {", + " return [].concat.apply([], xs.map(f));", + " }", + "", + " function rng(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(function (x, i) {", + " return m + i;", + " });", + " }", + "", + "})(1, 10000);", + "", + "Output:", + "[6, 28, 496, 8128]", + "", + "", + "====ES6====", + "", + "((nFrom, nTo) => {", + "", + " // perfect :: Int -> Bool", + " let perfect = n => {", + " let lows = range(1, Math.floor(Math.sqrt(n)))", + " .filter(x => (n % x) === 0);", + "", + " return n > 1 && lows.concat(lows.map(x => n / x))", + " .reduce((a, x) => (a + x), 0) / 2 === n;", + " },", + "", + " // range :: Int -> Int -> Maybe Int -> [Int]", + " range = (m, n, step) => {", + " let d = (step || 1) * (n >= m ? 1 : -1);", + "", + " return Array.from({", + " length: Math.floor((n - m) / d) + 1", + " }, (_, i) => m + (i * d));", + " };", + "", + " return range(nFrom, nTo)", + " .filter(perfect);", + "", + "})(1, 10000);", + "", + "{{Out}}", + "[6, 28, 496, 8128]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f6a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function is_perfect(n)\n{\n var sum = 1, i, sqrt=Math.floor(Math.sqrt(n));\n for (i = sqrt-1; i>1; i--)\n {\n if (n % i == 0) {\n sum += i + n/i;\n }\n }\n if(n % sqrt == 0)\n sum += sqrt + (sqrt*sqrt == n ? 0 : n/sqrt);\n return sum === n;\n}\n\n\nvar i;\nfor (i = 1; i < 10000; i++)\n{\n if (is_perfect(i))\n print(i);\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Perfect shuffle", + "type": "Waypoint", + "description": [ + "

A perfect shuffle (or faro/weave shuffle) means splitting a deck of cards into equal halves, and perfectly interleaving them - so that you end up with the first card from the left half, followed by the first card from the right half, and so on:

", + "7♠ 8♠ 9♠ J♠ Q♠ K♠7♠ 8♠ 9♠J♠ Q♠ K♠7♠ J♠ 8♠ Q♠ 9♠ K♠", + "

When you repeatedly perform perfect shuffles on an even-sized deck of unique cards, it will at some point arrive back at its original order. How many shuffles this takes, depends solely on the number of cards in the deck - for example for a deck of eight cards it takes three shuffles:

", + "

{| style=\"border-spacing:0.5em 0;border-collapse:separate;margin:0 1em;text-align:right\"

", + "

|-

", + "

| original: ||

", + "

1

", + "

2

", + "

3

", + "

4

", + "

5

", + "

6

", + "

7

", + "

8

", + "

|-

", + "

| after 1st shuffle: ||

", + "

1

", + "

5

", + "

2

", + "

6

", + "

3

", + "

7

", + "

4

", + "

8

", + "

|-

", + "

| after 2nd shuffle: ||

", + "

1

", + "

3

", + "

5

", + "

7

", + "

2

", + "

4

", + "

6

", + "

8

", + "

|-

", + "

| after 3rd shuffle: ||

", + "

1

", + "

2

", + "

3

", + "

4

", + "

5

", + "

6

", + "

7

", + "

8

", + "

|}

", + "

The Task

Write a function that can perform a perfect shuffle on an even-sized list of values.", + "Call this function repeatedly to count how many shuffles are needed to get a deck back to its original order, for each of the deck sizes listed under \"Test Cases\" below.", + "* You can use a list of numbers (or anything else that's convenient) to represent a deck; just make sure that all \"cards\" are unique within each deck.", + "* Print out the resulting shuffle counts, to demonstrate that your program passes the test-cases.", + "

Test Cases

{|

", + "

|-

", + "

! input (deck size) !! output (number of shuffles required)

", + "

|-

", + "

| 8 || 3

", + "

|-

", + "

| 24 || 11

", + "

|-

", + "

| 52 || 8

", + "

|-

", + "

| 100 || 30

", + "

|-

", + "

| 1020 || 1018

", + "

|-

", + "

| 1024 || 10

", + "

|-

", + "

| 10000 || 300

", + "

|}

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "(() => {", + " 'use strict';", + "", + " // shuffleCycleLength :: Int -> Int", + " const shuffleCycleLength = deckSize =>", + " firstCycle(shuffle, range(1, deckSize))", + " .all.length;", + "", + " // shuffle :: [a] -> [a]", + " const shuffle = xs =>", + " concat(zip.apply(null, splitAt(div(length(xs), 2), xs)));", + "", + " // firstycle :: Eq a => (a -> a) -> a -> [a]", + " const firstCycle = (f, x) =>", + " until(", + " m => EqArray(x, m.current),", + " m => {", + " const fx = f(m.current);", + " return {", + " current: fx,", + " all: m.all.concat([fx])", + " };", + " }, {", + " current: f(x),", + " all: [x]", + " }", + " );", + "", + " // Two arrays equal ?", + " // EqArray :: [a] -> [b] -> Bool", + " const EqArray = (xs, ys) => {", + " const [nx, ny] = [xs.length, ys.length];", + " return nx === ny ? (", + " nx > 0 ? (", + " xs[0] === ys[0] && EqArray(xs.slice(1), ys.slice(1))", + " ) : true", + " ) : false;", + " };", + "", + " // GENERIC FUNCTIONS", + "", + " // zip :: [a] -> [b] -> [(a,b)]", + " const zip = (xs, ys) =>", + " xs.slice(0, Math.min(xs.length, ys.length))", + " .map((x, i) => [x, ys[i]]);", + "", + " // concat :: [[a]] -> [a]", + " const concat = xs => [].concat.apply([], xs);", + "", + " // splitAt :: Int -> [a] -> ([a],[a])", + " const splitAt = (n, xs) => [xs.slice(0, n), xs.slice(n)];", + "", + " // div :: Num -> Num -> Int", + " const div = (x, y) => Math.floor(x / y);", + "", + " // until :: (a -> Bool) -> (a -> a) -> a -> a", + " const until = (p, f, x) => {", + " const go = x => p(x) ? x : go(f(x));", + " return go(x);", + " }", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // length :: [a] -> Int", + " // length :: Text -> Int", + " const length = xs => xs.length;", + "", + " // maximumBy :: (a -> a -> Ordering) -> [a] -> a", + " const maximumBy = (f, xs) =>", + " xs.reduce((a, x) => a === undefined ? x : (", + " f(x, a) > 0 ? x : a", + " ), undefined);", + "", + " // transpose :: [[a]] -> [[a]]", + " const transpose = xs =>", + " xs[0].map((_, iCol) => xs.map((row) => row[iCol]));", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x, null, 2);", + "", + " // replicateS :: Int -> String -> String", + " const replicateS = (n, s) => {", + " let v = s,", + " o = '';", + " if (n < 1) return o;", + " while (n > 1) {", + " if (n & 1) o = o.concat(v);", + " n >>= 1;", + " v = v.concat(v);", + " }", + " return o.concat(v);", + " };", + "", + " // justifyRight :: Int -> Char -> Text -> Text", + " const justifyRight = (n, cFiller, strText) =>", + " n > strText.length ? (", + " (replicateS(n, cFiller) + strText)", + " .slice(-n)", + " ) : strText;", + "", + " // TEST", + " return transpose(transpose([", + " ['Deck', 'Shuffles']", + " ].concat(", + " [8, 24, 52, 100, 1020, 1024, 10000]", + " .map(n => [n.toString(), shuffleCycleLength(n)", + " .toString()", + " ])))", + " .map(col => { // Right-justified number columns", + " const width = length(", + " maximumBy((a, b) => length(a) - length(b), col)", + " ) + 2;", + "", + " return col.map(x => justifyRight(width, ' ', x));", + " }))", + " .map(row => row.join(''))", + " .join('\\n');", + "})();", + "", + "{{Out}}", + "
   Deck  Shuffles",
+      "      8         3",
+      "     24        11",
+      "     52         8",
+      "    100        30",
+      "   1020      1018",
+      "   1024        10",
+      "  10000       300
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f6b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // shuffleCycleLength :: Int -> Int\n const shuffleCycleLength = deckSize =>\n firstCycle(shuffle, range(1, deckSize))\n .all.length;\n\n // shuffle :: [a] -> [a]\n const shuffle = xs =>\n concat(zip.apply(null, splitAt(div(length(xs), 2), xs)));\n\n // firstycle :: Eq a => (a -> a) -> a -> [a]\n const firstCycle = (f, x) =>\n until(\n m => EqArray(x, m.current),\n m => {\n const fx = f(m.current);\n return {\n current: fx,\n all: m.all.concat([fx])\n };\n }, {\n current: f(x),\n all: [x]\n }\n );\n\n // Two arrays equal ?\n // EqArray :: [a] -> [b] -> Bool\n const EqArray = (xs, ys) => {\n const [nx, ny] = [xs.length, ys.length];\n return nx === ny ? (\n nx > 0 ? (\n xs[0] === ys[0] && EqArray(xs.slice(1), ys.slice(1))\n ) : true\n ) : false;\n };\n\n // GENERIC FUNCTIONS\n\n // zip :: [a] -> [b] -> [(a,b)]\n const zip = (xs, ys) =>\n xs.slice(0, Math.min(xs.length, ys.length))\n .map((x, i) => [x, ys[i]]);\n\n // concat :: [[a]] -> [a]\n const concat = xs => [].concat.apply([], xs);\n\n // splitAt :: Int -> [a] -> ([a],[a])\n const splitAt = (n, xs) => [xs.slice(0, n), xs.slice(n)];\n\n // div :: Num -> Num -> Int\n const div = (x, y) => Math.floor(x / y);\n\n // until :: (a -> Bool) -> (a -> a) -> a -> a\n const until = (p, f, x) => {\n const go = x => p(x) ? x : go(f(x));\n return go(x);\n }\n\n // range :: Int -> Int -> [Int]\n const range = (m, n) =>\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i);\n\n // length :: [a] -> Int\n // length :: Text -> Int\n const length = xs => xs.length;\n\n // maximumBy :: (a -> a -> Ordering) -> [a] -> a\n const maximumBy = (f, xs) =>\n xs.reduce((a, x) => a === undefined ? x : (\n f(x, a) > 0 ? x : a\n ), undefined);\n\n // transpose :: [[a]] -> [[a]]\n const transpose = xs =>\n xs[0].map((_, iCol) => xs.map((row) => row[iCol]));\n\n // show :: a -> String\n const show = x => JSON.stringify(x, null, 2);\n\n // replicateS :: Int -> String -> String\n const replicateS = (n, s) => {\n let v = s,\n o = '';\n if (n < 1) return o;\n while (n > 1) {\n if (n & 1) o = o.concat(v);\n n >>= 1;\n v = v.concat(v);\n }\n return o.concat(v);\n };\n\n // justifyRight :: Int -> Char -> Text -> Text\n const justifyRight = (n, cFiller, strText) =>\n n > strText.length ? (\n (replicateS(n, cFiller) + strText)\n .slice(-n)\n ) : strText;\n\n // TEST\n return transpose(transpose([\n ['Deck', 'Shuffles']\n ].concat(\n [8, 24, 52, 100, 1020, 1024, 10000]\n .map(n => [n.toString(), shuffleCycleLength(n)\n .toString()\n ])))\n .map(col => { // Right-justified number columns\n const width = length(\n maximumBy((a, b) => length(a) - length(b), col)\n ) + 2;\n\n return col.map(x => justifyRight(width, ' ', x));\n }))\n .map(row => row.join(''))\n .join('\\n');\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Permutations by swapping", + "type": "Waypoint", + "description": [ + "Task:", + "

Generate permutations of n items in which successive permutations differ from each other by the swapping of any two items.

Also generate the sign of the permutation which is +1 when the permutation is generated from an even number of swaps from the initial state, and -1 for odd.

Show the permutations and signs of three items, in order of generation here.

Such data are of use in generating the determinant of a square matrix and any functions created should bear this in mind.

Note: The Steinhaus–Johnson–Trotter algorithm generates successive permutations where adjacent items are swapped, but from this discussion adjacency is not a requirement.

", + "References:", + "Steinhaus–Johnson–Trotter algorithm", + "Johnson-Trotter Algorithm Listing All Permutations", + "Correction to Heap's algorithm as presented in Wikipedia and widely distributed.", + "[http://www.gutenberg.org/files/18567/18567-h/18567-h.htm#ch7] TintinnalogiaRelated task:", + " Matrix arithmetic", + " Gray code" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f6c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Permutations/Derangements", + "type": "Waypoint", + "description": [ + "

A derangement is a permutation of the order of distinct items in which no item appears in its original place.

For example, the only two derangements of the three items (0, 1, 2) are (1, 2, 0), and (2, 0, 1).

The number of derangements of n distinct items is known as the subfactorial of n, sometimes written as !n.

", + "

There are various ways to calculate !n.

", + "Task:", + "Create a named function/method/subroutine/... to generate derangements of the integers 0..n-1, (or 1..n if you prefer). ", + "Generate and show all the derangements of 4 integers using the above routine.", + "Create a function that calculates the subfactorial of n, !n.", + "Print and show a table of the counted number of derangements of n vs. the calculated !n for n from 0..9 inclusive.Optional stretch goal:", + " Calculate !20 Related tasks:", + " Anagrams/Deranged anagrams", + " Best shuffle", + " Left_factorials" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f6d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Permutations/Rank of a permutation", + "type": "Waypoint", + "description": [ + "

A particular ranking of a permutation associates an integer with a particular ordering of all the permutations of a set of distinct items.

", + "

For our purposes the ranking will assign integers $0 .. (n! - 1)$ to an ordering of all the permutations of the integers $0 .. (n - 1)$.

For example, the permutations of the digits zero to 3 arranged lexicographically have the following rank:

  PERMUTATION      RANK",
+      "  (0, 1, 2, 3) ->  0",
+      "  (0, 1, 3, 2) ->  1",
+      "  (0, 2, 1, 3) ->  2",
+      "  (0, 2, 3, 1) ->  3",
+      "  (0, 3, 1, 2) ->  4",
+      "  (0, 3, 2, 1) ->  5",
+      "  (1, 0, 2, 3) ->  6",
+      "  (1, 0, 3, 2) ->  7",
+      "  (1, 2, 0, 3) ->  8",
+      "  (1, 2, 3, 0) ->  9",
+      "  (1, 3, 0, 2) -> 10",
+      "  (1, 3, 2, 0) -> 11",
+      "  (2, 0, 1, 3) -> 12",
+      "  (2, 0, 3, 1) -> 13",
+      "  (2, 1, 0, 3) -> 14",
+      "  (2, 1, 3, 0) -> 15",
+      "  (2, 3, 0, 1) -> 16",
+      "  (2, 3, 1, 0) -> 17",
+      "  (3, 0, 1, 2) -> 18",
+      "  (3, 0, 2, 1) -> 19",
+      "  (3, 1, 0, 2) -> 20",
+      "  (3, 1, 2, 0) -> 21",
+      "  (3, 2, 0, 1) -> 22",
+      "  (3, 2, 1, 0) -> 23

Algorithms exist that can generate a rank from a permutation for some particular ordering of permutations, and that can generate the same rank from the given individual permutation (i.e. given a rank of 17 produce (2, 3, 1, 0) in the example above).

One use of such algorithms could be in generating a small, random, sample of permutations of $n$ items without duplicates when the total number of permutations is large. Remember that the total number of permutations of $n$ items is given by $n!$ which grows large very quickly: A 32 bit integer can only hold $12!$, a 64 bit integer only $20!$. It becomes difficult to take the straight-forward approach of generating all permutations then taking a random sample of them.

A question on the Stack Overflow site asked how to generate one million random and indivudual permutations of 144 items.

", + "Task:", + "Create a function to generate a permutation from a rank.", + "Create the inverse function that given the permutation generates its rank.", + "Show that for $n=3$ the two functions are indeed inverses of each other.", + "Compute and show here 4 random, individual, samples of permutations of 12 objects.Stretch goal:", + "State how reasonable it would be to use your program to address the limits of the Stack Overflow question.References:", + "Ranking and Unranking Permutations in Linear Time by Myrvold & Ruskey. (Also available via Google here).", + "Ranks on the DevData site.", + "Another answer on Stack Overflow to a different question that explains its algorithm in detail." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f6e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Permutations", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a program that generates all permutations of n different objects. (Practically numerals!)

", + "Related tasks: ", + " Find the missing permutation", + " Permutations/Derangements" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Iteration====", + "", + "Copy the following as an HTML file and load in a browser.", + "Permutations", + "
",
+      "
", + "", + "Alternatively: 'Genuine' js code, assuming no duplicate.", + "", + "", + "function perm(a) {", + " if (a.length < 2) return [a];", + " var c, d, b = [];", + " for (c = 0; c < a.length; c++) {", + " var e = a.splice(c, 1),", + " f = perm(a);", + " for (d = 0; d < f.length; d++) b.push([e].concat(f[d]));", + " a.splice(c, 0, e[0])", + " } return b", + "}", + "", + "console.log(perm(['Aardvarks', 'eat', 'ants']).join(\"\\n\"));", + "", + "", + "{{Out}}", + "Aardvarks,eat,ants", + "Aardvarks,ants,eat", + "eat,Aardvarks,ants", + "eat,ants,Aardvarks", + "ants,Aardvarks,eat", + "ants,eat,Aardvarks", + "", + "====Functional composition====", + "", + "{{trans|Haskell}}", + "", + "(Simple version – assuming a unique list of objects comparable by the JS === operator)", + "", + "(function () {", + " 'use strict';", + "", + " // permutations :: [a] -> [[a]]", + " var permutations = function (xs) {", + " return xs.length ? concatMap(function (x) {", + " return concatMap(function (ys) {", + " return [[x].concat(ys)];", + " }, permutations(delete_(x, xs)));", + " }, xs) : [[]];", + " };", + "", + " // GENERIC FUNCTIONS", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " var concatMap = function (f, xs) {", + " return [].concat.apply([], xs.map(f));", + " };", + "", + " // delete :: Eq a => a -> [a] -> [a]", + " var delete_ = function (x, xs) {", + " return deleteBy(function (a, b) {", + " return a === b;", + " }, x, xs);", + " };", + "", + " // deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]", + " var deleteBy = function (f, x, xs) {", + " return xs.length > 0 ? f(x, xs[0]) ? xs.slice(1) : ", + " [xs[0]].concat(deleteBy(f, x, xs.slice(1))) : [];", + " };", + "", + " // TEST", + " return permutations(['Aardvarks', 'eat', 'ants']);", + "})(); ", + "", + "{{Out}}", + "[[\"Aardvarks\", \"eat\", \"ants\"], [\"Aardvarks\", \"ants\", \"eat\"],", + " [\"eat\", \"Aardvarks\", \"ants\"], [\"eat\", \"ants\", \"Aardvarks\"], ", + "[\"ants\", \"Aardvarks\", \"eat\"], [\"ants\", \"eat\", \"Aardvarks\"]]", + "", + "===ES6===", + "", + "(() => {", + " 'use strict';", + "", + " // permutations :: [a] -> [[a]]", + " const permutations = xs =>", + " xs.length ? concatMap(x => concatMap(ys => [", + " [x].concat(ys)", + " ],", + " permutations(delete_(x, xs))), xs) : [", + " []", + " ];", + "", + " // GENERIC FUNCTIONS", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + " //", + " // // delete :: Eq a => a -> [a] -> [a]", + " // const delete_ = (x, xs) =>", + " // deleteBy((a, b) => a === b, x, xs);", + "", + " // delete_ :: Eq a => a -> [a] -> [a]", + " const delete_ = (x, xs) =>", + " xs.length > 0 ? (", + " (x === xs[0]) ? (", + " xs.slice(1)", + " ) : [xs[0]].concat(delete_(x, xs.slice(1)))", + " ) : [];", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // TEST", + " return permutations(['Aardvarks', 'eat', 'ants']);", + "})();", + "", + "", + "{{Out}}", + "[[\"Aardvarks\", \"eat\", \"ants\"], [\"Aardvarks\", \"ants\", \"eat\"],", + " [\"eat\", \"Aardvarks\", \"ants\"], [\"eat\", \"ants\", \"Aardvarks\"], ", + "[\"ants\", \"Aardvarks\", \"eat\"], [\"ants\", \"eat\", \"Aardvarks\"]]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f6f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "Permutations\n
\n\n"
+    ],
+    "betaTests": [
+      "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');"
+    ]
+  },
+  {
+    "title": "Permutation test",
+    "type": "Waypoint",
+    "description": [
+      "

A new medical treatment was tested on a population of $n + m$

", + "

volunteers, with each volunteer randomly assigned either to a group of

", + "

$n$ treatment subjects, or to a group of $m$ control subjects.

Members of the treatment group were given the treatment,

", + "

and members of the control group were given a placebo.

", + "

The effect of the treatment or placebo on each volunteer

", + "

was measured and reported in this table.

{| style=\"text-align: left; width: 50%;\" border=\"4\" cellpadding=\"2\" cellspacing=\"2\"

", + "

|+ Table of experimental results

", + "

|- style=\"background-color: rgb(255, 204, 255);\"

", + "

! Treatment group !! Control group

", + "

|-

", + "

| 85 || 68

", + "

|-

", + "

| 88 || 41

", + "

|-

", + "

| 75 || 10

", + "

|-

", + "

| 66 || 49

", + "

|-

", + "

| 25 || 16

", + "

|-

", + "

| 29 || 65

", + "

|-

", + "

| 83 || 32

", + "

|-

", + "

| 39 || 92

", + "

|-

", + "

| 97 || 28

", + "

|-

", + "

| || 98

", + "

|}

", + "

Write a program that performs a

", + "

permutation test to judge

", + "

whether the treatment had a significantly stronger effect than the

", + "

placebo.

Do this by considering every possible alternative assignment from the same pool of volunteers to a treatment group of size $n$ and a control group of size $m$ (i.e., the same group sizes used in the actual experiment but with the group members chosen differently), while assuming that each volunteer's effect remains constant regardless.", + "Note that the number of alternatives will be the binomial coefficient $\\tbinom{n+m}{n}$.", + "Compute the mean effect for each group and the difference in means between the groups in every case by subtracting the mean of the control group from the mean of the treatment group.", + "Report the percentage of alternative groupings for which the difference in means is less or equal to the actual experimentally observed difference in means, and the percentage for which it is greater.", + "Note that they should sum to 100%.", + "

Extremely dissimilar values are evidence of an effect not entirely due

", + "

to chance, but your program need not draw any conclusions.

You may assume the experimental data are known at compile time if

", + "

that's easier than loading them at run time. Test your solution on the

", + "

data given above.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f70", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Pernicious numbers", + "type": "Waypoint", + "description": [ + "

A pernicious number is a positive integer whose population count is a prime. The population count is the number of ones in the binary representation of a non-negative integer.

", + "Example", + "

22 (which is 10110 in binary) has a population count of 3, which is prime, and therefore 22 is a pernicious number.

", + "Task", + "display the first 25 pernicious numbers.", + "display all pernicious numbers between 888,888,877 and 888,888,888 (inclusive).", + "display each list of integers on one line (which may or may not include a title).See also", + "Sequence A052294 pernicious numbers on The On-Line Encyclopedia of Integer Sequences.", + "Rosetta Code entry population count, evil numbers, odious numbers." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f71", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Phrase reversals", + "type": "Waypoint", + "description": [ + "Task:", + "

Given a string of space separated words containing the following phrase:

", + "

rosetta code phrase reversal

# Reverse the string.

", + "

# Reverse each individual word in the string, maintaining original string order.

", + "

# Reverse the order of each word of the phrase, maintaining the order of characters in each word.

", + "

Show your output here.

", + "See also: ", + "Reverse a string", + "Reverse words in a string" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "(function (p) {", + " return [", + " p.split('').reverse().join(''),", + "", + " p.split(' ').map(function (x) {", + " return x.split('').reverse().join('');", + " }).join(' '),", + "", + " p.split(' ').reverse().join(' ')", + "", + " ].join('\\n');", + "", + "})('rosetta code phrase reversal');", + "{{out}}", + "
lasrever esarhp edoc attesor",
+      "attesor edoc esarhp lasrever",
+      "reversal phrase code rosetta
", + "", + "===ES6===", + "(() => {", + " 'use strict'", + "", + " // reverseString, reverseEachWord, reverseWordOrder :: String -> String", + " const", + " reverseString = s => reverse(s),", + "", + " reverseEachWord = s => wordLevel(map(reverse))(s),", + "", + " reverseWordOrder = s => wordLevel(reverse)(s);", + "", + " // wordLevel :: ([String] -> [String]) -> String -> String", + " const wordLevel = f =>", + " x => unwords(f(words(x)));", + "", + "", + " // GENERIC FUNCTIONS -----------------------------------------------------", + "", + " // A list of functions applied to a list of arguments", + " // <*> :: [(a -> b)] -> [a] -> [b]", + " const ap = (fs, xs) => //", + " [].concat.apply([], fs.map(f => //", + " [].concat.apply([], xs.map(x => [f(x)]))));", + "", + " // 2 or more arguments", + " // curry :: Function -> Function", + " const curry = (f, ...args) => {", + " const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :", + " function () {", + " return go(xs.concat(Array.from(arguments)));", + " };", + " return go([].slice.call(args, 1));", + " };", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = curry((f, xs) => xs.map(f));", + "", + " // reverse :: [a] -> [a]", + " const reverse = curry(xs =>", + " typeof xs === 'string' ? (", + " xs.split('')", + " .reverse()", + " .join('')", + " ) : xs.slice(0)", + " .reverse());", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // unwords :: [String] -> String", + " const unwords = xs => xs.join(' ');", + "", + " // words :: String -> [String]", + " const words = s => s.split(/\\s+/);", + "", + "", + " // TEST ------------------------------------------------------------------", + " return unlines(", + " ap([", + " reverseString,", + " reverseEachWord,", + " reverseWordOrder", + " ], [\"rosetta code phrase reversal\"])", + " );", + "})();", + "{{Out}}", + "
lasrever esarhp edoc attesor",
+      "attesor edoc esarhp lasrever",
+      "reversal phrase code rosetta
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f72", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function (p) {\n return [\n p.split('').reverse().join(''),\n\n p.split(' ').map(function (x) {\n return x.split('').reverse().join('');\n }).join(' '),\n\n p.split(' ').reverse().join(' ')\n\n ].join('\\n');\n\n})('rosetta code phrase reversal');\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Polynomial long division", + "type": "Waypoint", + "description": [ + "

In algebra, polynomial long division is an algorithm for dividing a polynomial by another polynomial of the same or lower degree.

Let us suppose a polynomial is represented by a vector, $x$ (i.e., an ordered collection of coefficients) so that the $i$th element keeps the coefficient of $x^i$, and the multiplication by a monomial is a shift of the vector's elements \"towards right\" (injecting ones from left) followed by a multiplication of each element by the coefficient of the monomial.

Then a pseudocode for the polynomial long division using the conventions described above could be:

degree(P):

", + "

return the index of the last non-zero element of P;

", + "

if all elements are 0, return -∞

polynomial_long_division(N, D) returns (q, r):

", + "

// N, D, q, r are vectors

", + "

if degree(D) < 0 then error

", + "

q ← 0

", + "

while degree(N) ≥ degree(D)

", + "

d ← D shifted right by (degree(N) - degree(D))

", + "

q(degree(N) - degree(D)) ← N(degree(N)) / d(degree(d))

", + "

// by construction, degree(d) = degree(N) of course

", + "

d ← d * q(degree(N) - degree(D))

", + "

N ← N - d

", + "

endwhile

", + "

r ← N

", + "

return (q, r)

Note: vector * scalar multiplies each element of the vector by the scalar; vectorA - vectorB subtracts each element of the vectorB from the element of the vectorA with \"the same index\". The vectors in the pseudocode are zero-based.

Error handling (for allocations or for wrong inputs) is not mandatory.", + "Conventions can be different; in particular, note that if the first coefficient in the vector is the highest power of x for the polynomial represented by the vector, then the algorithm becomes simpler.", + "

Example for clarification

", + "

This example is from Wikipedia, but changed to show how the given pseudocode works.

0 1 2 3

", + "

----------------------

", + "

N: -42 0 -12 1 degree = 3

", + "

D: -3 1 0 0 degree = 1

d(N) - d(D) = 2, so let's shift D towards right by 2:

N: -42 0 -12 1

", + "

d: 0 0 -3 1

N(3)/d(3) = 1, so d is unchanged. Now remember that \"shifting by 2\"

", + "

is like multiplying by x2, and the final multiplication

", + "

(here by 1) is the coefficient of this monomial. Let's store this

", + "

into q:

", + "

0 1 2

", + "

---------------

", + "

q: 0 0 1

now compute N - d, and let it be the \"new\" N, and let's loop

N: -42 0 -9 0 degree = 2

", + "

D: -3 1 0 0 degree = 1

d(N) - d(D) = 1, right shift D by 1 and let it be d

N: -42 0 -9 0

", + "

d: 0 -3 1 0 * -9/1 = -9

q: 0 -9 1

d: 0 27 -9 0

N ← N - d

N: -42 -27 0 0 degree = 1

", + "

D: -3 1 0 0 degree = 1

looping again... d(N)-d(D)=0, so no shift is needed; we

", + "

multiply D by -27 (= -27/1) storing the result in d, then

q: -27 -9 1

and

N: -42 -27 0 0 -

", + "

d: 81 -27 0 0 =

", + "

N: -123 0 0 0 (last N)

d(N) < d(D), so now r ← N, and the result is:

0 1 2

", + "

-------------

", + "

q: -27 -9 1 → x2 - 9x - 27

", + "

r: -123 0 0 → -123

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f80", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Polynomial regression", + "type": "Waypoint", + "description": [ + "

Find an approximating polynomial of known degree for a given data.

Example:

", + "

For input data:

", + "

x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

", + "

y = {1, 6, 17, 34, 57, 86, 121, 162, 209, 262, 321};

", + "

The approximating polynomial is:

", + "

3 x2 + 2 x + 1

", + "

Here, the polynomial's coefficients are (3, 2, 1).

This task is intended as a subtask for Measure relative performance of sorting algorithms implementations.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f81", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Polyspiral", + "type": "Waypoint", + "description": [ + "

A Polyspiral is a spiral made of multiple line segments, whereby each segment is larger (or smaller) than the previous one by a given amount. Each segment also changes direction at a given angle.

", + "Task", + "

Animate a series of polyspirals, by drawing a complete spiral then incrementing the angle, and (after clearing the background) drawing the next, and so on. Every spiral will be a frame of the animation. The animation may stop as it goes full circle or continue indefinitely. The given input values may be varied.

If animation is not practical in your programming environment, you may show a single frame instead.

", + "Pseudo code", + "
",
+      "    set incr to 0.0    // animation loop",
+      "    WHILE true         incr = (incr + 0.05) MOD 360",
+      "        x = width / 2",
+      "        y = height / 2",
+      "        length = 5",
+      "        angle = incr        // spiral loop",
+      "        FOR 1 TO 150",
+      "            drawline",
+      "            change direction by angle",
+      "            length = length + 3",
+      "            angle = (angle + incr) MOD 360",
+      "        ENDFOR"
+    ],
+    "null": ["



", ""], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f82", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Population count", + "type": "Waypoint", + "description": [ + "

The population count is the number of 1s (ones) in the binary representation of a non-negative integer.

Population count is also known as pop count, popcount, sideways sum, and Hamming weight.

For example, 5 (which is 101 in binary) has a population count of 2.

", + "

Evil numbers are non-negative integers that have an even population count.

Odious numbers are positive integers that have an odd population count.

", + "Task:", + "write a function (or routine) to return the population count of a non-negative integer.", + "all computation of the lists below should start with 0 (zero indexed).* display the pop count of the 1st thirty powers of 3 (30, 31, 32, 33, 34, ∙∙∙ 329).", + "

* display the 1st thirty evil numbers.

", + "

* display the 1st thirty odious numbers.

", + "display each list of integers on one line (which may or may not include a title), each set of integers being shown should be properly identified.See also", + "The On-Line Encyclopedia of Integer Sequences: A000069 odious numbers.", + "The On-Line Encyclopedia of Integer Sequences: A001969 evil numbers." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f83", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Power set", + "type": "Waypoint", + "description": [ + "

A set is a collection (container) of certain values,

", + "

without any particular order, and no repeated values.

It corresponds with a finite set in mathematics.

A set can be implemented as an associative array (partial mapping)

", + "

in which the value of each key-value pair is ignored.

Given a set S, the power set (or powerset) of S, written P(S), or 2S, is the set of all subsets of S.

", + "Task:", + "

By using a library or built-in set type, or by defining a set type with necessary operations, write a function with a set S as input that yields the power set 2S of S.

", + "

For example, the power set of {1,2,3,4} is

", + "

:: .

For a set which contains n elements, the corresponding power set has 2n elements, including the edge cases of empty set.

The power set of the empty set is the set which contains itself (20 = 1):

", + "

:: $\\mathcal{P}$($\\varnothing$) = { $\\varnothing$ }

And the power set of the set which contains only the empty set, has two subsets, the empty set and the set which contains the empty set (21 = 2):

", + "

:: $\\mathcal{P}$({$\\varnothing$}) = { $\\varnothing$, { $\\varnothing$ } }

", + "

Extra credit: Demonstrate that your language supports these last two powersets.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "====Iteration====", + "Uses a JSON stringifier from http://www.json.org/js.html", + "", + "{{works with|SpiderMonkey}}", + "function powerset(ary) {", + " var ps = [[]];", + " for (var i=0; i < ary.length; i++) {", + " for (var j = 0, len = ps.length; j < len; j++) {", + " ps.push(ps[j].concat(ary[i]));", + " }", + " }", + " return ps;", + "}", + "", + "var res = powerset([1,2,3,4]);", + "", + "load('json2.js');", + "print(JSON.stringify(res));", + "", + "{{out}}", + "
[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3],[4],[1,4],[2,4],[1,2,4],[3,4],[1,3,4],[2,3,4],[1,2,3,4]]
", + "", + "", + "====Functional composition====", + "", + "{{trans|Haskell}}", + "", + "(function () {", + "", + " // translating: powerset = foldr (\\x acc -> acc ++ map (x:) acc) [[]]", + "", + " function powerset(xs) {", + " return xs.reduceRight(function (a, x) {", + " return a.concat(a.map(function (y) {", + " return [x].concat(y);", + " }));", + " }, [[]]);", + " }", + "", + "", + " // TEST", + " return {", + " '[1,2,3] ->': powerset([1, 2, 3]),", + " 'empty set ->': powerset([]),", + " 'set which contains only the empty set ->': powerset([[]])", + " }", + "", + "})();", + "", + "{{Out}}", + "", + "{", + " \"[1,2,3] ->\":[[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]],", + " \"empty set ->\":[[]],", + " \"set which contains only the empty set ->\":[[], [[]]]", + "}", + "", + "===ES6===", + "", + "(() => {", + " 'use strict';", + "", + " // powerset :: [a] -> [[a]]", + " const powerset = xs =>", + " xs.reduceRight((a, x) => a.concat(a.map(y => [x].concat(y))), [", + " []", + " ]);", + "", + "", + " // TEST", + " return {", + " '[1,2,3] ->': powerset([1, 2, 3]),", + " 'empty set ->': powerset([]),", + " 'set which contains only the empty set ->': powerset([", + " []", + " ])", + " };", + "})()", + "", + "{{Out}}", + "{\"[1,2,3] ->\":[[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]], ", + "\"empty set ->\":[[]], ", + "\"set which contains only the empty set ->\":[[], [[]]]}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f84", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function powerset(ary) {\n var ps = [[]];\n for (var i=0; i < ary.length; i++) {\n for (var j = 0, len = ps.length; j < len; j++) {\n ps.push(ps[j].concat(ary[i]));\n }\n }\n return ps;\n}\n\nvar res = powerset([1,2,3,4]);\n\nload('json2.js');\nprint(JSON.stringify(res));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Price fraction", + "type": "Waypoint", + "description": [ + "

A friend of mine runs a pharmacy. He has a specialized function in his Dispensary application which receives a decimal value of currency and replaces it to a standard value. This value is regulated by a government department.

", + "Task:", + "

Given a floating point value between 0.00 and 1.00, rescale according to the following table:

>= 0.00 < 0.06 := 0.10

", + "

>= 0.06 < 0.11 := 0.18

", + "

>= 0.11 < 0.16 := 0.26

", + "

>= 0.16 < 0.21 := 0.32

", + "

>= 0.21 < 0.26 := 0.38

", + "

>= 0.26 < 0.31 := 0.44

", + "

>= 0.31 < 0.36 := 0.50

", + "

>= 0.36 < 0.41 := 0.54

", + "

>= 0.41 < 0.46 := 0.58

", + "

>= 0.46 < 0.51 := 0.62

", + "

>= 0.51 < 0.56 := 0.66

", + "

>= 0.56 < 0.61 := 0.70

", + "

>= 0.61 < 0.66 := 0.74

", + "

>= 0.66 < 0.71 := 0.78

", + "

>= 0.71 < 0.76 := 0.82

", + "

>= 0.76 < 0.81 := 0.86

", + "

>= 0.81 < 0.86 := 0.90

", + "

>= 0.86 < 0.91 := 0.94

", + "

>= 0.91 < 0.96 := 0.98

", + "

>= 0.96 < 1.01 := 1.00

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "In the task definition, the first step is 0.06, the rest are 0.05 ", + "so a re-factoring can subtract 0.01 from the value and divide by 0.05 to get the step.", + "", + "Working with decimal numbers in JavaScript has issues, e.g. 0.06 - 0.01 = 0.049999999999999996 due to using IEEE 754 double precision numbers that can't accurately represent all decimals. So values are multiplied by 100 and integer arithmetic is used.", + "", + "Note that multiplying a string by a number produces a number, the bitwise OR (|) truncates floating point numbers to integer, making it a concise replacement for ''Math.floor''.", + "", + "Passing a value outside the range 0 <= x < 1.01 will return undefined.", + "", + "function getScaleFactor(v) {", + "", + " var values = ['0.10','0.18','0.26','0.32','0.38','0.44','0.50','0.54',", + " '0.58','0.62','0.66','0.70','0.74','0.78','0.82','0.86',", + " '0.90','0.94','0.98','1.00'];", + "", + " return values[(v * 100 - 1) / 5 | 0];", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f86", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function getScaleFactor(v) {\n\n var values = ['0.10','0.18','0.26','0.32','0.38','0.44','0.50','0.54',\n '0.58','0.62','0.66','0.70','0.74','0.78','0.82','0.86',\n '0.90','0.94','0.98','1.00'];\n\n return values[(v * 100 - 1) / 5 | 0];\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Primality by trial division", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a boolean function that tells whether a given integer is prime.

", + "

Remember that 1 and all non-positive numbers are not prime.

Use trial division.

Even numbers over two may be eliminated right away.

A loop from 3 to √ will suffice, but other loops are allowed.

", + "Related tasks:", + " count in factors", + " prime decomposition", + " AKS test for primes", + " factors of an integer", + " Sieve of Eratosthenes", + " factors of a Mersenne number", + " trial factoring of a Mersenne number", + " partition an integer X into N primes", + " sequence of primes by Trial Division" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function isPrime(n) {", + " if (n == 2 || n == 3 || n == 5 || n == 7) {", + " return true;", + " } else if ((n < 2) || (n % 2 == 0)) {", + " return false;", + " } else {", + " for (var i = 3; i <= Math.sqrt(n); i += 2) {", + " if (n % i == 0)", + " return false;", + " }", + " return true;", + " }", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f87", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function isPrime(n) {\n if (n == 2 || n == 3 || n == 5 || n == 7) {\n return true;\n } else if ((n < 2) || (n % 2 == 0)) {\n return false;\n } else {\n for (var i = 3; i <= Math.sqrt(n); i += 2) {\n if (n % i == 0)\n return false;\n }\n return true;\n }\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Prime decomposition", + "type": "Waypoint", + "description": [ + "

The prime decomposition of a number is defined as a list of prime numbers

", + "

which when all multiplied together, are equal to that number.

", + "Example:", + "

12 = 2 × 2 × 3, so its prime decomposition is {2, 2, 3}

", + "Task:", + "

Write a function which returns an array or collection which contains the prime decomposition of a given number $n$ greater than 1.

If your language does not have an isPrime-like function available,

", + "

you may assume that you have a function which determines

", + "

whether a number is prime (note its name before your code).

If you would like to test code from this task, you may use code from trial division or the Sieve of Eratosthenes.

Note: The program must not be limited by the word size of your computer or some other artificial limit; it should work for any number regardless of size (ignoring the physical limits of RAM etc).

", + "Related tasks:", + " count in factors", + " factors of an integer", + " Sieve of Eratosthenes", + " primality by trial division", + " factors of a Mersenne number", + " trial factoring of a Mersenne number", + " partition an integer X into N primes", + " sequence of primes by Trial Division" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "This code uses the BigInteger Library [http://xenon.stanford.edu/~tjw/jsbn/jsbn.js jsbn] and [http://xenon.stanford.edu/~tjw/jsbn/jsbn2.js jsbn2]", + "function run_factorize(input, output) {", + " var n = new BigInteger(input.value, 10);", + " var TWO = new BigInteger(\"2\", 10);", + " var divisor = new BigInteger(\"3\", 10);", + " var prod = false;", + "", + " if (n.compareTo(TWO) < 0) ", + " return; ", + "", + " output.value = \"\";", + "", + " while (true) {", + " var qr = n.divideAndRemainder(TWO);", + " if (qr[1].equals(BigInteger.ZERO)) {", + " if (prod) ", + " output.value += \"*\"; ", + " else ", + " prod = true; ", + " output.value += \"2\";", + " n = qr[0];", + " }", + " else ", + " break; ", + " }", + "", + " while (!n.equals(BigInteger.ONE)) {", + " var qr = n.divideAndRemainder(divisor);", + " if (qr[1].equals(BigInteger.ZERO)) {", + " if (prod) ", + " output.value += \"*\"; ", + " else ", + " prod = true; ", + " output.value += divisor;", + " n = qr[0];", + " }", + " else ", + " divisor = divisor.add(TWO); ", + " }", + "}", + "", + "Without any library.", + "function run_factorize(n) {", + "\tif (n <= 3)", + "\t\t\treturn [n];", + "", + "\tvar ans = [];", + "\tvar done = false;", + "\twhile (!done)", + "\t{", + "\t\tif (n%2 === 0){", + "\t\t\t\tans.push(2);", + "\t\t\t\tn /= 2;", + "\t\t\t\tcontinue;", + "\t\t}", + "\t\tif (n%3 === 0){", + "\t\t\t\tans.push(3);", + "\t\t\t\tn /= 3;", + "\t\t\t\tcontinue;", + "\t\t}", + "\t\tif ( n === 1)", + "\t\t\treturn ans;", + "\t\tvar sr = Math.sqrt(n);", + "\t\tdone = true;", + "\t\t// try to divide the checked number by all numbers till its square root.", + "\t\tfor (var i=6; i<=sr; i+=6){", + "\t\t\t\tif (n%(i-1) === 0){ // is n divisible by i-1?", + "\t\t\t\t\t\tans.push( (i-1) );", + "\t\t\t\t\t\tn /= (i-1);", + "\t\t\t\t\t\tdone = false;", + "\t\t\t\t\t\tbreak;", + "\t\t\t\t}", + "\t\t\t\tif (n%(i+1) === 0){ // is n divisible by i+1?", + "\t\t\t\t\t\tans.push( (i+1) );", + "\t\t\t\t\t\tn /= (i+1);", + "\t\t\t\t\t\tdone = false;", + "\t\t\t\t\t\tbreak;", + "\t\t\t\t}", + "\t\t}", + "\t}", + "\tans.push( n );", + "\treturn ans;", + "}", + "", + "TDD using Jasmine", + "", + "PrimeFactors.js", + "function factors(n) {", + " if (!n || n < 2)", + " return [];", + "", + " var f = [];", + " for (var i = 2; i <= n; i++){", + " while (n % i === 0){", + " f.push(i);", + " n /= i;", + " }", + " }", + "", + " return f;", + "};", + "", + "", + "SpecPrimeFactors.js (with tag for Chutzpah)", + "/// ", + "", + "describe(\"Prime Factors\", function() {", + " it(\"Given nothing, empty is returned\", function() {", + " expect(factors()).toEqual([]);", + " });", + "", + " it(\"Given 1, empty is returned\", function() {", + " expect(factors(1)).toEqual([]);", + " });", + "", + " it(\"Given 2, 2 is returned\", function() {", + " expect(factors(2)).toEqual([2]);", + " });", + "", + " it(\"Given 3, 3 is returned\", function() {", + " expect(factors(3)).toEqual([3]);", + " });", + "", + " it(\"Given 4, 2 and 2 is returned\", function() {", + " expect(factors(4)).toEqual([2, 2]);", + " });", + "", + " it(\"Given 5, 5 is returned\", function() {", + " expect(factors(5)).toEqual([5]);", + " });", + "", + " it(\"Given 6, 2 and 3 is returned\", function() {", + " expect(factors(6)).toEqual([2, 3]);", + " });", + "", + " it(\"Given 7, 7 is returned\", function() {", + " expect(factors(7)).toEqual([7]);", + " });", + "", + " it(\"Given 8; 2, 2, and 2 is returned\", function() {", + " expect(factors(8)).toEqual([2, 2, 2]);", + " });", + "", + " it(\"Given a large number, many primes factors are returned\", function() {", + " expect(factors(2*2*2*3*3*7*11*17))", + " .toEqual([2, 2, 2, 3, 3, 7, 11, 17]);", + " });", + "", + " it(\"Given a large prime number, that number is returned\", function() {", + " expect(factors(997)).toEqual([997]);", + " });", + "});", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f88", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function run_factorize(input, output) {\n var n = new BigInteger(input.value, 10);\n var TWO = new BigInteger(\"2\", 10);\n var divisor = new BigInteger(\"3\", 10);\n var prod = false;\n\n if (n.compareTo(TWO) < 0) \n return; \n\n output.value = \"\";\n\n while (true) {\n var qr = n.divideAndRemainder(TWO);\n if (qr[1].equals(BigInteger.ZERO)) {\n if (prod) \n output.value += \"*\"; \n else \n prod = true; \n output.value += \"2\";\n n = qr[0];\n }\n else \n break; \n }\n\n while (!n.equals(BigInteger.ONE)) {\n var qr = n.divideAndRemainder(divisor);\n if (qr[1].equals(BigInteger.ZERO)) {\n if (prod) \n output.value += \"*\"; \n else \n prod = true; \n output.value += divisor;\n n = qr[0];\n }\n else \n divisor = divisor.add(TWO); \n }\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Primes - allocate descendants to their ancestors", + "type": "Waypoint", + "description": [ + "

The concept, rather simple, is to add the decomposition into prime factors of a number to get its 'ancestors'.

", + "

The objective is to demonstrate that the choice of the algorithm can be crucial in term of performance.

", + "

This solution could be compared to the solution that would use the decomposition into primes for all the numbers between 1 and 333.

", + "

The problem is to list, for a delimited set of ancestors (from 1 to 99) :

- the total of their own ancestors (LEVEL),

- their own ancestors (ANCESTORS),

- the total of the direct descendants (DESCENDANTS),

- all the direct descendants.

", + "

You only have to consider the prime factors < 100.

A grand total of the descendants has to be printed at the end of the list.

The task should be accomplished in a reasonable time-frame.

", + "

Example :

", + "
46 = 2*23 --> 2+23 = 25, is the parent of 46.",
+      "25 = 5*5  --> 5+5  = 10, is the parent of 25.",
+      "10 = 2*5  --> 2+5  = 7,  is the parent of 10.",
+      "7 is a prime factor and, as such, has no parent.46 has 3 ancestors (7, 10 and 25).",
+      "46 has 557 descendants.

The list layout and the output for Parent [46] :

", + "
[46] Level: 3",
+      "Ancestors: 7, 10, 25",
+      "Descendants: 557",
+      "129, 205, 246, 493, 518, 529, 740, 806, 888, 999, 1364, 1508, 1748, 2552, 2871, 3128, 3255, 3472, 3519, 3875, 3906, 4263, 4650, 4960, 5075, 5415, 5580, 5776, 5952, 6090, 6279, 6496, 6498, 6696, 6783, 7250, 7308, 7475, 7533, 8075, 8151, 8619, 8700, 8855, 8970, 9280, 9568, 9690, 10115, 10336, 10440, 10626, 10764, 11136, 11495, 11628, 11745, 12103, 12138, 12155, 12528, 12650, 13794, 14094, 14399, 14450, 14586, 15180, 15379, 15778, 16192, 17290, 17303, 17340, 18216, 18496, 20482, 20493, 20570, 20748, 20808, 21658, 21970, 22540, 23409, 24684, 24700, 26026, 26364, 27048, 29260, 29282, 29640, 30429, 30940, 31616, 32200, 33345, 35112, 35568, 36225, 36652, 37128, 37180, 38640, 39501, 40014, 41216, 41769, 41800, 43125, 43470, 44044, 44200, 44616, 46000, 46368, 47025, 49725, 50160, 50193, 51750, 52136, 52164, 52360, 53040, 53504, 55200, 56430, 56576, 58653, 58880, 58905, 59670, 60192, 62100, 62832, 62920, 63648, 66240, 66248, 67716, 69825, 70125, 70656, 70686, 70785, 71604, 74480, 74520, 74529, 74536, 74800, 75504, 79488, 83125, 83790, 83835, 83853, 84150, 84942, 87465, 88725, 89376, 89424, 89760, 93296, 94640, 95744, 99750, 99825, 100548, 100602, 100980, 104125, 104958, 105105, 105625, 106400, 106470, 106480, 107712, 112112, 113568, 118750, 119700, 119790, 121176, 124509, 124950, 125125, 126126, 126750, 127680, 127764, 127776, 133280, 135200, 136192, 136323, 142500, 143640, 143748, 148225, 148750, 149940, 150150, 152000, 152100, 153216, 156065, 159936, 160160, 161595, 162240, 171000, 172368, 173056, 177870, 178500, 178750, 179928, 180180, 182400, 182520, 184877, 187278, 189728, 190400, 192192, 192375, 193914, 194560, 194688, 202419, 205200, 205335, 211750, 212500, 213444, 214200, 214500, 216216, 218880, 219024, 222950, 228480, 228800, 230850, 233472, 240975, 243243, 243712, 246240, 246402, 254100, 255000, 257040, 257400, 262656, 264110, 267540, 271040, 272000, 274176, 274560, 277020, 285376, 286875, 289170, 289575, 292864, 295488, 302500, 304920, 306000, 308448, 308880, 316932, 318500, 321048, 325248, 326400, 329472, 332424, 343035, 344250, 347004, 347490, 348160, 361179, 363000, 365904, 367200, 370656, 373977, 377300, 382200, 387200, 391680, 407680, 408375, 411642, 413100, 416988, 417792, 429975, 435600, 440640, 452760, 455000, 458640, 464640, 470016, 470596, 482944, 489216, 490050, 495616, 495720, 509355, 511875, 515970, 522720, 528768, 539000, 543312, 546000, 550368, 557568, 557685, 582400, 588060, 594864, 606375, 609375, 611226, 614250, 619164, 627264, 646800, 650000, 655200, 669222, 672280, 689920, 698880, 705672, 721875, 727650, 731250, 737100, 745472, 756315, 770000, 776160, 780000, 786240, 793881, 806736, 827904, 832000, 838656, 859375, 866250, 873180, 877500, 884520, 900375, 907578, 924000, 931392, 936000, 943488, 960400, 985600, 995085, 998400, 1031250, 1039500, 1047816, 1053000, 1061424, 1064960, 1071875, 1080450, 1100000, 1108800, 1123200, 1152480, 1178793, 1182720, 1184625, 1194102, 1198080, 1229312, 1237500, 1247400, 1261568, 1263600, 1277952, 1286250, 1296540, 1320000, 1330560, 1347840, 1372000, 1382976, 1403325, 1408000, 1419264, 1421550, 1437696, 1485000, 1496880, 1516320, 1531250, 1543500, 1555848, 1584000, 1596672, 1617408, 1646400, 1670625, 1683990, 1689600, 1705860, 1750329, 1756160, 1782000, 1796256, 1802240, 1819584, 1837500, 1852200, 1900800, 1960000, 1975680, 2004750, 2020788, 2027520, 2047032, 2083725, 2107392, 2138400, 2162688, 2187500, 2205000, 2222640, 2280960, 2302911, 2352000, 2370816, 2405700, 2433024, 2480625, 2500470, 2508800, 2566080, 2625000, 2646000, 2667168, 2737152, 2800000, 2822400, 2886840, 2953125, 2976750, 3000564, 3010560, 3079296, 3125000, 3150000, 3175200, 3211264, 3247695, 3360000, 3386880, 3464208, 3515625, 3543750, 3572100, 3584000, 3612672, 3750000, 3780000, 3810240, 3897234, 4000000, 4032000, 4064256, 4218750, 4252500, 4286520, 4300800, 4500000, 4536000, 4572288, 4587520, 4800000, 4822335, 4838400, 5062500, 5103000, 5120000, 5143824, 5160960, 5400000, 5443200, 5505024, 5740875, 5760000, 5786802, 5806080, 6075000, 6123600, 6144000, 6193152, 6480000, 6531840, 6553600, 6834375, 6889050, 6912000, 6967296, 7290000, 7348320, 7372800, 7776000, 7838208, 7864320, 8201250, 8266860, 8294400, 8388608, 8748000, 8817984, 8847360, 9331200, 9437184, 9841500, 9920232, 9953280, 10497600, 10616832, 11160261, 11197440, 11809800, 11943936, 12597120, 13286025, 13436928, 14171760, 15116544, 15943230, 17006112, 19131876

Some figures :

", + "
The biggest descendant number : 3^33 = 5.559.060.566.555.523 (parent 99)Total Descendants 546.986",
+      "
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f89", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Primorial numbers", + "type": "Waypoint", + "description": [ + "

Primorial numbers are those formed by multiplying successive prime numbers.

", + "

The primorial number series is:

:* primorial(0) = 1 (by definition)

", + "

:* primorial(1) = 2 (2)

", + "

:* primorial(2) = 6 (2*3)

", + "

:* primorial(3) = 30 (2*3*5)

", + "

:* primorial(4) = 210 (2*3*5*7)

", + "

:* primorial(5) = 2310 (2*3*5*7*11)

", + "

:* primorial(6) = 30030 (2*3*5*7*11*13)

", + "

;* ∙ ∙ ∙

To express this mathematically, primorialn is

", + "

the product of the first n (successive) primes:

", + "

", + "

$primorial_n = \\prod_{k=1}^n prime_k$

", + "
", + "

::::: ─── where $prime_k$ is the kth'' prime number.

", + "
", + "

In some sense, generating primorial numbers is similar to factorials.

As with factorials, primorial numbers get large quickly.

", + "

task requirements:

Show the first ten primorial numbers (0 ──► 9, inclusive).", + " Show the length of primorial numbers whose index is: 10 100 1,000 10,000 and 100,000.", + " Show the length of the one millionth primorial number (optional). ", + " Use exact integers, not approximations.

By length (above), it is meant the number of decimal digits in the numbers.

", + "

links:

See the MathWorld webpage: primorial

See the Wikipedia webpage: primorial.

See the OEIS webpage: A2110.

", + "

Related tasks:

", + "Factorial", + "Sequence of primorial primes" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f8a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Problem of Apollonius", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement a solution to the Problem of Apollonius (description on Wikipedia) which is the problem of finding the circle that is tangent to three specified circles. There is an algebraic solution which is pretty straightforward.

The solutions to the example in the code are shown in the image (below and right). The red circle is \"internally tangent\" to all three black circles, and the green circle is \"externally tangent\" to all three black circles.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f8d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Pythagoras tree", + "type": "Waypoint", + "description": [ + "

The Pythagoras tree is a fractal tree constructed from squares. It is named after Pythagoras because each triple of touching squares encloses a right triangle, in a configuration traditionally used to represent the Pythagorean theorem.

", + "Task", + "

Construct a Pythagoras tree of order 7 using only vectors (no rotation or trig functions).

", + "Related tasks", + "Fractal tree" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f90", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Pythagorean triples", + "type": "Waypoint", + "description": [ + "

A Pythagorean triple is defined as three positive integers $(a, b, c)$ where $a < b < c$, and $a^2+b^2=c^2.$

They are called primitive triples if $a, b, c$ are co-prime, that is, if their pairwise greatest common divisors ${\\rm gcd}(a, b) = {\\rm gcd}(a, c) = {\\rm gcd}(b, c) = 1$.

Because of their relationship through the Pythagorean theorem, a, b, and c are co-prime if a and b are co-prime (${\\rm gcd}(a, b) = 1$).

Each triple forms the length of the sides of a right triangle, whose perimeter is $P=a+b+c$.

", + "Task:", + "

The task is to determine how many Pythagorean triples there are with a perimeter no larger than 100 and the number of these that are primitive.

", + "Extra credit: ", + "

Deal with large values. Can your program handle a maximum perimeter of 1,000,000? What about 10,000,000? 100,000,000?

Note: the extra credit is not for you to demonstrate how fast your language is compared to others; you need a proper algorithm to solve them in a timely manner.

", + "Cf:", + "List comprehensions" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "Exhaustive search of a full cartesian product. Not scalable.", + "(() => {", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // gcd :: Integral a => a -> a -> a", + " const gcd = (x, y) => {", + " const _gcd = (a, b) => (b === 0 ? a : _gcd(b, a % b)),", + " abs = Math.abs;", + " return _gcd(abs(x), abs(y));", + " }", + "", + " // Arguments: predicate, maximum perimeter", + " // pythTripleCount :: ((Int, Int, Int) -> Bool) -> Int -> Int", + " const pythTripleCount = (p, maxPerim) => {", + " const xs = range(1, Math.floor(maxPerim / 2));", + "", + " return concatMap(x =>", + " concatMap(y =>", + " concatMap(z =>", + " ( (x + y + z <= maxPerim ) &&", + " (x * x + y * y === z * z ) &&", + " p(x, y, z) ) ? [", + " [x, y, z]", + " ] : [ ], // concatMap eliminates empty lists", + " xs.slice(y)), xs.slice(x)), xs", + " )", + " .length;", + " };", + "", + " return [10, 100, 1000]", + " .map(n => ({", + " maxPerimeter: n,", + " triples: pythTripleCount(x => true, n),", + " primitives: pythTripleCount((x, y, _) => gcd(x, y) === 1, n)", + " }));", + "})();", + "", + "{{Out}}", + "[{\"maxPerimeter\":10, \"triples\":0, \"primitives\":0}, ", + " {\"maxPerimeter\":100, \"triples\":17, \"primitives\":7}, ", + " {\"maxPerimeter\":1000, \"triples\":325, \"primitives\":70}]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f91", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n\n // concatMap :: (a -> [b]) -> [a] -> [b]\n const concatMap = (f, xs) => [].concat.apply([], xs.map(f));\n\n // range :: Int -> Int -> [Int]\n const range = (m, n) =>\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i);\n\n // gcd :: Integral a => a -> a -> a\n const gcd = (x, y) => {\n const _gcd = (a, b) => (b === 0 ? a : _gcd(b, a % b)),\n abs = Math.abs;\n return _gcd(abs(x), abs(y));\n }\n\n // Arguments: predicate, maximum perimeter\n // pythTripleCount :: ((Int, Int, Int) -> Bool) -> Int -> Int\n const pythTripleCount = (p, maxPerim) => {\n const xs = range(1, Math.floor(maxPerim / 2));\n\n return concatMap(x =>\n concatMap(y =>\n concatMap(z =>\n ( (x + y + z <= maxPerim ) &&\n (x * x + y * y === z * z ) &&\n p(x, y, z) ) ? [\n [x, y, z]\n ] : [ ], // concatMap eliminates empty lists\n xs.slice(y)), xs.slice(x)), xs\n )\n .length;\n };\n\n return [10, 100, 1000]\n .map(n => ({\n maxPerimeter: n,\n triples: pythTripleCount(x => true, n),\n primitives: pythTripleCount((x, y, _) => gcd(x, y) === 1, n)\n }));\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "QR decomposition", + "type": "Waypoint", + "description": [ + "

Any rectangular $m \\times n$ matrix $\\mathit A$ can be decomposed to a product of an orthogonal matrix $\\mathit Q$ and an upper (right) triangular matrix $\\mathit R$, as described in QR decomposition.

Task

Demonstrate the QR decomposition on the example matrix from the Wikipedia article:

:$A = \\begin{pmatrix}

", + "

12 & -51 & 4 \\\\

", + "

6 & 167 & -68 \\\\

", + "

-4 & 24 & -41 \\end{pmatrix}$

and the usage for linear least squares problems on the example from Polynomial_regression. The method of Householder reflections should be used:

Method

Multiplying a given vector $\\mathit a$, for example the first column of matrix $\\mathit A$, with the Householder matrix $\\mathit H$, which is given as

:$H = I - \\frac {2} {u^T u} u u^T$

reflects $\\mathit a$ about a plane given by its normal vector $\\mathit u$. When the normal vector of the plane $\\mathit u$ is given as

:$u = a - \\|a\\|_2 \\; e_1$

then the transformation reflects $\\mathit a$ onto the first standard basis vector

:$e_1 = [1 \\; 0 \\; 0 \\; ...]^T$

which means that all entries but the first become zero. To avoid numerical cancellation errors, we should take the opposite sign of $a_1$:

:$u = a + \\textrm{sign}(a_1)\\|a\\|_2 \\; e_1$

and normalize with respect to the first element:

:$v = \\frac{u}{u_1}$

The equation for $H$ thus becomes:

:$H = I - \\frac {2} {v^T v} v v^T$

or, in another form

:$H = I - \\beta v v^T$

with

", + "

:$\\beta = \\frac {2} {v^T v}$

Applying $\\mathit H$ on $\\mathit a$ then gives

:$H \\; a = -\\textrm{sign}(a_1) \\; \\|a\\|_2 \\; e_1$

and applying $\\mathit H$ on the matrix $\\mathit A$ zeroes all subdiagonal elements of the first column:

:$H_1 \\; A = \\begin{pmatrix}

", + "

r_{11} & r_{12} & r_{13} \\\\

", + "

0 & * & * \\\\

", + "

0 & * & * \\end{pmatrix}$

In the second step, the second column of $\\mathit A$, we want to zero all elements but the first two, which means that we have to calculate $\\mathit H$ with the first column of the submatrix (denoted *), not on the whole second column of $\\mathit A$.

To get $H_2$, we then embed the new $\\mathit H$ into an $m \\times n$ identity:

:$H_2 = \\begin{pmatrix}

", + "

1 & 0 & 0 \\\\

", + "

0 & H & \\\\

", + "

0 & & \\end{pmatrix}$

This is how we can, column by column, remove all subdiagonal elements of $\\mathit A$ and thus transform it into $\\mathit R$.

:$H_n \\; ... \\; H_3 H_2 H_1 A = R$

The product of all the Householder matrices $\\mathit H$, for every column, in reverse order, will then yield the orthogonal matrix $\\mathit Q$.

:$H_1 H_2 H_3 \\; ... \\; H_n = Q$

The QR decomposition should then be used to solve linear least squares (Multiple regression) problems $\\mathit A x = b$ by solving

:$R \\; x = Q^T \\; b$

When $\\mathit R$ is not square, i.e. $m > n$ we have to cut off the $\\mathit m - n$ zero padded bottom rows.

:$R =

", + "

\\begin{pmatrix}

", + "

R_1 \\\\

", + "

0 \\end{pmatrix}$

and the same for the RHS:

:$Q^T \\; b =

", + "

\\begin{pmatrix}

", + "

q_1 \\\\

", + "

q_2 \\end{pmatrix}$

Finally, solve the square upper triangular system by back substitution:

:$R_1 \\; x = q_1$

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f92", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Quaternion type", + "type": "Waypoint", + "description": [ + "

Quaternions are an extension of the idea of complex numbers.

A complex number has a real and complex part, sometimes written as a + bi,

", + "where a and b stand for real numbers, and i stands for the square root of minus 1.

An example of a complex number might be -3 + 2i,

", + "where the real part, a is -3.0 and the complex part, b is +2.0.

A quaternion has one real part and three imaginary parts, i, j, and k.

A quaternion might be written as a + bi + cj + dk.

In the quaternion numbering system:

", + "

::* i∙i = j∙j = k∙k = i∙j∙k = -1, or more simply,

", + "

::* ii = jj = kk = ijk = -1.

The order of multiplication is important, as, in general, for two quaternions:

", + "

::: q1 and q2: q1q2 ≠ q2q1.

An example of a quaternion might be 1 +2i +3j +4k

There is a list form of notation where just the numbers are shown and the imaginary multipliers i, j, and k are assumed by position.

So the example above would be written as (1, 2, 3, 4)

", + "Task:", + "

Given the three quaternions and their components:

", + "

q = (1, 2, 3, 4) = (a, b, c, d)

", + "

q1 = (2, 3, 4, 5) = (a1, b1, c1, d1)

", + "

q2 = (3, 4, 5, 6) = (a2, b2, c2, d2)

", + "

And a wholly real number r = 7.

", + "

Note: The first formula below is invisible to the majority of browsers, including Chrome, IE/Edge, Safari, Opera etc. It may, subject to the installation of requisite fonts, prove visible in Firefox.

", + "

Create functions (or classes) to perform simple maths with quaternions including computing:

", + "The norm of a quaternion: $ = \\sqrt{ a^2 + b^2 + c^2 + d^2 } $ ", + "The negative of a quaternion: = (-a, -b, -c, -d) ", + "The conjugate of a quaternion: = ( a, -b, -c, -d) ", + "Addition of a real number r and a quaternion q: r + q = q + r = (a+r, b, c, d) ", + "Addition of two quaternions: q1 + q2 = (a1+a2, b1+b2, c1+c2, d1+d2) ", + "Multiplication of a real number and a quaternion: qr = rq = (ar, br, cr, dr) ", + "Multiplication of two quaternions q1 and q2 is given by: ( a1a2 − b1b2 − c1c2 − d1d2, a1b2 + b1a2 + c1d2 − d1c2, a1c2 − b1d2 + c1a2 + d1b2, a1d2 + b1c2 − c1b2 + d1a2 ) ", + "Show that, for the two quaternions q1 and q2: q1q2 ≠ q2q1 ", + "

If a language has built-in support for quaternions, then use it.

", + "C.f.:", + " Vector products", + " On Quaternions; or on a new System of Imaginaries in Algebra. By Sir William Rowan Hamilton LL.D, P.R.I.A., F.R.A.S., Hon. M. R. Soc. Ed. and Dub., Hon. or Corr. M. of the Royal or Imperial Academies of St. Petersburgh, Berlin, Turin and Paris, Member of the American Academy of Arts and Sciences, and of other Scientific Societies at Home and Abroad, Andrews' Prof. of Astronomy in the University of Dublin, and Royal Astronomer of Ireland." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Runs on Firefox 3+, limited support in other JS engines. More compatible JavaScript deserves its own entry.", + "", + "var Quaternion = (function() {", + " // The Q() function takes an array argument and changes it", + " // prototype so that it becomes a Quaternion instance. This is", + " // scoped only for prototype member access.", + " function Q(a) {", + "\ta.__proto__ = proto;", + "\treturn a;", + " }", + "", + " // Actual constructor. This constructor converts its arguments to", + " // an array, then that array to a Quaternion instance, then", + " // returns that instance. (using \"new\" with this constructor is", + " // optional)", + " function Quaternion() {", + "\treturn Q(Array.prototype.slice.call(arguments, 0, 4));", + " }", + "", + " // Prototype for all Quaternions", + " const proto = {", + "\t// Inherits from a 4-element Array", + "\t__proto__ : [0,0,0,0],", + "", + "\t// Properties -- In addition to Array[0..3] access, we", + "\t// also define matching a, b, c, and d properties", + "\tget a() this[0],", + "\tget b() this[1],", + "\tget c() this[2],", + "\tget d() this[3],", + "", + "\t// Methods", + "\tnorm : function() Math.sqrt(this.map(function(x) x*x).reduce(function(x,y) x+y)),", + "\tnegate : function() Q(this.map(function(x) -x)),", + "\tconjugate : function() Q([ this[0] ].concat(this.slice(1).map(function(x) -x))),", + "\tadd : function(x) {", + "\t if (\"number\" === typeof x) {", + "\t\treturn Q([ this[0] + x ].concat(this.slice(1)));", + "\t } else {", + "\t\treturn Q(this.map(function(v,i) v+x[i]));", + "\t }", + "\t},", + "\tmul : function(r) {", + "\t var q = this;", + "\t if (\"number\" === typeof r) {", + "\t\treturn Q(q.map(function(e) e*r));", + "\t } else {", + "\t\treturn Q([ q[0] * r[0] - q[1] * r[1] - q[2] * r[2] - q[3] * r[3],", + "\t\t\t q[0] * r[1] + q[1] * r[0] + q[2] * r[3] - q[3] * r[2],", + "\t\t\t q[0] * r[2] - q[1] * r[3] + q[2] * r[0] + q[3] * r[1],", + "\t\t\t q[0] * r[3] + q[1] * r[2] - q[2] * r[1] + q[3] * r[0] ]);", + "\t }", + "\t},", + "\tequals : function(q) this.every(function(v,i) v === q[i]),", + "\ttoString : function() (this[0] + \" + \" + this[1] + \"i + \"+this[2] + \"j + \" + this[3] + \"k\").replace(/\\+ -/g, '- ')", + " };", + "", + " Quaternion.prototype = proto;", + " return Quaternion;", + "})();", + "", + "Task/Example Usage:", + "", + "var q = Quaternion(1,2,3,4);", + "var q1 = Quaternion(2,3,4,5);", + "var q2 = Quaternion(3,4,5,6);", + "var r = 7;", + "", + "console.log(\"q = \"+q);", + "console.log(\"q1 = \"+q1);", + "console.log(\"q2 = \"+q2);", + "console.log(\"r = \"+r);", + "console.log(\"1. q.norm() = \"+q.norm());", + "console.log(\"2. q.negate() = \"+q.negate());", + "console.log(\"3. q.conjugate() = \"+q.conjugate());", + "console.log(\"4. q.add(r) = \"+q.add(r));", + "console.log(\"5. q1.add(q2) = \"+q1.add(q2));", + "console.log(\"6. q.mul(r) = \"+q.mul(r));", + "console.log(\"7.a. q1.mul(q2) = \"+q1.mul(q2));", + "console.log(\"7.b. q2.mul(q1) = \"+q2.mul(q1));", + "console.log(\"8. q1.mul(q2) \" + (q1.mul(q2).equals(q2.mul(q1)) ? \"==\" : \"!=\") + \" q2.mul(q1)\");", + "", + "{{out}}", + "
q = 1 + 2i + 3j + 4k",
+      "q1 = 2 + 3i + 4j + 5k",
+      "q2 = 3 + 4i + 5j + 6k",
+      "r = 7",
+      "1. q.norm() = 5.477225575051661",
+      "2. q.negate() = -1 - 2i - 3j - 4k",
+      "3. q.conjugate() = 1 - 2i - 3j - 4k",
+      "4. q.add(r) = 8 + 2i + 3j + 4k",
+      "5. q1.add(q2) = 5 + 7i + 9j + 11k",
+      "6. q.mul(r) = 7 + 14i + 21j + 28k",
+      "7.a. q1.mul(q2) = -56 + 16i + 24j + 26k",
+      "7.b. q2.mul(q1) = -56 + 18i + 20j + 28k",
+      "8. q1.mul(q2) != q2.mul(q1)
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f93", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var Quaternion = (function() {\n // The Q() function takes an array argument and changes it\n // prototype so that it becomes a Quaternion instance. This is\n // scoped only for prototype member access.\n function Q(a) {\n\ta.__proto__ = proto;\n\treturn a;\n }\n\n // Actual constructor. This constructor converts its arguments to\n // an array, then that array to a Quaternion instance, then\n // returns that instance. (using \"new\" with this constructor is\n // optional)\n function Quaternion() {\n\treturn Q(Array.prototype.slice.call(arguments, 0, 4));\n }\n\n // Prototype for all Quaternions\n const proto = {\n\t// Inherits from a 4-element Array\n\t__proto__ : [0,0,0,0],\n\n\t// Properties -- In addition to Array[0..3] access, we\n\t// also define matching a, b, c, and d properties\n\tget a() this[0],\n\tget b() this[1],\n\tget c() this[2],\n\tget d() this[3],\n\n\t// Methods\n\tnorm : function() Math.sqrt(this.map(function(x) x*x).reduce(function(x,y) x+y)),\n\tnegate : function() Q(this.map(function(x) -x)),\n\tconjugate : function() Q([ this[0] ].concat(this.slice(1).map(function(x) -x))),\n\tadd : function(x) {\n\t if (\"number\" === typeof x) {\n\t\treturn Q([ this[0] + x ].concat(this.slice(1)));\n\t } else {\n\t\treturn Q(this.map(function(v,i) v+x[i]));\n\t }\n\t},\n\tmul : function(r) {\n\t var q = this;\n\t if (\"number\" === typeof r) {\n\t\treturn Q(q.map(function(e) e*r));\n\t } else {\n\t\treturn Q([ q[0] * r[0] - q[1] * r[1] - q[2] * r[2] - q[3] * r[3],\n\t\t\t q[0] * r[1] + q[1] * r[0] + q[2] * r[3] - q[3] * r[2],\n\t\t\t q[0] * r[2] - q[1] * r[3] + q[2] * r[0] + q[3] * r[1],\n\t\t\t q[0] * r[3] + q[1] * r[2] - q[2] * r[1] + q[3] * r[0] ]);\n\t }\n\t},\n\tequals : function(q) this.every(function(v,i) v === q[i]),\n\ttoString : function() (this[0] + \" + \" + this[1] + \"i + \"+this[2] + \"j + \" + this[3] + \"k\").replace(/\\+ -/g, '- ')\n };\n\n Quaternion.prototype = proto;\n return Quaternion;\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Queue/Definition", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement a FIFO queue.

Elements are added at one side and popped from the other in the order of insertion.

", + "

Operations:

", + " push (aka enqueue) - add element", + " pop (aka dequeue) - pop first element", + " empty - return truth value when empty

Errors:

", + " handle the error of trying to pop from an empty queue (behavior depends on the language and platform)See:", + " Queue/Usage for the built-in FIFO or queue of your language or standard library." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Most of the time, the built-in Array suffices. However, if you explicitly want to limit the usage to FIFO operations, it's easy to implement such a constructor.", + "", + "=== Using built-in Array ===", + "var fifo = [];", + "fifo.push(42); // Enqueue.", + "fifo.push(43);", + "var x = fifo.shift(); // Dequeue.", + "alert(x); // 42", + "", + "=== Custom constructor function ===", + "function FIFO() {", + " this.data = new Array();", + "", + " this.push = function(element) {this.data.push(element)}", + " this.pop = function() {return this.data.shift()}", + " this.empty = function() {return this.data.length == 0}", + "", + " this.enqueue = this.push;", + " this.dequeue = this.pop;", + "}", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f94", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var fifo = [];\nfifo.push(42); // Enqueue.\nfifo.push(43);\nvar x = fifo.shift(); // Dequeue.\nalert(x); // 42\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Queue/Usage", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a queue data structure and demonstrate its operations.

(For implementations of queues, see the FIFO task.)

", + "

Operations:

", + "

:* push (aka enqueue) - add element

", + "

:* pop (aka dequeue) - pop first element

", + "

:* empty - return truth value when empty

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "JavaScript arrays can be used as FIFOs.", + "var f = new Array();", + "print(f.length);", + "f.push(1,2); // can take multiple arguments", + "f.push(3);", + "f.shift();", + "f.shift();", + "print(f.length);", + "print(f.shift())", + "print(f.length == 0);", + "print(f.shift());", + "", + "outputs:", + "
0",
+      "1",
+      "3",
+      "true",
+      "undefined
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f95", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var f = new Array();\nprint(f.length);\nf.push(1,2); // can take multiple arguments\nf.push(3);\nf.shift();\nf.shift();\nprint(f.length);\nprint(f.shift())\nprint(f.length == 0);\nprint(f.shift());\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Quickselect algorithm", + "type": "Waypoint", + "description": [ + "

Use the quickselect algorithm on the vector

", + "

[9, 8, 7, 6, 5, 0, 1, 2, 3, 4]

", + "

To show the first, second, third, ... up to the tenth largest member of the vector, in order, here on this page.

Note: Quicksort has a separate task. " + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f96", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Quine", + "type": "Waypoint", + "description": [ + "

A Quine is a self-referential program that can,

", + "

without any external access, output its own source.

It is named after the philosopher and logician

", + "

who studied self-reference and quoting in natural language,

", + "

as for example in the paradox \"'Yields falsehood when preceded by its quotation' yields falsehood when preceded by its quotation.\"

\"Source\" has one of two meanings. It can refer to the text-based program source.

", + "

For languages in which program source is represented as a data structure, \"source\" may refer to the data structure: quines in these languages fall into two categories: programs which print a textual representation of themselves, or expressions which evaluate to a data structure which is equivalent to that expression.

The usual way to code a Quine works similarly to this paradox: The program consists of two identical parts, once as plain code and once quoted in some way (for example, as a character string, or a literal data structure). The plain code then accesses the quoted code and prints it out twice, once unquoted and once with the proper quotation marks added. Often, the plain code and the quoted code have to be nested.

", + "Task:", + "

Write a program that outputs its own source code in this way. If the language allows it, you may add a variant that accesses the code directly. You are not allowed to read any external files with the source code. The program should also contain some sort of self-reference, so constant expressions which return their own value which some top-level interpreter will print out. Empty programs producing no output are not allowed.

There are several difficulties that one runs into when writing a quine, mostly dealing with quoting:

", + "Part of the code usually needs to be stored as a string or structural literal in the language, which needs to be quoted somehow. However, including quotation marks in the string literal itself would be troublesome because it requires them to be escaped, which then necessitates the escaping character (e.g. a backslash) in the string, which itself usually needs to be escaped, and so on.", + "* Some languages have a function for getting the \"source code representation\" of a string (i.e. adds quotation marks, etc.); in these languages, this can be used to circumvent the quoting problem.", + "* Another solution is to construct the quote character from its character code, without having to write the quote character itself. Then the character is inserted into the string at the appropriate places. The ASCII code for double-quote is 34, and for single-quote is 39.", + "Newlines in the program may have to be reproduced as newlines in the string, which usually requires some kind of escape sequence (e.g. \"\\n\"). This causes the same problem as above, where the escaping character needs to itself be escaped, etc.", + "* If the language has a way of getting the \"source code representation\", it usually handles the escaping of characters, so this is not a problem.", + "* Some languages allow you to have a string literal that spans multiple lines, which embeds the newlines into the string without escaping.", + "* Write the entire program on one line, for free-form languages (as you can see for some of the solutions here, they run off the edge of the screen), thus removing the need for newlines. However, this may be unacceptable as some languages require a newline at the end of the file; and otherwise it is still generally good style to have a newline at the end of a file. (The task is not clear on whether a newline is required at the end of the file.) Some languages have a print statement that appends a newline; which solves the newline-at-the-end issue; but others do not.", + "

Next to the Quines presented here, many other versions can be found on the Quine page.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|SpiderMonkey}} 1.7.0", + "(function(){print(\"(\"+arguments.callee.toString().replace(/\\s/g,'')+\")()\");})()", + "", + "=== Using eval ===", + "{{works with|SpiderMonkey}} 1.7.0", + "This version doesn't use arguments.callee.toString() to return the string representation of itself. Instead, it relies on eval().", + "var code='var q=String.fromCharCode(39);print(\"var code=\"+q+code+q+\";eval(code)\")';eval(code)", + "", + "=== Replacing String ===", + "(function(){str=[\"(function(){str=[F].join(String.fromCharCode(34));str=str.replace(/F/,String.fromCharCode(34)+str+String.fromCharCode(34));console.log(str)})()\"].join(String.fromCharCode(34));str=str.replace(/F/,String.fromCharCode(34)+str+String.fromCharCode(34));console.log(str)})()", + "", + "===Another Method===", + "var a=function () {var b=\"var a=\"+a.toString()+\"\\;a()\";alert(b)};a()", + "", + "===A simple module which simply evaluates to itself===", + "", + "(function f() {", + " ", + " return '(' + f.toString() + ')();';", + " ", + "})();", + "", + "{{Out}}", + "", + "(function f() {", + "", + " return '(' + f.toString() + ')();';", + " ", + "})();", + "", + "===Or logs itself to the console===", + "(function f() {", + "", + " console.log('(' + f.toString() + ')();');", + "", + "})();", + "", + "{{Out}}", + "
(function f() {",
+      "",
+      "    console.log('(' + f.toString() + ')();');",
+      "",
+      "})();
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f97", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function(){print(\"(\"+arguments.callee.toString().replace(/\\s/g,'')+\")()\");})()\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Random number generator (device)", + "type": "Waypoint", + "description": [ + "Task:", + "

If your system has a means to generate random numbers involving not only a software algorithm (like the /dev/urandom devices in Unix), then:

show how to obtain a random 32-bit number from that mechanism.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f98", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Random number generator (included)", + "type": "Waypoint", + "description": [ + "

The task is to:

", + "

State the type of random number generator algorithm used in a language's built-in random number generator. If the language or its immediate libraries don't provide a random number generator, skip this task.

", + "

If possible, give a link to a wider explanation of the algorithm used.

Note: the task is not to create an RNG, but to report on the languages in-built RNG that would be the most likely RNG used.

The main types of pseudo-random number generator (PRNG) that are in use are the Linear Congruential Generator (LCG), and the Generalized Feedback Shift Register (GFSR), (of which the Mersenne twister generator is a subclass). The last main type is where the output of one of the previous ones (typically a Mersenne twister) is fed through a cryptographic hash function to maximize unpredictability of individual bits.

Note that neither LCGs nor GFSRs should be used for the most demanding applications (cryptography) without additional steps.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "The only built-in random number generation facility is Math.random(), which returns a floating-point number greater than or equal to 0 and less than 1, with approximately uniform distribution. The standard (ECMA-262) does not specify what algorithm is to be used.", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f99", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["null\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Range expansion", + "type": "Waypoint", + "description": [ + "Task:", + "

Expand the range description:

", + "

-6,-3--1,3-5,7-11,14,15,17-20

Note that the second element above,

", + "

is the range from minus 3 to minus 1.

", + "Related task:", + " Range extraction" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Imperative (Spidermonkey)===", + "", + "#!/usr/bin/env js", + "", + "function main() {", + " print(rangeExpand('-6,-3--1,3-5,7-11,14,15,17-20'));", + "}", + "", + "function rangeExpand(rangeExpr) {", + " ", + " function getFactors(term) {", + " var matches = term.match(/(-?[0-9]+)-(-?[0-9]+)/);", + " if (!matches) return {first:Number(term)};", + " return {first:Number(matches[1]), last:Number(matches[2])};", + " }", + " ", + " function expandTerm(term) {", + " var factors = getFactors(term);", + " if (factors.length < 2) return [factors.first];", + " var range = [];", + " for (var n = factors.first; n <= factors.last; n++) {", + " range.push(n);", + " }", + " return range;", + " }", + " ", + " var result = [];", + " var terms = rangeExpr.split(/,/);", + " for (var t in terms) {", + " result = result.concat(expandTerm(terms[t]));", + " }", + " ", + " return result;", + "}", + "", + "main();", + "", + "", + "{{out}}", + " -6,-3,-2,-1,3,4,5,7,8,9,10,11,14,15,17,18,19,20", + "", + "===Functional===", + "", + "====ES5====", + "", + "(function (strTest) {", + " 'use strict';", + "", + " // s -> [n]", + " function expansion(strExpr) {", + "", + " // concat map yields flattened output list", + " return [].concat.apply([], strExpr.split(',')", + " .map(function (x) {", + " return x.split('-')", + " .reduce(function (a, s, i, l) {", + "", + " // negative (after item 0) if preceded by an empty string", + " // (i.e. a hyphen-split artefact, otherwise ignored)", + " return s.length ? i ? a.concat(", + " parseInt(l[i - 1].length ? s :", + " '-' + s, 10)", + " ) : [+s] : a;", + " }, []);", + "", + " // two-number lists are interpreted as ranges", + " })", + " .map(function (r) {", + " return r.length > 1 ? range.apply(null, r) : r;", + " }));", + " }", + "", + "", + " // [m..n]", + " function range(m, n) {", + " return Array.apply(null, Array(n - m + 1))", + " .map(function (x, i) {", + " return m + i;", + " });", + " }", + "", + " return expansion(strTest);", + "", + "})('-6,-3--1,3-5,7-11,14,15,17-20');", + "", + "{{Out}}", + "", + "[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]", + "", + "", + "====ES6====", + "", + "(strTest => {", + " ", + " // expansion :: String -> [Int]", + " let expansion = strExpr =>", + "", + " // concat map yields flattened output list", + " [].concat.apply([], strExpr.split(',')", + " .map(x => x.split('-')", + " .reduce((a, s, i, l) =>", + "", + " // negative (after item 0) if preceded by an empty string", + " // (i.e. a hyphen-split artefact, otherwise ignored)", + " s.length ? i ? a.concat(", + " parseInt(l[i - 1].length ? s :", + " '-' + s, 10)", + " ) : [+s] : a, [])", + "", + " // two-number lists are interpreted as ranges", + " )", + " .map(r => r.length > 1 ? range.apply(null, r) : r)),", + "", + "", + "", + " // range :: Int -> Int -> Maybe Int -> [Int]", + " range = (m, n, step) => {", + " let d = (step || 1) * (n >= m ? 1 : -1);", + "", + " return Array.from({", + " length: Math.floor((n - m) / d) + 1", + " }, (_, i) => m + (i * d));", + " };", + "", + "", + "", + " return expansion(strTest);", + "", + "})('-6,-3--1,3-5,7-11,14,15,17-20');", + "", + "{{Out}}", + "[-6, -3, -2, -1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f9b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "#!/usr/bin/env js\n\nfunction main() {\n print(rangeExpand('-6,-3--1,3-5,7-11,14,15,17-20'));\n}\n\nfunction rangeExpand(rangeExpr) {\n \n function getFactors(term) {\n var matches = term.match(/(-?[0-9]+)-(-?[0-9]+)/);\n if (!matches) return {first:Number(term)};\n return {first:Number(matches[1]), last:Number(matches[2])};\n }\n \n function expandTerm(term) {\n var factors = getFactors(term);\n if (factors.length < 2) return [factors.first];\n var range = [];\n for (var n = factors.first; n <= factors.last; n++) {\n range.push(n);\n }\n return range;\n }\n \n var result = [];\n var terms = rangeExpr.split(/,/);\n for (var t in terms) {\n result = result.concat(expandTerm(terms[t]));\n }\n \n return result;\n}\n\nmain();\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Range extraction", + "type": "Waypoint", + "description": [ + "Task:", + "Create a function that takes a list of integers in increasing order and returns a correctly formatted string in the range format. ", + "Use the function to compute and print the range formatted version of the following ordered list of integers. (The correct answer is: 0-2,4,6-8,11,12,14-25,27-33,35-39.)", + "

0, 1, 2, 4, 6, 7, 8, 11, 12, 14,

", + "

15, 16, 17, 18, 19, 20, 21, 22, 23, 24,

", + "

25, 27, 28, 29, 30, 31, 32, 33, 35, 36,

", + "

37, 38, 39

", + "Show the output of your program.Related task:", + " Range expansion" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Imperative====", + "function rangeExtraction(list) {", + " var len = list.length;", + " var out = [];", + " var i, j;", + "", + " for (i = 0; i < len; i = j + 1) {", + " // beginning of range or single", + " out.push(list[i]);", + " ", + " // find end of range", + " for (var j = i + 1; j < len && list[j] == list[j-1] + 1; j++);", + " j--;", + " ", + " if (i == j) {", + " // single number", + " out.push(\",\");", + " } else if (i + 1 == j) {", + " // two numbers", + " out.push(\",\", list[j], \",\");", + " } else { ", + " // range", + " out.push(\"-\", list[j], \",\");", + " }", + " }", + " out.pop(); // remove trailing comma", + " return out.join(\"\");", + "}", + "", + "// using print function as supplied by Rhino standalone", + "print(rangeExtraction([", + " 0, 1, 2, 4, 6, 7, 8, 11, 12, 14,", + " 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,", + " 25, 27, 28, 29, 30, 31, 32, 33, 35, 36,", + " 37, 38, 39", + "]));", + "", + "====Functional====", + "{{Trans|ES6}}", + "{{Trans|Haskell}}", + "(function () {", + " 'use strict';", + "", + " // rangeFormat :: [Int] -> String", + " var rangeFormat = function (xs) {", + " return splitBy(function (a, b) {", + " return b - a > 1;", + " }, xs)", + " .map(rangeString)", + " .join(',');", + " };", + "", + " // rangeString :: [Int] -> String", + " var rangeString = function (xs) {", + " return xs.length > 2 ? [head(xs), last(xs)].map(show)", + " .join('-') : xs.join(',');", + " };", + "", + " // GENERIC FUNCTIONS", + "", + " // Splitting not on a delimiter, but whenever the relationship between", + " // two consecutive items matches a supplied predicate function", + "", + " // splitBy :: (a -> a -> Bool) -> [a] -> [[a]]", + " var splitBy = function (f, xs) {", + " if (xs.length < 2) return [xs];", + " var h = head(xs),", + " lstParts = xs.slice(1)", + " .reduce(function (a, x) {", + " var acc = a[0],", + " active = a[1],", + " prev = a[2];", + "", + " return f(prev, x) ? (", + " [acc.concat([active]), [x], x]", + " ) : [acc, active.concat(x), x];", + " }, [", + " [],", + " [h], h", + " ]);", + " return lstParts[0].concat([lstParts[1]]);", + " };", + "", + " // head :: [a] -> a", + " var head = function (xs) {", + " return xs.length ? xs[0] : undefined;", + " };", + "", + " // last :: [a] -> a", + " var last = function (xs) {", + " return xs.length ? xs.slice(-1)[0] : undefined;", + " };", + "", + " // show :: a -> String", + " var show = function (x) {", + " return JSON.stringify(x);", + " };", + "", + " // TEST", + " return rangeFormat([0, 1, 2, 4, 6, 7, 8, 11, 12, 14, 15, 16,", + " 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32,", + " 33, 35, 36, 37, 38, 39", + " ]);", + "})();", + "", + "{{Out}}", + "
\"0-2,4,6-8,11,12,14-25,27-33,35-39\"
", + "", + "===ES6===", + "{{Trans|Haskell}}", + "Defining the range format in terms of a reusable '''splitBy''' function:", + "(() => {", + " 'use strict';", + "", + " // rangeFormat :: [Int] -> String", + " const rangeFormat = xs =>", + " splitBy((a, b) => b - a > 1, xs)", + " .map(rangeString)", + " .join(',');", + "", + " // rangeString :: [Int] -> String", + " const rangeString = xs =>", + " xs.length > 2 ? (", + " [head(xs), last(xs)].map(show)", + " .join('-')", + " ) : xs.join(',')", + "", + "", + " // GENERIC FUNCTIONS", + "", + " // Splitting not on a delimiter, but whenever the relationship between", + " // two consecutive items matches a supplied predicate function", + "", + " // splitBy :: (a -> a -> Bool) -> [a] -> [[a]]", + " const splitBy = (f, xs) => {", + " if (xs.length < 2) return [xs];", + " const", + " h = head(xs),", + " lstParts = xs.slice(1)", + " .reduce(([acc, active, prev], x) =>", + " f(prev, x) ? (", + " [acc.concat([active]), [x], x]", + " ) : [acc, active.concat(x), x], [", + " [],", + " [h],", + " h", + " ]);", + " return lstParts[0].concat([lstParts[1]]);", + " };", + "", + " // head :: [a] -> a", + " const head = xs => xs.length ? xs[0] : undefined;", + "", + " // last :: [a] -> a", + " const last = xs => xs.length ? xs.slice(-1)[0] : undefined;", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x);", + "", + " // TEST", + " return rangeFormat([0, 1, 2, 4, 6, 7, 8, 11, 12, 14,", + " 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,", + " 25, 27, 28, 29, 30, 31, 32, 33, 35, 36,", + " 37, 38, 39", + " ]);", + "})();", + "{{Out}}", + "
0-2,4,6-8,11,12,14-25,27-33,35-39
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f9c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function rangeExtraction(list) {\n var len = list.length;\n var out = [];\n var i, j;\n\n for (i = 0; i < len; i = j + 1) {\n // beginning of range or single\n out.push(list[i]);\n \n // find end of range\n for (var j = i + 1; j < len && list[j] == list[j-1] + 1; j++);\n j--;\n \n if (i == j) {\n // single number\n out.push(\",\");\n } else if (i + 1 == j) {\n // two numbers\n out.push(\",\", list[j], \",\");\n } else { \n // range\n out.push(\"-\", list[j], \",\");\n }\n }\n out.pop(); // remove trailing comma\n return out.join(\"\");\n}\n\n// using print function as supplied by Rhino standalone\nprint(rangeExtraction([\n 0, 1, 2, 4, 6, 7, 8, 11, 12, 14,\n 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\n 25, 27, 28, 29, 30, 31, 32, 33, 35, 36,\n 37, 38, 39\n]));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Ranking methods", + "type": "Waypoint", + "description": [ + "

The numerical rank of competitors in a competition shows if one is better than, equal to, or worse than another based on their results in a competition.

The numerical rank of a competitor can be assigned in several different ways.

", + "Task:", + "

The following scores are accrued for all competitors of a competition (in best-first order):

", + "
44 Solomon",
+      "42 Jason",
+      "42 Errol",
+      "41 Garry",
+      "41 Bernard",
+      "41 Barry",
+      "39 Stephen

For each of the following ranking methods, create a function/method/procedure/subroutine... that applies the ranking method to an ordered list of scores with scorers:

", + "Standard. (Ties share what would have been their first ordinal number).", + "Modified. (Ties share what would have been their last ordinal number).", + "Dense. (Ties share the next available integer). ", + "Ordinal. ((Competitors take the next available integer. Ties are not treated otherwise).", + "Fractional. (Ties share the mean of what would have been their ordinal numbers).", + "

See the wikipedia article for a fuller description.

Show here, on this page, the ranking of the test scores under each of the numbered ranking methods.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "The task formulation doesn't seem to directly explain or determine the order of listing for players whose score is the same.", + "", + "( This version chooses to use a secondary (alphabetic) sort after the numeric sort by score. That does, of course, affect the ordinal placements for some players)", + "", + "(function () {", + " ", + " var xs = 'Solomon Jason Errol Garry Bernard Barry Stephen'.split(' '),", + " ns = [44, 42, 42, 41, 41, 41, 39],", + " ", + " sorted = xs.map(function (x, i) {", + " return { name: x, score: ns[i] };", + " }).sort(function (a, b) {", + " var c = b.score - a.score;", + " return c ? c : a.name < b.name ? -1 : a.name > b.name ? 1 : 0;", + " }),", + " ", + " names = sorted.map(function (x) { return x.name; }),", + " scores = sorted.map(function (x) { return x.score; }),", + " ", + " reversed = scores.slice(0).reverse(),", + " unique = scores.filter(function (x, i) {", + " return scores.indexOf(x) === i;", + " });", + " ", + " // RANKINGS AS FUNCTIONS OF SCORES: SORTED, REVERSED AND UNIQUE", + " ", + " var rankings = function (score, index) {", + " return {", + " name: names[index],", + " score: score,", + "", + " Ordinal: index + 1,", + "", + " Standard: function (n) {", + " return scores.indexOf(n) + 1;", + " }(score),", + "", + " Modified: function (n) {", + " return reversed.length - reversed.indexOf(n);", + " }(score),", + "", + " Dense: function (n) {", + " return unique.indexOf(n) + 1;", + " }(score),", + "", + " Fractional: function (n) {", + " return (", + " (scores.indexOf(n) + 1) +", + " (reversed.length - reversed.indexOf(n))", + " ) / 2;", + " }(score)", + " };", + " },", + " ", + " tbl = [", + " 'Name Score Standard Modified Dense Ordinal Fractional'.split(' ')", + " ].concat(scores.map(rankings).reduce(function (a, x) {", + " return a.concat([", + " [x.name, x.score,", + " x.Standard, x.Modified, x.Dense, x.Ordinal, x.Fractional", + " ]", + " ]);", + " }, [])),", + " ", + " //[[a]] -> bool -> s -> s", + " wikiTable = function (lstRows, blnHeaderRow, strStyle) {", + " return '{| class=\"wikitable\" ' + (", + " strStyle ? 'style=\"' + strStyle + '\"' : ''", + " ) + lstRows.map(function (lstRow, iRow) {", + " var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');", + " ", + " return '\\n|-\\n' + strDelim + ' ' + lstRow.map(function (v) {", + " return typeof v === 'undefined' ? ' ' : v;", + " }).join(' ' + strDelim + strDelim + ' ');", + " }).join('') + '\\n|}';", + " };", + " ", + " return wikiTable(tbl, true, 'text-align:center');", + " ", + "})();", + "", + "{{out}}", + "", + "{| class=\"wikitable\" style=\"text-align:center\"", + "|-", + "! Name !! Score !! Standard !! Modified !! Dense !! Ordinal !! Fractional", + "|-", + "| Solomon || 44 || 1 || 1 || 1 || 1 || 1", + "|-", + "| Errol || 42 || 2 || 3 || 2 || 2 || 2.5", + "|-", + "| Jason || 42 || 2 || 3 || 2 || 3 || 2.5", + "|-", + "| Barry || 41 || 4 || 6 || 3 || 4 || 5", + "|-", + "| Bernard || 41 || 4 || 6 || 3 || 5 || 5", + "|-", + "| Garry || 41 || 4 || 6 || 3 || 6 || 5", + "|-", + "| Stephen || 39 || 7 || 7 || 4 || 7 || 7", + "|}", + "", + "===ES6===", + "", + "((() => {", + " const xs = 'Solomon Jason Errol Garry Bernard Barry Stephen'.split(' '),", + " ns = [44, 42, 42, 41, 41, 41, 39];", + "", + " const sorted = xs.map((x, i) => ({", + " name: x,", + " score: ns[i]", + " }))", + " .sort((a, b) => {", + " const c = b.score - a.score;", + " return c ? c : a.name < b.name ? -1 : a.name > b.name ? 1 : 0;", + " });", + "", + " const names = sorted.map(x => x.name),", + " scores = sorted.map(x => x.score),", + " reversed = scores.slice(0)", + " .reverse(),", + " unique = scores.filter((x, i) => scores.indexOf(x) === i);", + "", + " // RANKINGS AS FUNCTIONS OF SCORES: SORTED, REVERSED AND UNIQUE", + "", + " // rankings :: Int -> Int -> Dictonary", + " const rankings = (score, index) => ({", + " name: names[index],", + " score,", + " Ordinal: index + 1,", + " Standard: scores.indexOf(score) + 1,", + " Modified: reversed.length - reversed.indexOf(score),", + " Dense: unique.indexOf(score) + 1,", + "", + " Fractional: (n => (", + " (scores.indexOf(n) + 1) +", + " (reversed.length - reversed.indexOf(n))", + " ) / 2)(score)", + " });", + "", + " // tbl :: [[[a]]]", + " const tbl = [", + " 'Name Score Standard Modified Dense Ordinal Fractional'.split(' ')", + " ].concat(scores.map(rankings)", + " .reduce((a, x) => a.concat([", + " [x.name, x.score,", + " x.Standard, x.Modified, x.Dense, x.Ordinal, x.Fractional", + " ]", + " ]), []));", + "", + " // wikiTable :: [[[a]]] -> Bool -> String -> String", + " const wikiTable = (lstRows, blnHeaderRow, strStyle) =>", + " `{| class=\"wikitable\" ${strStyle ? 'style=\"' + strStyle + '\"' : ''}", + " ${lstRows.map((lstRow, iRow) => {", + " const strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');", + "", + " return '\\n|-\\n' + strDelim + ' ' + lstRow", + " .map(v => typeof v === 'undefined' ? ' ' : v)", + " .join(' ' + strDelim + strDelim + ' ');", + " }).join('')}\\n|}`;", + "", + " return wikiTable(tbl, true, 'text-align:center');", + "}))();", + "", + "{| class=\"wikitable\" style=\"text-align:center\"", + " ", + "|-", + "! Name !! Score !! Standard !! Modified !! Dense !! Ordinal !! Fractional", + "|-", + "| Solomon || 44 || 1 || 1 || 1 || 1 || 1", + "|-", + "| Errol || 42 || 2 || 3 || 2 || 2 || 2.5", + "|-", + "| Jason || 42 || 2 || 3 || 2 || 3 || 2.5", + "|-", + "| Barry || 41 || 4 || 6 || 3 || 4 || 5", + "|-", + "| Bernard || 41 || 4 || 6 || 3 || 5 || 5", + "|-", + "| Garry || 41 || 4 || 6 || 3 || 6 || 5", + "|-", + "| Stephen || 39 || 7 || 7 || 4 || 7 || 7", + "|}", + "{{Out}}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f9d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function () {\n \n var xs = 'Solomon Jason Errol Garry Bernard Barry Stephen'.split(' '),\n ns = [44, 42, 42, 41, 41, 41, 39],\n \n sorted = xs.map(function (x, i) {\n return { name: x, score: ns[i] };\n }).sort(function (a, b) {\n var c = b.score - a.score;\n return c ? c : a.name < b.name ? -1 : a.name > b.name ? 1 : 0;\n }),\n \n names = sorted.map(function (x) { return x.name; }),\n scores = sorted.map(function (x) { return x.score; }),\n \n reversed = scores.slice(0).reverse(),\n unique = scores.filter(function (x, i) {\n return scores.indexOf(x) === i;\n });\n \n // RANKINGS AS FUNCTIONS OF SCORES: SORTED, REVERSED AND UNIQUE\n \n var rankings = function (score, index) {\n return {\n name: names[index],\n score: score,\n\n Ordinal: index + 1,\n\n Standard: function (n) {\n return scores.indexOf(n) + 1;\n }(score),\n\n Modified: function (n) {\n return reversed.length - reversed.indexOf(n);\n }(score),\n\n Dense: function (n) {\n return unique.indexOf(n) + 1;\n }(score),\n\n Fractional: function (n) {\n return (\n (scores.indexOf(n) + 1) +\n (reversed.length - reversed.indexOf(n))\n ) / 2;\n }(score)\n };\n },\n \n tbl = [\n 'Name Score Standard Modified Dense Ordinal Fractional'.split(' ')\n ].concat(scores.map(rankings).reduce(function (a, x) {\n return a.concat([\n [x.name, x.score,\n x.Standard, x.Modified, x.Dense, x.Ordinal, x.Fractional\n ]\n ]);\n }, [])),\n \n //[[a]] -> bool -> s -> s\n wikiTable = function (lstRows, blnHeaderRow, strStyle) {\n return '{| class=\"wikitable\" ' + (\n strStyle ? 'style=\"' + strStyle + '\"' : ''\n ) + lstRows.map(function (lstRow, iRow) {\n var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');\n \n return '\\n|-\\n' + strDelim + ' ' + lstRow.map(function (v) {\n return typeof v === 'undefined' ? ' ' : v;\n }).join(' ' + strDelim + strDelim + ' ');\n }).join('') + '\\n|}';\n };\n \n return wikiTable(tbl, true, 'text-align:center');\n \n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Rate counter", + "type": "Waypoint", + "description": [ + "

Counting the frequency at which something occurs is a common activity in measuring performance and managing resources. In this task, we assume that there is some job which we want to perform repeatedly, and we want to know how quickly these jobs are being performed.

Of interest is the code that performs the actual measurements. Any other code (such as job implementation or dispatching) that is required to demonstrate the rate tracking is helpful, but not the focus.

Multiple approaches are allowed (even preferable), so long as they can accomplish these goals:

Run N seconds worth of jobs and/or Y jobs.", + "Report at least three distinct times.", + "Be aware of the precision and accuracy limitations of your timing mechanisms, and document them if you can.

See also: System time, Time a function

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "The ''benchmark'' function below executes a given function n times, calling it with the specified arguments. After execution of all functions, it returns an array with the execution time of each execution, in milliseconds.", + "", + "function millis() { // Gets current time in milliseconds.", + " return (new Date()).getTime();", + "}", + "", + "/* Executes function 'func' n times, returns array of execution times. */", + "function benchmark(n, func, args) {", + " var times = [];", + " for (var i=0; i", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f9e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function millis() { // Gets current time in milliseconds.\n return (new Date()).getTime();\n}\n\n/* Executes function 'func' n times, returns array of execution times. */\nfunction benchmark(n, func, args) {\n var times = [];\n for (var i=0; ireplaceMe is a function.');" + ] + }, + { + "title": "Ray-casting algorithm", + "type": "Waypoint", + "description": [ + "

Given a point and a polygon, check if the point is inside or outside the polygon using the ray-casting algorithm.

A pseudocode can be simply:

count ← 0

", + "

foreach side in polygon:

", + "

if ray_intersects_segment(P,side) then

", + "

count ← count + 1

", + "

if is_odd(count) then

", + "

return inside

", + "

else

", + "

return outside

Where the function ray_intersects_segment return true if the horizontal ray starting from the point P intersects the side (segment), false otherwise.

An intuitive explanation of why it works is that every time we cross

", + "

a border, we change \"country\" (inside-outside, or outside-inside), but

", + "

the last \"country\" we land on is surely outside (since the inside of the polygon is finite, while the ray continues towards infinity). So, if we crossed an odd number of borders we were surely inside, otherwise we were outside; we can follow the ray backward to see it better: starting from outside, only an odd number of crossing can give an inside: outside-inside, outside-inside-outside-inside, and so on (the - represents the crossing of a border).

So the main part of the algorithm is how we determine if a ray intersects a segment. The following text explain one of the possible ways.

200px|thumb|right

", + "

Looking at the image on the right, we can easily be convinced of the fact that rays starting from points in the hatched area (like P1 and P2) surely do not intersect the segment AB. We also can easily see that rays starting from points in the greenish area surely intersect the segment AB (like point P3).

So the problematic points are those inside the white area (the box delimited by the points A and B), like P4.

128px|thumb|right

", + "

128px|thumb|right

Let us take into account a segment AB (the point A having y coordinate always smaller than B's y coordinate, i.e. point A is always below point B) and a point P. Let us use the cumbersome notation PAX to denote the angle between segment AP and AX, where X is always a point on the horizontal line passing by A with x coordinate bigger than the maximum between the x coordinate of A and the x coordinate of B. As explained graphically by the figures on the right, if PAX is greater than the angle BAX, then the ray starting from P intersects the segment AB. (In the images, the ray starting from PA does not intersect the segment, while the ray starting from PB in the second picture, intersects the segment).

Points on the boundary or \"on\" a vertex are someway special and through this approach we do not obtain coherent results. They could be treated apart, but it is not necessary to do so.

An algorithm for the previous speech could be (if P is a point, Px is its x coordinate):

ray_intersects_segment:

", + "

P : the point from which the ray starts

", + "

A : the end-point of the segment with the smallest y coordinate

", + "

(A must be \"below\" B)

", + "

B : the end-point of the segment with the greatest y coordinate

", + "

(B must be \"above\" A)

", + "

if Py = Ay or Py = By then

", + "

Py ← Py + ε

", + "

end if

", + "

if Py < Ay or Py > By then

", + "

return false

", + "

else if Px > max(Ax, Bx) then

", + "

return false

", + "

else

", + "

if Px < min(Ax, Bx) then

", + "

return true

", + "

else

", + "

if Ax ≠ Bx then

", + "

m_red ← (By - Ay)/(Bx - Ax)

", + "

else

", + "

m_red ← ∞

", + "

end if

", + "

if Ax ≠ Px then

", + "

m_blue ← (Py - Ay)/(Px - Ax)

", + "

else

", + "

m_blue ← ∞

", + "

end if

", + "

if m_blue ≥ m_red then

", + "

return true

", + "

else

", + "

return false

", + "

end if

", + "

end if

", + "

end if

(To avoid the \"ray on vertex\" problem, the point is moved upward of a small quantity ε.)

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7f9f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "RCRPG", + "type": "Waypoint", + "description": [ + "

Create a simple interactive game which incorporates the following features:

room-based navigation in three integer dimensions (x,y,z)", + "player inventory", + "three types of item: sledge, gold and ladder", + "a goal coordinate", + "

Use of the sledge should be required to create a passage between rooms. The ladder should be present in a room (but not held by the player), in order for the player to access the room above him. The gold need not have a function.

This project is based on this blog post by Michael Mol, and the Perl version comes from there.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fa0", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Real constants and functions", + "type": "Waypoint", + "description": [ + "Task:", + "

Show how to use the following math constants and functions in your language (if not available, note it):

", + "

* e (base of the natural logarithm)

", + "

* $\\pi$

", + "

* square root

", + "

* logarithm (any base allowed)

", + "

* exponential (ex )

", + "

* absolute value (a.k.a. \"magnitude\")

", + "

* floor (largest integer less than or equal to this number--not the same as truncate or int)

", + "

* ceiling (smallest integer not less than this number--not the same as round up)

", + "

* power (xy )

", + "Related task:", + " Trigonometric Functions" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Math.E", + "Math.PI", + "Math.sqrt(x)", + "Math.log(x)", + "Math.exp(x)", + "Math.abs(x)", + "Math.floor(x)", + "Math.ceil(x)", + "Math.pow(x,y)", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fa5", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "Math.E\nMath.PI\nMath.sqrt(x)\nMath.log(x)\nMath.exp(x)\nMath.abs(x)\nMath.floor(x)\nMath.ceil(x)\nMath.pow(x,y)\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Reduced row echelon form", + "type": "Waypoint", + "description": [ + "

Show how to compute the reduced row echelon form

", + "

(a.k.a. row canonical form) of a matrix.

The matrix can be stored in any datatype that is convenient

", + "

(for most languages, this will probably be a two-dimensional array).

Built-in functions or this pseudocode (from Wikipedia) may be used:

", + "

function ToReducedRowEchelonForm(Matrix M) is

", + "

lead := 0

", + "

rowCount := the number of rows in M

", + "

columnCount := the number of columns in M

", + "

for 0 ≤ r < rowCount do

", + "

if columnCount ≤ lead then

", + "

stop

", + "

end if

", + "

i = r

", + "

while M[i, lead] = 0 do

", + "

i = i + 1

", + "

if rowCount = i then

", + "

i = r

", + "

lead = lead + 1

", + "

if columnCount = lead then

", + "

stop

", + "

end if

", + "

end if

", + "

end while

", + "

Swap rows i and r

", + "

If M[r, lead] is not 0 divide row r by M[r, lead]

", + "

for 0 ≤ i < rowCount do

", + "

if i ≠ r do

", + "

Subtract M[i, lead] multiplied by row r from row i

", + "

end if

", + "

end for

", + "

lead = lead + 1

", + "

end for

", + "

end function

For testing purposes, the RREF of this matrix:

", + "
1   2   -1   -4",
+      "2   3   -1   -11",
+      "-2   0   -3   22
", + "

is:

", + "
1   0   0   -8",
+      "0   1   0   1",
+      "0   0   1   -2
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|SpiderMonkey}} for the print() function.", + "Extends the Matrix class defined at [[Matrix Transpose#JavaScript]]", + "// modifies the matrix in-place", + "Matrix.prototype.toReducedRowEchelonForm = function() {", + " var lead = 0;", + " for (var r = 0; r < this.rows(); r++) {", + " if (this.columns() <= lead) {", + " return;", + " }", + " var i = r;", + " while (this.mtx[i][lead] == 0) {", + " i++;", + " if (this.rows() == i) {", + " i = r;", + " lead++;", + " if (this.columns() == lead) {", + " return;", + " }", + " }", + " }", + "", + " var tmp = this.mtx[i];", + " this.mtx[i] = this.mtx[r];", + " this.mtx[r] = tmp;", + "", + " var val = this.mtx[r][lead];", + " for (var j = 0; j < this.columns(); j++) {", + " this.mtx[r][j] /= val;", + " }", + "", + " for (var i = 0; i < this.rows(); i++) {", + " if (i == r) continue;", + " val = this.mtx[i][lead];", + " for (var j = 0; j < this.columns(); j++) {", + " this.mtx[i][j] -= val * this.mtx[r][j];", + " }", + " }", + " lead++;", + " }", + " return this;", + "}", + "", + "var m = new Matrix([", + " [ 1, 2, -1, -4],", + " [ 2, 3, -1,-11],", + " [-2, 0, -3, 22]", + "]);", + "print(m.toReducedRowEchelonForm());", + "print();", + "", + "m = new Matrix([", + " [ 1, 2, 3, 7],", + " [-4, 7,-2, 7],", + " [ 3, 3, 0, 7]", + "]);", + "print(m.toReducedRowEchelonForm());", + "{{out}}", + "
1,0,0,-8",
+      "0,1,0,1",
+      "0,0,1,-2",
+      "",
+      "1,0,0,0.6666666666666663",
+      "0,1,0,1.666666666666667",
+      "0,0,1,1
", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fa7", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// modifies the matrix in-place\nMatrix.prototype.toReducedRowEchelonForm = function() {\n var lead = 0;\n for (var r = 0; r < this.rows(); r++) {\n if (this.columns() <= lead) {\n return;\n }\n var i = r;\n while (this.mtx[i][lead] == 0) {\n i++;\n if (this.rows() == i) {\n i = r;\n lead++;\n if (this.columns() == lead) {\n return;\n }\n }\n }\n\n var tmp = this.mtx[i];\n this.mtx[i] = this.mtx[r];\n this.mtx[r] = tmp;\n\n var val = this.mtx[r][lead];\n for (var j = 0; j < this.columns(); j++) {\n this.mtx[r][j] /= val;\n }\n\n for (var i = 0; i < this.rows(); i++) {\n if (i == r) continue;\n val = this.mtx[i][lead];\n for (var j = 0; j < this.columns(); j++) {\n this.mtx[i][j] -= val * this.mtx[r][j];\n }\n }\n lead++;\n }\n return this;\n}\n\nvar m = new Matrix([\n [ 1, 2, -1, -4],\n [ 2, 3, -1,-11],\n [-2, 0, -3, 22]\n]);\nprint(m.toReducedRowEchelonForm());\nprint();\n\nm = new Matrix([\n [ 1, 2, 3, 7],\n [-4, 7,-2, 7],\n [ 3, 3, 0, 7]\n]);\nprint(m.toReducedRowEchelonForm());\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Regular expressions", + "type": "Waypoint", + "description": [ + "

The goal of this task is

", + "to match a string against a regular expression", + "to substitute part of a string using a regular expression" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Test/Match", + "var subject = \"Hello world!\";", + "", + "// Two different ways to create the RegExp object", + "// Both examples use the exact same pattern... matching \"hello \"", + "var re_PatternToMatch = /Hello (World)/i; // creates a RegExp literal with case-insensitivity", + "var re_PatternToMatch2 = new RegExp(\"Hello (World)\", \"i\");", + "", + "// Test for a match - return a bool", + "var isMatch = re_PatternToMatch.test(subject);", + "", + "// Get the match details", + "// Returns an array with the match's details", + "// matches[0] == \"Hello world\"", + "// matches[1] == \"world\"", + "var matches = re_PatternToMatch2.exec(subject);", + "", + "Substitute", + "var subject = \"Hello world!\";", + "", + "// Perform a string replacement", + "// newSubject == \"Replaced!\"", + "var newSubject = subject.replace(re_PatternToMatch, \"Replaced\");", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fab", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var subject = \"Hello world!\";\n\n// Two different ways to create the RegExp object\n// Both examples use the exact same pattern... matching \"hello \"\nvar re_PatternToMatch = /Hello (World)/i; // creates a RegExp literal with case-insensitivity\nvar re_PatternToMatch2 = new RegExp(\"Hello (World)\", \"i\");\n\n// Test for a match - return a bool\nvar isMatch = re_PatternToMatch.test(subject);\n\n// Get the match details\n// Returns an array with the match's details\n// matches[0] == \"Hello world\"\n// matches[1] == \"world\"\nvar matches = re_PatternToMatch2.exec(subject);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Remove duplicate elements", + "type": "Waypoint", + "description": [ + "

Given an Array, derive a sequence of elements in which all duplicates are removed.

There are basically three approaches seen here:

", + "Put the elements into a hash table which does not allow duplicates. The complexity is O(n) on average, and O(n2) worst case. This approach requires a hash function for your type (which is compatible with equality), either built-in to your language, or provided by the user.", + "Sort the elements and remove consecutive duplicate elements. The complexity of the best sorting algorithms is O(n log n). This approach requires that your type be \"comparable\", i.e., have an ordering. Putting the elements into a self-balancing binary search tree is a special case of sorting.", + "Go through the list, and for each element, check the rest of the list to see if it appears again, and discard it if it does. The complexity is O(n2). The up-shot is that this always works on any type (provided that you can test for equality)." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "This uses the === \"strict equality\" operator, which does no type conversions (4 == \"4\" is true but 4 === \"4\" is false)", + "function unique(ary) {", + " // concat() with no args is a way to clone an array", + " var u = ary.concat().sort();", + " for (var i = 1; i < u.length; ) {", + " if (u[i-1] === u[i])", + " u.splice(i,1);", + " else", + " i++;", + " }", + " return u;", + "}", + "", + "var ary = [1, 2, 3, \"a\", \"b\", \"c\", 2, 3, 4, \"b\", \"c\", \"d\", \"4\"];", + "var uniq = unique(ary);", + "for (var i = 0; i < uniq.length; i++) ", + " print(uniq[i] + \"\\t\" + typeof(uniq[i]));", + "
1 - number",
+      "2 - number",
+      "3 - number",
+      "4 - number",
+      "4 - string",
+      "a - string",
+      "b - string",
+      "c - string",
+      "d - string
", + "", + "Or, extend the prototype for Array:", + "Array.prototype.unique = function() {", + " var u = this.concat().sort();", + " for (var i = 1; i < u.length; ) {", + " if (u[i-1] === u[i])", + " u.splice(i,1);", + " else", + " i++;", + " }", + " return u;", + "}", + "var uniq = [1, 2, 3, \"a\", \"b\", \"c\", 2, 3, 4, \"b\", \"c\", \"d\"].unique();", + "", + "With reduce and arrow functions (ES6):", + "Array.prototype.unique = function() {", + " return this.sort().reduce( (a,e) => e === a[a.length-1] ? a : (a.push(e), a), [] )", + "}", + "", + "With sets and spread operator (ES6):", + "Array.prototype.unique = function() {", + " return [... new Set(this)]", + "}", + "", + "If, however, the array is homogenous, or we wish to interpret it as such by using JavaScript's Abstract Equality comparison (as in '==', see http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3) then it proves significantly faster to use a hash table.", + "", + "For example, in ES 5:", + "", + "function uniq(lst) {", + " var u = [],", + " dct = {},", + " i = lst.length,", + " v;", + "", + " while (i--) {", + " v = lst[i], dct[v] || (", + " dct[v] = u.push(v)", + " );", + " }", + " u.sort(); // optional", + " ", + " return u;", + "}", + "", + "Or, to allow for customised definitions of equality and duplication, we can follow the Haskell prelude in defining a '''nub :: [a] -> [a] function''' which is a special case of '''nubBy :: (a -> a -> Bool) -> [a] -> [a]'''", + "", + "{{trans|Haskell}}", + "", + "(function () {", + " 'use strict';", + "", + " // nub :: [a] -> [a]", + " function nub(xs) {", + "", + " // Eq :: a -> a -> Bool", + " function Eq(a, b) {", + " return a === b;", + " }", + "", + " // nubBy :: (a -> a -> Bool) -> [a] -> [a]", + " function nubBy(fnEq, xs) {", + " var x = xs.length ? xs[0] : undefined;", + "", + " return x !== undefined ? [x].concat(", + " nubBy(fnEq, xs.slice(1)", + " .filter(function (y) {", + " return !fnEq(x, y);", + " }))", + " ) : [];", + " }", + "", + " return nubBy(Eq, xs);", + " }", + "", + "", + " // TEST", + " ", + " return [", + " nub('4 3 2 8 0 1 9 5 1 7 6 3 9 9 4 2 1 5 3 2'.split(' '))", + " .map(function (x) {", + " return Number(x);", + " }),", + " nub('chthonic eleemosynary paronomasiac'.split(''))", + " .join('')", + " ]", + "", + "})();", + "", + "{{Out}}", + "", + "
[[4, 3, 2, 8, 0, 1, 9, 5, 7, 6], \"chtoni elmsyarp\"]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fac", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function unique(ary) {\n // concat() with no args is a way to clone an array\n var u = ary.concat().sort();\n for (var i = 1; i < u.length; ) {\n if (u[i-1] === u[i])\n u.splice(i,1);\n else\n i++;\n }\n return u;\n}\n\nvar ary = [1, 2, 3, \"a\", \"b\", \"c\", 2, 3, 4, \"b\", \"c\", \"d\", \"4\"];\nvar uniq = unique(ary);\nfor (var i = 0; i < uniq.length; i++) \n print(uniq[i] + \"\\t\" + typeof(uniq[i]));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Rendezvous", + "type": "Waypoint", + "description": [ + "

Demonstrate the “rendezvous” communications technique by implementing a printer monitor.

", + "

==Detailed Description of Programming Task==

", + "

Rendezvous is a synchronization mechanism based on procedural decomposition. Rendezvous is similar to a procedure call with the difference that the caller and the callee belong to different tasks. The called procedure is usually called an entry point of the corresponding task. A call to an entry point is synchronous, i.e. the caller is blocked until completion. For the caller a call to the entry point is indivisible. Internally it consists of:

Waiting for the callee ready to accept the rendezvous;", + "Engaging the rendezvous (servicing the entry point).", + "

The caller may limit the waiting time to the callee to accept the rendezvous. I.e. a rendezvous request can be aborted if not yet accepted by the callee. When accepted the rendezvous is processed until its completion. During this time the caller and the callee tasks stay synchronized. Which context is used to process the rendezvous depends on the implementation which may wish to minimize context switching.

The callee task may accept several rendezvous requests:

Rendezvous to the same entry point from different tasks;", + "Rendezvous to different entry points.", + "

The callee accepts one rendezvous at a time.

Language mechanism of exceptions (if any) has to be consistent with the rendezvous. In particular when an exception is propagated out of a rendezvous it shall do in both tasks. The exception propagation is synchronous within the rendezvous and asynchronous outside it.

An engaged rendezvous can be requeued by the callee to another entry point of its task or to another task, transparently to the caller.

Differently to messages which are usually asynchronous, rendezvous are synchronous, as it was stated before. Therefore a rendezvous does not require marshaling the parameters and a buffer to keep them. Further, rendezvous can be implemented without context switch. This makes rendezvous a more efficient than messaging.

Rendezvous can be used to implement monitor synchronization objects. A monitor guards a shared resource. All users of the resource request a rendezvous to the monitor in order to get access to the resource. Access is granted by accepting the rendezvous for the time while the rendezvous is serviced.

===Language task===

", + "

Show how rendezvous are supported by the language. If the language does not have rendezvous, provide an implementation of them based on other primitives.

===Use case task===

", + "

Implement a printer monitor. The monitor guards a printer. There are two printers main and reserve. Each has a monitor that accepts a rendezvous Print with a text line to print of the printer. The standard output may serve for printing purpose. Each character of the line is printed separately in order to illustrate that lines are printed indivisibly. Each printer has ink for only 5 lines of text. When the main printer runs out of ink it redirects its requests to the reserve printer. When that runs out of ink too, Out_Of_Ink exception propagates back to the caller. Create two writer tasks which print their plagiarisms on the printer. One does Humpty Dumpty, another Mother Goose.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7faf", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Rep-string", + "type": "Waypoint", + "description": [ + "

Given a series of ones and zeroes in a string, define a repeated string or rep-string as a string which is created by repeating a substring of the first N characters of the string truncated on the right to the length of the input string, and in which the substring appears repeated at least twice in the original.

For example, the string 10011001100 is a rep-string as the leftmost four characters of 1001 are repeated three times and truncated on the right to give the original string.

Note that the requirement for having the repeat occur two or more times means that the repeating unit is never longer than half the length of the input string.

", + "Task:", + "Write a function/subroutine/method/... that takes a string and returns an indication of if it is a rep-string and the repeated string. (Either the string that is repeated, or the number of repeated characters would suffice). ", + "There may be multiple sub-strings that make a string a rep-string - in that case an indication of all, or the longest, or the shortest would suffice.", + "Use the function to indicate the repeating substring if any, in the following:
", + "
",
+      "1001110011",
+      "1110111011",
+      "0010010010",
+      "1010101010",
+      "1111111111",
+      "0100101101",
+      "0100100",
+      "101",
+      "11",
+      "00",
+      "1",
+      "
", + "Show your output on this page." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "(() => {", + " 'use strict';", + "", + " // REP-CYCLES -------------------------------------------------------------", + "", + " // repCycles :: String -> [String]", + " const repCycles = xs => {", + " const n = xs.length;", + " return filter(", + " cs => xs === takeCycle(n, cs),", + " map(concat, tail(inits(take(quot(n, 2), xs))))", + " );", + " };", + "", + " // cycleReport :: String -> [String]", + " const cycleReport = xs => {", + " const reps = repCycles(xs);", + " return [xs, isNull(reps) ? '(n/a)' : last(reps)];", + " };", + "", + "", + " // GENERIC ----------------------------------------------------------------", + "", + " // compose :: (b -> c) -> (a -> b) -> (a -> c)", + " const compose = (f, g) => x => f(g(x));", + "", + " // concat :: [[a]] -> [a] | [String] -> String", + " const concat = xs => {", + " if (xs.length > 0) {", + " const unit = typeof xs[0] === 'string' ? '' : [];", + " return unit.concat.apply(unit, xs);", + " } else return [];", + " };", + "", + " // cons :: a -> [a] -> [a]", + " const cons = (x, xs) => [x].concat(xs);", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " const curry = f => a => b => f(a, b);", + "", + " // filter :: (a -> Bool) -> [a] -> [a]", + " const filter = (f, xs) => xs.filter(f);", + "", + " // inits :: [a] -> [[a]]", + " // inits :: String -> [String]", + " const inits = xs => [", + " []", + " ]", + " .concat((typeof xs === 'string' ? xs.split('') : xs)", + " .map((_, i, lst) => lst.slice(0, i + 1)));", + "", + " // intercalate :: String -> [a] -> String", + " const intercalate = (s, xs) => xs.join(s);", + "", + " // last :: [a] -> a", + " const last = xs => xs.length ? xs.slice(-1)[0] : undefined;", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // isNull :: [a] -> Bool", + " const isNull = xs => (xs instanceof Array) ? xs.length < 1 : undefined;", + "", + " // Integral a => a -> a -> a", + " const quot = (n, m) => Math.floor(n / m);", + "", + " // replicate :: Int -> a -> [a]", + " const replicate = (n, a) => {", + " let v = [a],", + " o = [];", + " if (n < 1) return o;", + " while (n > 1) {", + " if (n & 1) o = o.concat(v);", + " n >>= 1;", + " v = v.concat(v);", + " }", + " return o.concat(v);", + " };", + "", + " // tail :: [a] -> [a]", + " const tail = xs => xs.length ? xs.slice(1) : undefined;", + "", + " // take :: Int -> [a] -> [a]", + " const take = (n, xs) => xs.slice(0, n);", + "", + " // First n members of an infinite cycle of xs", + " // takeCycle :: Int -> [a] -> [a]", + " const takeCycle = (n, xs) => {", + " const lng = xs.length;", + " return concat((lng >= n ? xs : replicate(Math.ceil(n / lng), xs)))", + " .slice(0, n);", + " };", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + "", + " // TEST -------------------------------------------------------------------", + " const samples = [\"1001110011\", \"1110111011\", \"0010010010\", \"1010101010\",", + " \"1111111111\", \"0100101101\", \"0100100\", \"101\", \"11\", \"00\", \"1\"", + " ];", + "", + " return unlines(cons('Longest cycle:\\n',", + " map(compose(curry(intercalate)(' -> '), cycleReport), samples)));", + "})();", + "{{Out}}", + "
Longest cycle:",
+      "",
+      "1001110011 -> 10011",
+      "1110111011 -> 1110",
+      "0010010010 -> 001",
+      "1010101010 -> 1010",
+      "1111111111 -> 11111",
+      "0100101101 -> (n/a)",
+      "0100100 -> 010",
+      "101 -> (n/a)",
+      "11 -> 1",
+      "00 -> 0",
+      "1 -> (n/a)
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fb1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // REP-CYCLES -------------------------------------------------------------\n\n // repCycles :: String -> [String]\n const repCycles = xs => {\n const n = xs.length;\n return filter(\n cs => xs === takeCycle(n, cs),\n map(concat, tail(inits(take(quot(n, 2), xs))))\n );\n };\n\n // cycleReport :: String -> [String]\n const cycleReport = xs => {\n const reps = repCycles(xs);\n return [xs, isNull(reps) ? '(n/a)' : last(reps)];\n };\n\n\n // GENERIC ----------------------------------------------------------------\n\n // compose :: (b -> c) -> (a -> b) -> (a -> c)\n const compose = (f, g) => x => f(g(x));\n\n // concat :: [[a]] -> [a] | [String] -> String\n const concat = xs => {\n if (xs.length > 0) {\n const unit = typeof xs[0] === 'string' ? '' : [];\n return unit.concat.apply(unit, xs);\n } else return [];\n };\n\n // cons :: a -> [a] -> [a]\n const cons = (x, xs) => [x].concat(xs);\n\n // curry :: ((a, b) -> c) -> a -> b -> c\n const curry = f => a => b => f(a, b);\n\n // filter :: (a -> Bool) -> [a] -> [a]\n const filter = (f, xs) => xs.filter(f);\n\n // inits :: [a] -> [[a]]\n // inits :: String -> [String]\n const inits = xs => [\n []\n ]\n .concat((typeof xs === 'string' ? xs.split('') : xs)\n .map((_, i, lst) => lst.slice(0, i + 1)));\n\n // intercalate :: String -> [a] -> String\n const intercalate = (s, xs) => xs.join(s);\n\n // last :: [a] -> a\n const last = xs => xs.length ? xs.slice(-1)[0] : undefined;\n\n // map :: (a -> b) -> [a] -> [b]\n const map = (f, xs) => xs.map(f);\n\n // isNull :: [a] -> Bool\n const isNull = xs => (xs instanceof Array) ? xs.length < 1 : undefined;\n\n // Integral a => a -> a -> a\n const quot = (n, m) => Math.floor(n / m);\n\n // replicate :: Int -> a -> [a]\n const replicate = (n, a) => {\n let v = [a],\n o = [];\n if (n < 1) return o;\n while (n > 1) {\n if (n & 1) o = o.concat(v);\n n >>= 1;\n v = v.concat(v);\n }\n return o.concat(v);\n };\n\n // tail :: [a] -> [a]\n const tail = xs => xs.length ? xs.slice(1) : undefined;\n\n // take :: Int -> [a] -> [a]\n const take = (n, xs) => xs.slice(0, n);\n\n // First n members of an infinite cycle of xs\n // takeCycle :: Int -> [a] -> [a]\n const takeCycle = (n, xs) => {\n const lng = xs.length;\n return concat((lng >= n ? xs : replicate(Math.ceil(n / lng), xs)))\n .slice(0, n);\n };\n\n // unlines :: [String] -> String\n const unlines = xs => xs.join('\\n');\n\n\n // TEST -------------------------------------------------------------------\n const samples = [\"1001110011\", \"1110111011\", \"0010010010\", \"1010101010\",\n \"1111111111\", \"0100101101\", \"0100100\", \"101\", \"11\", \"00\", \"1\"\n ];\n\n return unlines(cons('Longest cycle:\\n',\n map(compose(curry(intercalate)(' -> '), cycleReport), samples)));\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Resistor mesh", + "type": "Waypoint", + "description": [ + "

300px||right

Task:", + "

Given 10×10 grid nodes (as shown in the image) interconnected by resistors as shown,

", + "find the resistance between point A and B.", + "See also:", + " (humor, nerd sniping) xkcd.com cartoon" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fb2", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Retrieve and search chat history", + "type": "Waypoint", + "description": [ + "Task:

Summary: Find and print the mentions of a given string in the recent chat logs from a chatroom. Only use your programming language's standard library.

Details:

The Tcl Chatroom is a online chatroom. Its conversations are logged. It is useful to know if some has mentioned you or your project in the chatroom recently. You can find this out by searching the chat logs. The logs are publicly available at http://tclers.tk/conferences/tcl/. One log file corresponds to the messages from one day in Germany's current time zone. Each chat log file has the name YYYY-MM-DD.tcl where YYYY is the year, MM is the month and DD the day. The logs store one message per line. The messages themselves are human-readable and their internal structure doesn't matter.

Retrieve the chat logs from the last 10 days via HTTP. Find those lines that include a particular substring and print them in the following format:

",
+      "------",
+      "",
+      "",
+      "...",
+      "",
+      "------

The substring will be given to your program as a command line argument.

You need to account for the possible time zone difference between the client running your program and the chat log writer on the server to not miss any mentions. (For example, if you generated the log file URLs naively based on the local date, you could miss mentions if it was already April 5th for the logger but only April 4th for the client.) What this means in practice is that you should either generate the URLs in the time zone Europe/Berlin or, if your language can not do that, add an extra day (today + 1) to the range of dates you check, but then make sure to not print parts of a \"not found\" page by accident if a log file doesn't exist yet.

The code should be contained in a single-file script, with no \"project\" or \"dependency\" file (e.g., no requirements.txt for Python). It should only use a given programming language's standard library to accomplish this task and not rely on the user having installed any third-party packages.

If your language does not have an HTTP client in the standard library, you can speak raw HTTP 1.0 to the server. If it can't parse command line arguments in a standalone script, read the string to look for from the standard input.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fb4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Reverse words in a string", + "type": "Waypoint", + "description": [ + "Task:", + "

Reverse the order of all tokens in each of a number of strings and display the result; the order of characters within a token should not be modified.

", + "Example:", + "

Hey you, Bub! would be shown reversed as: Bub! you, Hey

", + "

Tokens are any non-space characters separated by spaces (formally, white-space); the visible punctuation form part of the word within which it is located and should not be modified.

You may assume that there are no significant non-visible characters in the input. Multiple or superfluous spaces may be compressed into a single space.

Some strings have no tokens, so an empty string (or one just containing spaces) would be the result.

Display the strings in order (1st, 2nd, 3rd, ···), and one string per line.

(You can consider the ten strings as ten lines, and the tokens as words.)

", + "Input data", + "
",
+      "             (ten lines within the box)",
+      " line",
+      "     ╔════════════════════════════════════════╗",
+      "   1 ║  ---------- Ice and Fire ------------  ║",
+      "   2 ║                                        ║  ◄─── a blank line here.",
+      "   3 ║  fire, in end will world the say Some  ║",
+      "   4 ║  ice. in say Some                      ║",
+      "   5 ║  desire of tasted I've what From       ║",
+      "   6 ║  fire. favor who those with hold I     ║",
+      "   7 ║                                        ║  ◄─── a blank line here.",
+      "   8 ║  ... elided paragraph last ...         ║",
+      "   9 ║                                        ║  ◄─── a blank line here.",
+      "  10 ║  Frost Robert -----------------------  ║",
+      "     ╚════════════════════════════════════════╝",
+      "
Cf.", + "Phrase reversals" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var strReversed =", + "\"---------- Ice and Fire ------------\\n\\", + "\\n\\", + "fire, in end will world the say Some\\n\\", + "ice. in say Some\\n\\", + "desire of tasted I've what From\\n\\", + "fire. favor who those with hold I\\n\\", + "\\n\\", + "... elided paragraph last ...\\n\\", + "\\n\\", + "Frost Robert -----------------------\";", + " ", + "function reverseString(s) {", + " return s.split('\\n').map(", + " function (line) {", + " return line.split(/\\s/).reverse().join(' ');", + " }", + " ).join('\\n');", + "}", + " ", + "console.log(", + " reverseString(strReversed)", + ");", + "", + "Output:", + "
------------ Fire and Ice ----------",
+      "",
+      "Some say the world will end in fire,",
+      "Some say in ice.",
+      "From what I've tasted of desire",
+      "I hold with those who favor fire.",
+      "",
+      "... last paragraph elided ...",
+      "",
+      "----------------------- Robert Frost
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fb7", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var strReversed =\n\"---------- Ice and Fire ------------\\n\\\n\\n\\\nfire, in end will world the say Some\\n\\\nice. in say Some\\n\\\ndesire of tasted I've what From\\n\\\nfire. favor who those with hold I\\n\\\n\\n\\\n... elided paragraph last ...\\n\\\n\\n\\\nFrost Robert -----------------------\";\n \nfunction reverseString(s) {\n return s.split('\\n').map(\n function (line) {\n return line.split(/\\s/).reverse().join(' ');\n }\n ).join('\\n');\n}\n \nconsole.log(\n reverseString(strReversed)\n);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "RIPEMD-160", + "type": "Waypoint", + "description": [ + "

RIPEMD-160 is another hash function; it computes a 160-bit message digest.

There is a RIPEMD-160 home page, with test vectors and pseudocode for RIPEMD-160.

", + "

For padding the message, RIPEMD-160 acts like MD4 (RFC 1320).

Find the RIPEMD-160 message digest of a string of octets.

", + "

Use the ASCII encoded string “Rosetta Code”.

", + "

You may either call an RIPEMD-160 library, or implement RIPEMD-160 in your language.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fb8", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Roman numerals/Decode", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a function that takes a Roman numeral as its argument and returns its value as a numeric decimal integer.

You don't need to validate the form of the Roman numeral.

Modern Roman numerals are written by expressing each decimal digit of the number to be encoded separately,

", + "starting with the leftmost decimal digit and skipping any 0s (zeroes).

1990 is rendered as MCMXC (1000 = M, 900 = CM, 90 = XC) and

", + "2008 is rendered as MMVIII (2000 = MM, 8 = VIII).

The Roman numeral for 1666, MDCLXVI, uses each letter in descending order.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Imperative====", + "{{works with|Rhino}}", + "{{works with|SpiderMonkey}}", + "var Roman = {", + " Values: [['CM', 900], ['CD', 400], ['XC', 90], ['XL', 40], ['IV', 4], ", + " ['IX', 9], ['V', 5], ['X', 10], ['L', 50], ", + " ['C', 100], ['M', 1000], ['I', 1], ['D', 500]],", + " UnmappedStr : 'Q',", + " parse: function(str) {", + " var result = 0", + " for (var i=0; i", + "{{out}}", + "
MCMXC: 1990",
+      "MDCLXVI: 1666",
+      "MMVIII: 2008",
+      "
", + "====Functional====", + "{{Trans|Haskell}}", + "(isPrefixOf example)", + "(function (lstTest) {", + " ", + " var mapping = [[\"M\", 1000], [\"CM\", 900], [\"D\", 500], [\"CD\", 400], [\"C\", 100], [", + " \"XC\", 90], [\"L\", 50], [\"XL\", 40], [\"X\", 10], [\"IX\", 9], [\"V\", 5], [\"IV\",", + " 4], [\"I\", 1]];", + " ", + " // s -> n", + " function romanValue(s) {", + " // recursion over list of characters", + " // [c] -> n", + " function toArabic(lst) {", + " return lst.length ? function (xs) {", + " var lstParse = chain(mapping, function (lstPair) {", + " return isPrefixOf(", + " lstPair[0], xs", + " ) ? [lstPair[1], drop(lstPair[0].length, xs)] : []", + " });", + " return lstParse[0] + toArabic(lstParse[1]);", + " }(lst) : 0", + " }", + " return toArabic(s.split(''));", + " }", + " ", + " // Monadic bind (chain) for lists", + " function chain(xs, f) {", + " return [].concat.apply([], xs.map(f));", + " }", + " ", + " // [a] -> [a] -> Bool", + " function isPrefixOf(lstFirst, lstSecond) {", + " return lstFirst.length ? (", + " lstSecond.length ?", + " lstFirst[0] === lstSecond[0] && isPrefixOf(", + " lstFirst.slice(1), lstSecond.slice(1)", + " ) : false", + " ) : true;", + " }", + " ", + " // Int -> [a] -> [a]", + " function drop(n, lst) {", + " return n <= 0 ? lst : (", + " lst.length ? drop(n - 1, lst.slice(1)) : []", + " );", + " }", + " ", + " return lstTest.map(romanValue);", + " ", + "})(['MCMXC', 'MDCLXVI', 'MMVIII']);", + "{{Out}}", + "[1990, 1666, 2008]", + "", + "or, more natively:", + "(function (lstTest) {", + " ", + " function romanValue(s) {", + " return s.length ? function () {", + " var parse = [].concat.apply([], glyphs.map(function (g) {", + " return 0 === s.indexOf(g) ? [trans[g], s.substr(g.length)] : [];", + " }));", + " return parse[0] + romanValue(parse[1]);", + " }() : 0;", + " }", + " ", + " var trans = {", + " M: 1E3,", + " CM: 900,", + " D: 500,", + " CD: 400,", + " C: 100,", + " XC: 90,", + " L: 50,", + " XL: 40,", + " X: 10,", + " IX: 9,", + " V: 5,", + " IV: 4,", + " I: 1", + " },", + " glyphs = Object.keys(trans);", + " ", + " return lstTest.map(romanValue);", + " ", + "})([\"MCMXC\", \"MDCLXVI\", \"MMVIII\", \"MMMM\"]);", + "{{Out}}", + "[1990, 1666, 2008]", + "", + "===ES6===", + "====Recursion====", + "(() => {", + " // romanValue :: String -> Int", + " const romanValue = s =>", + " s.length ? (() => {", + " const parse = [].concat(", + " ...glyphs.map(g => 0 === s.indexOf(g) ? (", + " [dctTrans[g], s.substr(g.length)]", + " ) : [])", + " );", + " return parse[0] + romanValue(parse[1]);", + " })() : 0;", + "", + " // dctTrans :: {romanKey: Integer}", + " const dctTrans = {", + " M: 1E3,", + " CM: 900,", + " D: 500,", + " CD: 400,", + " C: 100,", + " XC: 90,", + " L: 50,", + " XL: 40,", + " X: 10,", + " IX: 9,", + " V: 5,", + " IV: 4,", + " I: 1", + " };", + "", + " // glyphs :: [romanKey]", + " const glyphs = Object.keys(dctTrans);", + "", + " // TEST -------------------------------------------------------------------", + " return [\"MCMXC\", \"MDCLXVI\", \"MMVIII\", \"MMMM\"].map(romanValue);", + "})();", + "{{Out}}", + "[1990,1666,2008,4000]", + "", + "", + "====Folding from the right====", + "{{Trans|Haskell}} ", + "(fold and foldr examples)", + "(() => {", + "", + " // Folding from right to left,", + " // lower leftward characters are subtracted,", + " // others are added.", + "", + " // fromRoman :: String -> Int", + " const fromRoman = s =>", + " snd(foldr(", + " ([r, n], l) => [l, l >= r ? n + l : n - l], [0, 0],", + " map(charVal, stringChars(s))", + " ));", + "", + " // charVal :: Char -> Maybe Int", + " const charVal = k => {", + " const v = {", + " I: 1,", + " V: 5,", + " X: 10,", + " L: 50,", + " C: 100,", + " D: 500,", + " M: 1000", + " }[k];", + " return v !== undefined ? v : 0;", + " };", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // foldr (a -> b -> b) -> b -> [a] -> b", + " const foldr = (f, a, xs) => xs.reduceRight(f, a);", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // snd :: (a, b) -> b", + " const snd = tpl => Array.isArray(tpl) ? tpl[1] : undefined;", + "", + " // stringChars :: String -> [Char]", + " const stringChars = s => s.split('');", + "", + " // show :: a -> String", + " const show = (...x) =>", + " JSON.stringify.apply(", + " null, x.length > 1 ? [x[1], null, x[0]] : x", + " );", + "", + " // TEST -------------------------------------------------------------------", + " return show(", + " map(fromRoman, [\"MDCLXVI\", \"MCMXC\", \"MMVIII\", \"MMXVI\", \"MMXVII\"])", + " );", + "})();", + "{{Out}}", + "
[1666,1990,2008,2016,2017]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fba", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var Roman = {\n Values: [['CM', 900], ['CD', 400], ['XC', 90], ['XL', 40], ['IV', 4], \n ['IX', 9], ['V', 5], ['X', 10], ['L', 50], \n ['C', 100], ['M', 1000], ['I', 1], ['D', 500]],\n UnmappedStr : 'Q',\n parse: function(str) {\n var result = 0\n for (var i=0; ireplaceMe is a function.');" + ] + }, + { + "title": "Roman numerals/Encode", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a function taking a positive integer as its parameter and returning a string containing the Roman numeral representation of that integer. Modern Roman numerals are written by expressing each digit separately, starting with the left most digit and skipping any digit with a value of zero.

", + "

In Roman numerals:

", + "1990 is rendered: 1000=M, 900=CM, 90=XC; resulting in MCMXC", + "2008 is written as 2000=MM, 8=VIII; or MMVIII", + "1666 uses each Roman symbol in descending order: MDCLXVI" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "====Iteration====", + "", + "{{trans|Tcl}}", + "var roman = {", + " map: [", + " 1000, 'M', 900, 'CM', 500, 'D', 400, 'CD', 100, 'C', 90, 'XC',", + " 50, 'L', 40, 'XL', 10, 'X', 9, 'IX', 5, 'V', 4, 'IV', 1, 'I',", + " ],", + " int_to_roman: function(n) {", + " var value = '';", + " for (var idx = 0; n > 0 && idx < this.map.length; idx += 2) {", + " while (n >= this.map[idx]) {", + " value += this.map[idx + 1];", + " n -= this.map[idx];", + " }", + " }", + " return value;", + " }", + "}", + "", + "roman.int_to_roman(1999); // \"MCMXCIX\"", + "", + "====Functional composition====", + "", + "(function () {", + " 'use strict';", + "", + "", + " // If the Roman is a string, pass any delimiters through", + "", + " // (Int | String) -> String", + " function romanTranscription(a) {", + " if (typeof a === 'string') {", + " var ps = a.split(/\\d+/),", + " dlm = ps.length > 1 ? ps[1] : undefined;", + "", + " return (dlm ? a.split(dlm)", + " .map(function (x) {", + " return Number(x);", + " }) : [a])", + " .map(roman)", + " .join(dlm);", + " } else return roman(a);", + " }", + "", + " // roman :: Int -> String", + " function roman(n) {", + " return [[1000, \"M\"], [900, \"CM\"], [500, \"D\"], [400, \"CD\"], [100,", + " \"C\"], [90, \"XC\"], [50, \"L\"], [40, \"XL\"], [10, \"X\"], [9,", + " \"IX\"], [5, \"V\"], [4, \"IV\"], [1, \"I\"]]", + " .reduce(function (a, lstPair) {", + " var m = a.remainder,", + " v = lstPair[0];", + "", + " return (v > m ? a : {", + " remainder: m % v,", + " roman: a.roman + Array(", + " Math.floor(m / v) + 1", + " )", + " .join(lstPair[1])", + " });", + " }, {", + " remainder: n,", + " roman: ''", + " }).roman; ", + " }", + "", + " // TEST", + "", + " return [2016, 1990, 2008, \"14.09.2015\", 2000, 1666].map(", + " romanTranscription);", + "", + "})();", + "", + "{{Out}}", + "[\"MMXVI\", \"MCMXC\", \"MMVIII\", \"XIV.IX.MMXV\", \"MM\", \"MDCLXVI\"]", + "", + "", + "===ES6===", + "{{Trans|Haskell}}", + "(mapAccumL version)", + "(() => {", + " // ROMAN INTEGER STRINGS ----------------------------------------------------", + "", + " // roman :: Int -> String", + " const roman = n =>", + " concat(snd(mapAccumL((balance, [k, v]) => {", + " const [q, r] = quotRem(balance, v);", + " return [r, q > 0 ? concat(replicate(q, k)) : ''];", + " }, n, [", + " ['M', 1000],", + " ['CM', 900],", + " ['D', 500],", + " ['CD', 400],", + " ['C', 100],", + " ['XC', 90],", + " ['L', 50],", + " ['XL', 40],", + " ['X', 10],", + " ['IX', 9],", + " ['V', 5],", + " ['IV', 4],", + " ['I', 1]", + " ])));", + "", + " // GENERIC FUNCTIONS -------------------------------------------------------", + "", + " // concat :: [[a]] -> [a] | [String] -> String", + " const concat = xs =>", + " xs.length > 0 ? (() => {", + " const unit = typeof xs[0] === 'string' ? '' : [];", + " return unit.concat.apply(unit, xs);", + " })() : [];", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // 'The mapAccumL function behaves like a combination of map and foldl;", + " // it applies a function to each element of a list, passing an accumulating", + " // parameter from left to right, and returning a final value of this", + " // accumulator together with the new list.' (See Hoogle)", + "", + " // mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])", + " const mapAccumL = (f, acc, xs) =>", + " xs.reduce((a, x) => {", + " const pair = f(a[0], x);", + " return [pair[0], a[1].concat([pair[1]])];", + " }, [acc, []]);", + "", + " // quotRem :: Integral a => a -> a -> (a, a)", + " const quotRem = (m, n) => [Math.floor(m / n), m % n];", + "", + " // replicate :: Int -> a -> [a]", + " const replicate = (n, x) =>", + " Array.from({", + " length: n", + " }, () => x);", + "", + " // show :: a -> String", + " const show = (...x) =>", + " JSON.stringify.apply(", + " null, x.length > 1 ? [x[0], null, x[1]] : x", + " );", + "", + " // snd :: (a, b) -> b", + " const snd = tpl => Array.isArray(tpl) ? tpl[1] : undefined;", + "", + " // TEST -------------------------------------------------------------------", + " return show(", + " map(roman, [2016, 1990, 2008, 2000, 1666])", + " );", + "})();", + "{{Out}}", + "[\"MMXVI\",\"MCMXC\",\"MMVIII\",\"MM\",\"MDCLXVI\"]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fbb", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var roman = {\n map: [\n 1000, 'M', 900, 'CM', 500, 'D', 400, 'CD', 100, 'C', 90, 'XC',\n 50, 'L', 40, 'XL', 10, 'X', 9, 'IX', 5, 'V', 4, 'IV', 1, 'I',\n ],\n int_to_roman: function(n) {\n var value = '';\n for (var idx = 0; n > 0 && idx < this.map.length; idx += 2) {\n while (n >= this.map[idx]) {\n value += this.map[idx + 1];\n n -= this.map[idx];\n }\n }\n return value;\n }\n}\n\nroman.int_to_roman(1999); // \"MCMXCIX\"\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Roots of a function", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a program that finds and outputs the roots of a given function, range and (if applicable) step width.

The program should identify whether the root is exact or approximate.

", + "

For this task, use: ƒ(x) = x3 - 3x2 + 2x

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{trans|Java}}", + "{{works with|SpiderMonkey|22}}", + "{{works with|Firefox|22}}", + "", + "// This function notation is sorta new, but useful here", + "// Part of the EcmaScript 6 Draft", + "// developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope", + "var poly = (x => x*x*x - 3*x*x + 2*x);", + "", + "function sign(x) {", + "\treturn (x < 0.0) ? -1 : (x > 0.0) ? 1 : 0;", + "}", + "", + "function printRoots(f, lowerBound, upperBound, step) {", + "\tvar x = lowerBound, ox = x,", + "\t\t y = f(x), oy = y,", + "\t\t s = sign(y), os = s;", + "", + "\tfor (; x <= upperBound ; x += step) {", + "\t s = sign(y = f(x));", + "\t if (s == 0) {", + "\t\t\tconsole.log(x);", + "\t }", + "\t else if (s != os) {", + "\t\t\tvar dx = x - ox;", + "\t\t\tvar dy = y - oy;", + "\t\t\tvar cx = x - dx * (y / dy);", + "\t\t\tconsole.log(\"~\" + cx);", + "\t }", + "\t ox = x; oy = y; os = s;", + "\t}", + "}", + "", + "printRoots(poly, -1.0, 4, 0.002);", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fbc", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n// This function notation is sorta new, but useful here\n// Part of the EcmaScript 6 Draft\n// developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope\nvar poly = (x => x*x*x - 3*x*x + 2*x);\n\nfunction sign(x) {\n\treturn (x < 0.0) ? -1 : (x > 0.0) ? 1 : 0;\n}\n\nfunction printRoots(f, lowerBound, upperBound, step) {\n\tvar x = lowerBound, ox = x,\n\t\t y = f(x), oy = y,\n\t\t s = sign(y), os = s;\n\n\tfor (; x <= upperBound ; x += step) {\n\t s = sign(y = f(x));\n\t if (s == 0) {\n\t\t\tconsole.log(x);\n\t }\n\t else if (s != os) {\n\t\t\tvar dx = x - ox;\n\t\t\tvar dy = y - oy;\n\t\t\tvar cx = x - dx * (y / dy);\n\t\t\tconsole.log(\"~\" + cx);\n\t }\n\t ox = x; oy = y; os = s;\n\t}\n}\n\nprintRoots(poly, -1.0, 4, 0.002);\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Roots of a quadratic function", + "type": "Waypoint", + "description": [ + "

Write a program to find the roots of a quadratic equation, i.e., solve the equation $ax^2 + bx + c = 0$.

", + "

Your program must correctly handle non-real roots, but it need not check that $a \\neq 0$.

The problem of solving a quadratic equation is a good example of how dangerous it can be to ignore the peculiarities of floating-point arithmetic.

", + "

The obvious way to implement the quadratic formula suffers catastrophic loss of accuracy when one of the roots to be found is much closer to 0 than the other.

", + "

In their classic textbook on numeric methods Computer Methods for Mathematical Computations, George Forsythe, Michael Malcolm, and Cleve Moler suggest trying the naive algorithm with $a = 1$, $b = -10^5$, and $c = 1$.

", + "

(For double-precision floats, set $b = -10^9$.)

", + "

Consider the following implementation in Ada:

", + "

with Ada.Text_IO; use Ada.Text_IO;

", + "

with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;

procedure Quadratic_Equation is

", + "

type Roots is array (1..2) of Float;

", + "

function Solve (A, B, C : Float) return Roots is

", + "

SD : constant Float := sqrt (B**2 - 4.0 * A * C);

", + "

AA : constant Float := 2.0 * A;

", + "

begin

", + "

return ((- B + SD) / AA, (- B - SD) / AA);

", + "

end Solve;

R : constant Roots := Solve (1.0, -10.0E5, 1.0);

", + "

begin

", + "

Put_Line (\"X1 =\" & Float'Image (R (1)) & \" X2 =\" & Float'Image (R (2)));

", + "

end Quadratic_Equation;

X1 = 1.00000E+06 X2 = 0.00000E+00
", + "

As we can see, the second root has lost all significant figures. The right answer is that X2 is about $10^{-6}$. The naive method is numerically unstable.

Suggested by Middlebrook (D-OA), a better numerical method: to define two parameters $ q = \\sqrt{a c} / b $ and $ f = 1/2 + \\sqrt{1 - 4 q^2} /2 $

and the two roots of the quardratic are: $ \\frac{-b}{a} f $ and $ \\frac{-c}{b f} $

", + "

Task: do it better. This means that given $a = 1$, $b = -10^9$, and $c = 1$, both of the roots your program returns should be greater than $10^{-11}$. Or, if your language can't do floating-point arithmetic any more precisely than single precision, your program should be able to handle $b = -10^6$. Either way, show what your program gives as the roots of the quadratic in question. See page 9 of

", + "

\"What Every Scientist Should Know About Floating-Point Arithmetic\" for a possible algorithm.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fbd", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Roots of unity", + "type": "Waypoint", + "description": [ + "

The purpose of this task is to explore working with complex numbers.

", + "Task:", + "

Given n, find the n-th roots of unity.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function Root(angle) {", + "\twith (Math) { this.r = cos(angle); this.i = sin(angle) }", + "}", + "", + "Root.prototype.toFixed = function(p) {", + "\treturn this.r.toFixed(p) + (this.i >= 0 ? '+' : '') + this.i.toFixed(p) + 'i'", + "}", + "", + "function roots(n) {", + "\tvar rs = [], teta = 2*Math.PI/n", + "\tfor (var angle=0, i=0; i')", + "}", + "", + "{{Output}}", + "
2: 1.00000+0.00000i, -1.00000+0.00000i",
+      "3: 1.00000+0.00000i, -0.50000+0.86603i, -0.50000-0.86603i",
+      "4: 1.00000+0.00000i, 0.00000+1.00000i, -1.00000+0.00000i, -0.00000-1.00000i",
+      "5: 1.00000+0.00000i, 0.30902+0.95106i, -0.80902+0.58779i, -0.80902-0.58779i, 0.30902-0.95106i",
+      "6: 1.00000+0.00000i, 0.50000+0.86603i, -0.50000+0.86603i, -1.00000+0.00000i, -0.50000-0.86603i, 0.50000-0.86603i",
+      "7: 1.00000+0.00000i, 0.62349+0.78183i, -0.22252+0.97493i, -0.90097+0.43388i, -0.90097-0.43388i, -0.22252-0.97493i, 0.62349-0.78183i
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fbe", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function Root(angle) {\n\twith (Math) { this.r = cos(angle); this.i = sin(angle) }\n}\n\nRoot.prototype.toFixed = function(p) {\n\treturn this.r.toFixed(p) + (this.i >= 0 ? '+' : '') + this.i.toFixed(p) + 'i'\n}\n\nfunction roots(n) {\n\tvar rs = [], teta = 2*Math.PI/n\n\tfor (var angle=0, i=0; i')\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Rosetta Code/Find bare lang tags", + "type": "Waypoint", + "description": [ + "Task:", + "

Find all tags without a language specified in the text of a page.

Display counts by language section:

",
+      "

Description

Pseudocode

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fc0", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Rosetta Code/Fix code tags", + "type": "Waypoint", + "description": [ + "Task:", + "

Fix Rosetta Code deprecated code tags, with these rules:

", + "
",
+      "Change <%s> to ",
+      "Change  to ",
+      "Change  to ",
+      "Change  to ",
+      "
", + "Usage:", + "
",
+      "./convert.py < wikisource.txt > converted.txt",
+      "
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|SpiderMonkey}}", + "var langs = ['foo', 'bar', 'baz']; // real list of langs goes here", + "var end_tag = '';", + "", + "var line;", + "while (line = readline()) {", + " line = line.replace(new RegExp('', 'gi'), end_tag);", + " for (var i = 0; i < langs.length; i++)", + " line = line.replace(new RegExp('<(?:code )?(' + langs[i] + ')>', 'gi'), '')", + " .replace(new RegExp('', 'gi'), end_tag);", + " print(line);", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fc2", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var langs = ['foo', 'bar', 'baz']; // real list of langs goes here\nvar end_tag = '';\n\nvar line;\nwhile (line = readline()) {\n line = line.replace(new RegExp('', 'gi'), end_tag);\n for (var i = 0; i < langs.length; i++)\n line = line.replace(new RegExp('<(?:code )?(' + langs[i] + ')>', 'gi'), '')\n .replace(new RegExp('', 'gi'), end_tag);\n print(line);\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Rot-13", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement a rot-13 function (or procedure, class, subroutine, or other \"callable\" object as appropriate to your programming environment).

Optionally wrap this function in a utility program (like tr, which acts like a common UNIX utility, performing a line-by-line rot-13 encoding of every line of input contained in each file listed on its command line, or (if no filenames are passed thereon) acting as a filter on its \"standard input.\"

", + "

(A number of UNIX scripting languages and utilities, such as awk and sed either default to processing files in this way or have command line switches or modules to easily implement these wrapper semantics, e.g., Perl and Python).

The rot-13 encoding is commonly known from the early days of Usenet \"Netnews\" as a way of obfuscating text to prevent casual reading of spoiler or potentially offensive material.

Many news reader and mail user agent programs have built-in rot-13 encoder/decoders or have the ability to feed a message through any external utility script for performing this (or other) actions.

The definition of the rot-13 function is to simply replace every letter of the ASCII alphabet with the letter which is \"rotated\" 13 characters \"around\" the 26 letter alphabet from its normal cardinal position (wrapping around from z' to a as necessary).

Thus the letters abc become nop and so on.

Technically rot-13 is a \"mono-alphabetic substitution cipher\" with a trivial \"key\".

A proper implementation should work on upper and lower case letters, preserve case, and pass all non-alphabetic characters

", + "

in the input stream through without alteration.

", + "Related tasks:", + " Caesar cipher", + " Substitution Cipher", + " Vigenère Cipher/Cryptanalysis" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function rot13(c) {", + " return c.replace(/([a-m])|([n-z])/ig, function($0,$1,$2) {", + " return String.fromCharCode($1 ? $1.charCodeAt(0) + 13 : $2 ? $2.charCodeAt(0) - 13 : 0) || $0;", + " });", + "}", + "rot13(\"ABJURER nowhere\") // NOWHERE abjurer", + "", + "", + "TDD with Jasmine using Underscore.js", + "", + "", + "function rot13(value){", + " if (!value)", + " return \"\";", + "", + " function singleChar(c) {", + " if (c.toUpperCase() < \"A\" || c.toUpperCase() > \"Z\")", + " return c;", + "", + " if (c.toUpperCase() <= \"M\")", + " return String.fromCharCode(c.charCodeAt(0) + 13);", + "", + " return String.fromCharCode(c.charCodeAt(0) - 13); ", + " }", + "", + " return _.map(value.split(\"\"), singleChar).join(\"\");", + "}", + "", + "describe(\"Rot-13\", function() {", + " it(\"Given nothing will return nothing\", function() {", + " expect(rot13()).toBe(\"\");", + " });", + "", + " it(\"Given empty string will return empty string\", function() {", + " expect(rot13(\"\")).toBe(\"\");", + " });", + "", + " it(\"Given A will return N\", function() {", + " expect(rot13(\"A\")).toBe(\"N\");", + " });", + "", + " it(\"Given B will return O\", function() {", + " expect(rot13(\"B\")).toBe(\"O\");", + " });", + "", + " it(\"Given N will return A\", function() {", + " expect(rot13(\"N\")).toBe(\"A\");", + " });", + "", + " it(\"Given Z will return M\", function() {", + " expect(rot13(\"Z\")).toBe(\"M\");", + " });", + "", + " it(\"Given ZA will return MN\", function() {", + " expect(rot13(\"ZA\")).toBe(\"MN\");", + " });", + "", + " it(\"Given HELLO will return URYYB\", function() {", + " expect(rot13(\"HELLO\")).toBe(\"URYYB\");", + " });", + "", + " it(\"Given hello will return uryyb\", function() {", + " expect(rot13(\"hello\")).toBe(\"uryyb\");", + " });", + "", + "", + " it(\"Given hello1 will return uryyb1\", function() {", + " expect(rot13(\"hello1\")).toBe(\"uryyb1\");", + " });", + "});", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fc4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function rot13(c) {\n return c.replace(/([a-m])|([n-z])/ig, function($0,$1,$2) {\n return String.fromCharCode($1 ? $1.charCodeAt(0) + 13 : $2 ? $2.charCodeAt(0) - 13 : 0) || $0;\n });\n}\nrot13(\"ABJURER nowhere\") // NOWHERE abjurer\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "RSA code", + "type": "Waypoint", + "description": [ + "

Given an RSA key (n,e,d), construct a program to encrypt and decrypt plaintext messages strings.

Background

RSA code is used to encode secret messages. It is named after Ron Rivest, Adi Shamir, and Leonard Adleman who published it at MIT in 1977. The advantage of this type of encryption is that you can distribute the number “$n$” and “$e$” (which makes up the Public Key used for encryption) to everyone. The Private Key used for decryption “$d$” is kept secret, so that only the recipient can read the encrypted plaintext.

The process by which this is done is that a message, for example “Hello World” is encoded as numbers (This could be encoding as ASCII or as a subset of characters $a=01,b=02,...,z=26$). This yields a string of numbers, generally referred to as \"numerical plaintext\", “$P$”. For example, “Hello World” encoded with a=1,...,z=26 by hundreds would yield $0805 1212 1523 1518 1204$.

The plaintext must also be split into blocks so that the numerical plaintext is smaller than $n$ otherwise the decryption will fail.

The ciphertext, $C$, is then computed by taking each block of $P$, and computing

", + "

$C \\equiv P^e \\mod n$

", + "

Similarly, to decode, one computes

", + "

$P \\equiv C^d \\mod n$

To generate a key, one finds 2 (ideally large) primes $p$ and $q$. the value “$n$” is simply: $n = p \\times q$.

", + "

One must then choose an “$e$” such that $\\gcd(e, (p-1)\\times(q-1) ) = 1$. That is to say, $e$ and $(p-1)\\times(q-1)$ are relatively prime to each other.

The decryption value $d$ is then found by solving

", + "

$d\\times e \\equiv 1 \\mod (p-1)\\times(q-1)$

The security of the code is based on the secrecy of the Private Key (decryption exponent) “$d$” and the difficulty in factoring “$n$”. Research into RSA facilitated advances in factoring and a number of factoring challenges. Keys of 768 bits have been successfully factored. While factoring of keys of 1024 bits has not been demonstrated, NIST expected them to be factorable by 2010 and now recommends 2048 bit keys going forward (see Asymmetric algorithm key lengths or NIST 800-57 Pt 1 Revised Table 4: Recommended algorithms and minimum key sizes).

Summary of the task requirements:

Encrypt and Decrypt a short message or two using RSA with a demonstration key. ", + " Implement RSA do not call a library.", + " Encode and decode the message using any reversible method of your choice (ASCII or a=1,..,z=26 are equally fine). ", + " Either support blocking or give an error if the message would require blocking)", + " Demonstrate that your solution could support real keys by using a non-trivial key that requires large integer support (built-in or libraries). There is no need to include library code but it must be referenced unless it is built into the language. The following keys will be meet this requirement;however, they are NOT long enough to be considered secure:: n = 9516311845790656153499716760847001433441357", + "

: e = 65537

", + "

: d = 5617843187844953170308463622230283376298685

", + " Messages can be hard-coded into the program, there is no need for elaborate input coding.", + " Demonstrate that your implementation works by showing plaintext, intermediate results, encrypted text, and decrypted text." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fc5", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Runge-Kutta method", + "type": "Waypoint", + "description": [ + "

Given the example Differential equation:

", + "

$y'(t) = t \\times \\sqrt {y(t)}$

", + "

With initial condition:

", + "

$t_0 = 0$ and $y_0 = y(t_0) = y(0) = 1$

", + "

This equation has an exact solution:

", + "

$y(t) = \\tfrac{1}{16}(t^2 +4)^2$

", + "Task", + "

Demonstrate the commonly used explicit fourth-order Runge–Kutta method to solve the above differential equation.

", + "Solve the given differential equation over the range $t = 0 \\ldots 10$ with a step value of $\\delta t=0.1$ (101 total points, the first being given)", + "Print the calculated values of $y$ at whole numbered $t$'s ($0.0, 1.0, \\ldots 10.0$) along with error as compared to the exact solution.Method summary", + "

Starting with a given $y_n$ and $t_n$ calculate:

", + "

$\\delta y_1 = \\delta t\\times y'(t_n, y_n)\\quad$

", + "

$\\delta y_2 = \\delta t\\times y'(t_n + \\tfrac{1}{2}\\delta t , y_n + \\tfrac{1}{2}\\delta y_1)$

", + "

$\\delta y_3 = \\delta t\\times y'(t_n + \\tfrac{1}{2}\\delta t , y_n + \\tfrac{1}{2}\\delta y_2)$

", + "

$\\delta y_4 = \\delta t\\times y'(t_n + \\delta t , y_n + \\delta y_3)\\quad$

", + "

then:

", + "

$y_{n+1} = y_n + \\tfrac{1}{6} (\\delta y_1 + 2\\delta y_2 + 2\\delta y_3 + \\delta y_4)$

", + "

$t_{n+1} = t_n + \\delta t\\quad$

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "function rk4(y, x, dx, f) {", + " var k1 = dx * f(x, y),", + " k2 = dx * f(x + dx / 2.0, +y + k1 / 2.0),", + " k3 = dx * f(x + dx / 2.0, +y + k2 / 2.0),", + " k4 = dx * f(x + dx, +y + k3);", + "", + " return y + (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0;", + "}", + "", + "function f(x, y) {", + " return x * Math.sqrt(y);", + "}", + "", + "function actual(x) {", + " return (1/16) * (x*x+4)*(x*x+4);", + "}", + "", + "var y = 1.0,", + " x = 0.0,", + " step = 0.1,", + " steps = 0,", + " maxSteps = 101,", + " sampleEveryN = 10;", + "", + "while (steps < maxSteps) {", + " if (steps%sampleEveryN === 0) {", + " console.log(\"y(\" + x + \") = \\t\" + y + \"\\t ± \" + (actual(x) - y).toExponential());", + " }", + "", + " y = rk4(y, x, step, f);", + "", + " // using integer math for the step addition", + " // to prevent floating point errors as 0.2 + 0.1 != 0.3", + " x = ((x * 10) + (step * 10)) / 10;", + " steps += 1;", + "}", + "", + "{{out}}", + "
",
+      "y(0) =  \t1\t                 ± 0e+0",
+      "y(1) =  \t1.562499854278108\t ± 1.4572189210859676e-7",
+      "y(2) =  \t3.999999080520799\t ± 9.194792007782837e-7",
+      "y(3) =  \t10.562497090437551\t ± 2.9095624487496252e-6",
+      "y(4) =  \t24.999993765090636\t ± 6.234909363911356e-6",
+      "y(5) =  \t52.562489180302585\t ± 1.0819697415342944e-5",
+      "y(6) =  \t99.99998340540358\t ± 1.659459641700778e-5",
+      "y(7) =  \t175.56247648227125\t ± 2.3517728749311573e-5",
+      "y(8) =  \t288.9999684347986\t ± 3.156520142510999e-5",
+      "y(9) =  \t451.56245927683966\t ± 4.07231603389846e-5",
+      "y(10) =  \t675.9999490167097\t ± 5.098329029351589e-5",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fc6", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nfunction rk4(y, x, dx, f) {\n var k1 = dx * f(x, y),\n k2 = dx * f(x + dx / 2.0, +y + k1 / 2.0),\n k3 = dx * f(x + dx / 2.0, +y + k2 / 2.0),\n k4 = dx * f(x + dx, +y + k3);\n\n return y + (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0;\n}\n\nfunction f(x, y) {\n return x * Math.sqrt(y);\n}\n\nfunction actual(x) {\n return (1/16) * (x*x+4)*(x*x+4);\n}\n\nvar y = 1.0,\n x = 0.0,\n step = 0.1,\n steps = 0,\n maxSteps = 101,\n sampleEveryN = 10;\n\nwhile (steps < maxSteps) {\n if (steps%sampleEveryN === 0) {\n console.log(\"y(\" + x + \") = \\t\" + y + \"\\t ± \" + (actual(x) - y).toExponential());\n }\n\n y = rk4(y, x, step, f);\n\n // using integer math for the step addition\n // to prevent floating point errors as 0.2 + 0.1 != 0.3\n x = ((x * 10) + (step * 10)) / 10;\n steps += 1;\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Run-length encoding", + "type": "Waypoint", + "description": [ + "

Given a string containing uppercase characters (A-Z), compress repeated 'runs' of the same character by storing the length of that run, and provide a function to reverse the compression. The output can be anything, as long as you can recreate the input with it.

Example:

Input: WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW

", + "

Output: 12W1B12W3B24W1B14W

Note: the encoding step in the above example is the same as a step of the Look-and-say sequence.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Here's an encoding method that walks the input string character by character", + "function encode(input) {", + " var encoding = [];", + " var prev, count, i;", + " for (count = 1, prev = input[0], i = 1; i < input.length; i++) {", + " if (input[i] != prev) {", + " encoding.push([count, prev]);", + " count = 1;", + " prev = input[i];", + " }", + " else ", + " count ++;", + " }", + " encoding.push([count, prev]);", + " return encoding;", + "}", + "", + "Here's an encoding method that uses a regular expression to grab the character runs ({{works with|JavaScript|1.6}} for the forEach method)", + "function encode_re(input) {", + " var encoding = [];", + " input.match(/(.)\\1*/g).forEach(function(substr){ encoding.push([substr.length, substr[0]]) });", + " return encoding;", + "}", + "", + "And to decode (see [[Repeating a string#JavaScript|Repeating a string]])", + "function decode(encoded) {", + " var output = \"\";", + " encoded.forEach(function(pair){ output += new Array(1+pair[0]).join(pair[1]) })", + " return output;", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fc7", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function encode(input) {\n var encoding = [];\n var prev, count, i;\n for (count = 1, prev = input[0], i = 1; i < input.length; i++) {\n if (input[i] != prev) {\n encoding.push([count, prev]);\n count = 1;\n prev = input[i];\n }\n else \n count ++;\n }\n encoding.push([count, prev]);\n return encoding;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Safe addition", + "type": "Waypoint", + "description": [ + "

Implementation of interval arithmetic and more generally fuzzy number arithmetic require operations that yield safe upper and lower bounds of the exact result.

For example, for an addition, it is the operations +↑ and +↓ defined as: a +↓ b ≤ a + b ≤ a +↑ b.

Additionally it is desired that the width of the interval (a +↑ b) - (a +↓ b) would be about the machine epsilon after removing the exponent part.

Differently to the standard floating-point arithmetic, safe interval arithmetic is accurate (but still imprecise).

I.E.: the result of each defined operation contains (though does not identify) the exact mathematical outcome.

Usually a FPU's have machine +,-,*,/ operations accurate within the machine precision.

To illustrate it, let us consider a machine with decimal floating-point arithmetic that has the precision is 3 decimal points.

If the result of the machine addition is 1.23, then the exact mathematical result is within the interval ]1.22, 1.24[.

When the machine rounds towards zero, then the exact result is within [1.23,1.24[. This is the basis for an implementation of safe addition.

", + "Task;", + "

Show how +↓ and +↑ can be implemented in your language using the standard floating-point type.

Define an interval type based on the standard floating-point one, and implement an interval-valued addition of two floating-point numbers considering them exact, in short an operation that yields the interval [a +↓ b, a +↑ b].

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fca", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Same Fringe", + "type": "Waypoint", + "description": [ + "

Write a routine that will compare the leaves (\"fringe\") of two binary trees to determine whether they are the same list of leaves when visited left-to-right. The structure or balance of the trees does not matter; only the number, order, and value of the leaves is important.

Any solution is allowed here, but many computer scientists will consider it inelegant to collect either fringe in its entirety before starting to collect the other one. In fact, this problem is usually proposed in various forums as a way to show off various forms of concurrency (tree-rotation algorithms have also been used to get around the need to collect one tree first). Thinking of it a slightly different way, an elegant solution is one that can perform the minimum amount of work to falsify the equivalence of the fringes when they differ somewhere in the middle, short-circuiting the unnecessary additional traversals and comparisons.

Any representation of a binary tree is allowed, as long as the nodes are orderable, and only downward links are used (for example, you may not use parent or sibling pointers to avoid recursion).

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fcc", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Search a list of records", + "type": "Waypoint", + "description": [ + "

Many programming languages provide convenient ways to look for a known value in a simple list of strings or numbers.

", + "

But what if the elements of the list are themselves compound records/objects/data-structures, and the search condition is more complex than a simple equality test?

", + "

Write a function/method/etc. that can find the first element in a given list matching a given condition.

", + "

It should be as generic and reusable as possible.

", + "

(Of course if your programming language already provides such a feature, you can use that instead of recreating it.)

Then to demonstrate its functionality, create the data structure specified under #Data set, and perform on it the searches specified under #Test cases.

", + "

The data structure to be used contains the names and populations (in millions) of the 10 largest metropolitan areas in Africa, and looks as follows when represented in JSON:

[

", + "

{ \"name\": \"Lagos\", \"population\": 21.0 },

", + "

{ \"name\": \"Cairo\", \"population\": 15.2 },

", + "

{ \"name\": \"Kinshasa-Brazzaville\", \"population\": 11.3 },

", + "

{ \"name\": \"Greater Johannesburg\", \"population\": 7.55 },

", + "

{ \"name\": \"Mogadishu\", \"population\": 5.85 },

", + "

{ \"name\": \"Khartoum-Omdurman\", \"population\": 4.98 },

", + "

{ \"name\": \"Dar Es Salaam\", \"population\": 4.7 },

", + "

{ \"name\": \"Alexandria\", \"population\": 4.58 },

", + "

{ \"name\": \"Abidjan\", \"population\": 4.4 },

", + "

{ \"name\": \"Casablanca\", \"population\": 3.98 }

", + "

]

However, you shouldn't parse it from JSON, but rather represent it natively in your programming language.

The top-level data structure should be an ordered collection (i.e. a list, array, vector, or similar).", + "Each element in this list should be an associative collection that maps from keys to values (i.e. a struct, object, hash map, dictionary, or similar).", + "Each of them has two entries: One string value with key \"name\", and one numeric value with key \"population\".", + "You may rely on the list being sorted by population count, as long as you explain this to readers.", + "

If any of that is impossible or unreasonable in your programming language, then feel free to deviate, as long as you explain your reasons in a comment above your solution.

", + "

{|

", + "

|-

", + "

! Search

", + "

! Expected result

", + "

|-

", + "

| Find the (zero-based) index of the first city in the list whose name is \"Dar Es Salaam\"

", + "

| 6

", + "

|-

", + "

| Find the name of the first city in this list whose population is less than 5 million

", + "

| Khartoum-Omdurman

", + "

|-

", + "

| Find the population of the first city in this list whose name starts with the letter \"A\"

", + "

| 4.58

", + "

|}

", + "

If your programming language supports higher-order programming, then the most elegant way to implement the requested functionality in a generic and reusable way, might be to write a function (maybe called \"find_index\" or similar), that takes two arguments:

", + "The list to search through.", + "A function/lambda/closure (the so-called \"predicate\"), which will be applied in turn to each element in the list, and whose boolean return value defines whether that element matches the search requirement.", + "

If this is not the approach which would be most natural or idiomatic in your language, explain why, and show what is.

", + "Search a list", + "


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "(function () {", + " 'use strict';", + " ", + " // find :: (a -> Bool) -> [a] -> Maybe a", + " function find(f, xs) {", + " for (var i = 0, lng = xs.length; i < lng; i++) {", + " if (f(xs[i])) return xs[i];", + " }", + " return undefined;", + " }", + " ", + " // findIndex :: (a -> Bool) -> [a] -> Maybe Int", + " function findIndex(f, xs) {", + " for (var i = 0, lng = xs.length; i < lng; i++) {", + " if (f(xs[i])) return i;", + " } ", + " return undefined;", + " }", + " ", + " ", + " var lst = [", + " { \"name\": \"Lagos\", \"population\": 21.0 },", + " { \"name\": \"Cairo\", \"population\": 15.2 },", + " { \"name\": \"Kinshasa-Brazzaville\", \"population\": 11.3 },", + " { \"name\": \"Greater Johannesburg\", \"population\": 7.55 },", + " { \"name\": \"Mogadishu\", \"population\": 5.85 },", + " { \"name\": \"Khartoum-Omdurman\", \"population\": 4.98 },", + " { \"name\": \"Dar Es Salaam\", \"population\": 4.7 },", + " { \"name\": \"Alexandria\", \"population\": 4.58 },", + " { \"name\": \"Abidjan\", \"population\": 4.4 },", + " { \"name\": \"Casablanca\", \"population\": 3.98 }", + " ];", + " ", + " return {", + " darEsSalaamIndex: findIndex(function (x) {", + " return x.name === 'Dar Es Salaam';", + " }, lst),", + " ", + " firstBelow5M: find(function (x) {", + " return x.population < 5;", + " }, lst)", + " .name,", + " ", + " firstApop: find(function (x) {", + " return x.name.charAt(0) === 'A';", + " }, lst)", + " .population", + " };", + " ", + "})();", + "", + "", + "{{Out}}", + "
{\"darEsSalaamIndex\":6, \"firstBelow5M\":\"Khartoum-Omdurman\", \"firstApop\":4.58}
", + "", + "===ES6===", + "", + "(() => {", + " 'use strict';", + " ", + " let lst = [", + " { \"name\": \"Lagos\", \"population\": 21.0 },", + " { \"name\": \"Cairo\", \"population\": 15.2 },", + " { \"name\": \"Kinshasa-Brazzaville\", \"population\": 11.3 },", + " { \"name\": \"Greater Johannesburg\", \"population\": 7.55 },", + " { \"name\": \"Mogadishu\", \"population\": 5.85 },", + " { \"name\": \"Khartoum-Omdurman\", \"population\": 4.98 },", + " { \"name\": \"Dar Es Salaam\", \"population\": 4.7 },", + " { \"name\": \"Alexandria\", \"population\": 4.58 },", + " { \"name\": \"Abidjan\", \"population\": 4.4 },", + " { \"name\": \"Casablanca\", \"population\": 3.98 }", + " ];", + " ", + " return {", + " darEsSalaamIndex: lst.findIndex(x => x.name === 'Dar Es Salaam'),", + " firstBelow5M: lst.find(x => x.population < 5)", + " .name,", + " firstApop: lst.find(x => x.name[0] === 'A')", + " .population", + " };", + " ", + "})();", + "", + "", + "{{Out}}", + "
{\"darEsSalaamIndex\":6, \"firstBelow5M\":\"Khartoum-Omdurman\", \"firstApop\":4.58}
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fcf", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function () {\n 'use strict';\n \n // find :: (a -> Bool) -> [a] -> Maybe a\n function find(f, xs) {\n for (var i = 0, lng = xs.length; i < lng; i++) {\n if (f(xs[i])) return xs[i];\n }\n return undefined;\n }\n \n // findIndex :: (a -> Bool) -> [a] -> Maybe Int\n function findIndex(f, xs) {\n for (var i = 0, lng = xs.length; i < lng; i++) {\n if (f(xs[i])) return i;\n } \n return undefined;\n }\n \n \n var lst = [\n { \"name\": \"Lagos\", \"population\": 21.0 },\n { \"name\": \"Cairo\", \"population\": 15.2 },\n { \"name\": \"Kinshasa-Brazzaville\", \"population\": 11.3 },\n { \"name\": \"Greater Johannesburg\", \"population\": 7.55 },\n { \"name\": \"Mogadishu\", \"population\": 5.85 },\n { \"name\": \"Khartoum-Omdurman\", \"population\": 4.98 },\n { \"name\": \"Dar Es Salaam\", \"population\": 4.7 },\n { \"name\": \"Alexandria\", \"population\": 4.58 },\n { \"name\": \"Abidjan\", \"population\": 4.4 },\n { \"name\": \"Casablanca\", \"population\": 3.98 }\n ];\n \n return {\n darEsSalaamIndex: findIndex(function (x) {\n return x.name === 'Dar Es Salaam';\n }, lst),\n \n firstBelow5M: find(function (x) {\n return x.population < 5;\n }, lst)\n .name,\n \n firstApop: find(function (x) {\n return x.name.charAt(0) === 'A';\n }, lst)\n .population\n };\n \n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Search a list", + "type": "Waypoint", + "description": [ + "

Find the index of a string (needle) in an indexable, ordered collection of strings (haystack).

Raise an exception if the needle is missing.

If there is more than one occurrence then return the smallest index to the needle.

", + "

Return the largest index to a needle that has multiple occurrences in the haystack.

", + "Search a list of records", + "


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var haystack = ['Zig', 'Zag', 'Wally', 'Ronald', 'Bush', 'Krusty', 'Charlie', 'Bush', 'Bozo']", + "var needles = ['Bush', 'Washington']", + "", + "for (var i in needles) {", + " var found = false;", + " for (var j in haystack) {", + " if (haystack[j] == needles[i]) {", + " found = true;", + " break;", + " }", + " }", + " if (found)", + " print(needles[i] + \" appears at index \" + j + \" in the haystack\");", + " else", + " throw needles[i] + \" does not appear in the haystack\"", + "}", + "", + "The following {{works with|JavaScript|1.6}}:", + "for each (var needle in needles) {", + " var idx = haystack.indexOf(needle);", + " if (idx == -1)", + " throw needle + \" does not appear in the haystack\"", + " else", + " print(needle + \" appears at index \" + idx + \" in the haystack\");", + "}", + "", + "// extra credit", + "", + "for each (var elem in haystack) {", + " var first_idx = haystack.indexOf(elem);", + " var last_idx = haystack.lastIndexOf(elem);", + " if (last_idx > first_idx) {", + " print(elem + \" last appears at index \" + last_idx + \" in the haystack\");", + " break", + " }", + "}", + "", + "", + "Or, generalising enough (in ES5) to allow for varying definitions of the type of match we are looking for:", + "", + "(function () {", + "", + " function findIndex(fnPredicate, list) {", + " for (var i = 0, lng = list.length; i < lng; i++) {", + " if (fnPredicate(list[i])) {", + " return i;", + " }", + " }", + " return Error(\"not found\");", + " };", + "", + " // DEFINING A PARTICULAR TYPE OF SEARCH MATCH", + " ", + " function matchCaseInsensitive(s, t) {", + " return s.toLowerCase() === t.toLowerCase();", + " }", + "", + " var lstHaystack = [", + " 'Zig', 'Zag', 'Wally', 'Ronald', 'Bush',", + " 'Krusty', 'Charlie', 'Bush', 'Bozo'", + " ],", + " lstReversed = lstHaystack.slice(0).reverse(),", + " iLast = lstHaystack.length - 1,", + " lstNeedles = ['bush', 'washington'];", + "", + " return {", + " 'first': lstNeedles.map(function (s) {", + " return [s, findIndex(function (t) {", + " return matchCaseInsensitive(s, t);", + " },", + " lstHaystack)];", + " }),", + "", + " 'last': lstNeedles.map(function (s) {", + " var varIndex = findIndex(function (t) {", + " return matchCaseInsensitive(s, t);", + " },", + " lstReversed);", + "", + " return [", + " s,", + " typeof varIndex === 'number' ?", + " iLast - varIndex : varIndex", + " ];", + " })", + " }", + "})();", + "", + "Output:", + "", + "{", + " \"first\": [", + " [", + " \"bush\",", + " 4", + " ],", + " [", + " \"washington\",", + " \"Error: not found\"", + " ]", + " ],", + " \"last\": [", + " [", + " \"bush\",", + " 7", + " ],", + " [", + " \"washington\",", + " \"Error: not found\"", + " ]", + " ]", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fd0", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var haystack = ['Zig', 'Zag', 'Wally', 'Ronald', 'Bush', 'Krusty', 'Charlie', 'Bush', 'Bozo']\nvar needles = ['Bush', 'Washington']\n\nfor (var i in needles) {\n var found = false;\n for (var j in haystack) {\n if (haystack[j] == needles[i]) {\n found = true;\n break;\n }\n }\n if (found)\n print(needles[i] + \" appears at index \" + j + \" in the haystack\");\n else\n throw needles[i] + \" does not appear in the haystack\"\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Self-describing numbers", + "type": "Waypoint", + "description": [ + "

There are several so-called \"self-describing\" or \"self-descriptive\" integers.

An integer is said to be \"self-describing\" if it has the property that, when digit positions are labeled 0 to N-1, the digit in each position is equal to the number of times that that digit appears in the number.

For example, 2020 is a four-digit self describing number:

position 0 has value 2 and there are two 0s in the number;", + " position 1 has value 0 and there are no 1s in the number;", + " position 2 has value 2 and there are two 2s;", + " position 3 has value 0 and there are zero 3s.", + "

Self-describing numbers < 100.000.000 are: 1210, 2020, 21200, 3211000, 42101000.

", + "Task Description", + "Write a function/routine/method/... that will check whether a given positive integer is self-describing.", + "As an optional stretch goal - generate and display the set of self-describing numbers." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|SpiderMonkey}}", + "", + "function is_self_describing(n) {", + " var digits = Number(n).toString().split(\"\").map(function(elem) {return Number(elem)});", + " var len = digits.length;", + " var count = digits.map(function(x){return 0});", + "", + " digits.forEach(function(digit, idx, ary) {", + " if (digit >= count.length)", + " return false", + " count[digit] ++;", + " });", + "", + " return digits.equals(count);", + "}", + "", + "Array.prototype.equals = function(other) {", + " if (this === other)", + " return true; // same object", + " if (this.length != other.length)", + " return false;", + " for (idx in this)", + " if (this[idx] !== other[idx])", + " return false;", + " return true;", + "}", + "", + "for (var i=1; i<=3300000; i++)", + " if (is_self_describing(i))", + " print(i);", + "", + "outputs", + "
1210",
+      "2020",
+      "21200",
+      "3211000
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fd3", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function is_self_describing(n) {\n var digits = Number(n).toString().split(\"\").map(function(elem) {return Number(elem)});\n var len = digits.length;\n var count = digits.map(function(x){return 0});\n\n digits.forEach(function(digit, idx, ary) {\n if (digit >= count.length)\n return false\n count[digit] ++;\n });\n\n return digits.equals(count);\n}\n\nArray.prototype.equals = function(other) {\n if (this === other)\n return true; // same object\n if (this.length != other.length)\n return false;\n for (idx in this)\n if (this[idx] !== other[idx])\n return false;\n return true;\n}\n\nfor (var i=1; i<=3300000; i++)\n if (is_self_describing(i))\n print(i);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Self-referential sequence", + "type": "Waypoint", + "description": [ + "

There are several ways to generate a self-referential sequence. One very common one (the Look-and-say sequence) is to start with a positive integer, then generate the next term by concatenating enumerated groups of adjacent alike digits:

0, 10, 1110, 3110, 132110, 1113122110, 311311222110 ...

The terms generated grow in length geometrically and never converge.

Another way to generate a self-referential sequence is to summarize the previous term.

Count how many of each alike digit there is, then concatenate the sum and digit for each of the sorted enumerated digits. Note that the first five terms are the same as for the previous sequence.

0, 10, 1110, 3110, 132110, 13123110, 23124110 ... see The On-Line Encyclopedia of Integer Sequences

Sort the digits largest to smallest. Do not include counts of digits that do not appear in the previous term.

Depending on the seed value, series generated this way always either converge to a stable value or to a short cyclical pattern. (For our purposes, I'll use converge to mean an element matches a previously seen element.) The sequence shown, with a seed value of 0, converges to a stable value of 1433223110 after 11 iterations. The seed value that converges most quickly is 22. It goes stable after the first element. (The next element is 22, which has been seen before.)

Task:

Find all the positive integer seed values under 1000000, for the above convergent self-referential sequence, that takes the largest number of iterations before converging. Then print out the number of iterations and the sequence they return. Note that different permutations of the digits of the seed will yield the same sequence. For this task, assume leading zeros are not permitted.

Seed Value(s): 9009 9090 9900Iterations: 21 Sequence: (same for all three seeds except for first element)",
+      "9009",
+      "2920",
+      "192210",
+      "19222110",
+      "19323110",
+      "1923123110",
+      "1923224110",
+      "191413323110",
+      "191433125110",
+      "19151423125110",
+      "19251413226110",
+      "1916151413325110",
+      "1916251423127110",
+      "191716151413326110",
+      "191726151423128110",
+      "19181716151413327110",
+      "19182716151423129110",
+      "29181716151413328110",
+      "19281716151423228110",
+      "19281716151413427110",
+      "19182716152413228110",
+      "
", + "

See also: Self-describing numbers and Look-and-say sequence

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fd4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Semiprime", + "type": "Waypoint", + "description": [ + "

Semiprime numbers are natural numbers that are products of exactly two (possibly equal) prime numbers.

", + "

Semiprimes are also known as:

", + "

::* semi-primes

", + "

::* biprimes

", + "

::* bi-primes

", + "

::* 2-almost primes

", + "

::* or simply: P2

", + "Example: ", + "

1679 = 23 × 73

(This particular number was chosen as the length of the Arecibo message).

", + "Task;", + "

Write a function determining whether a given number is semiprime.

", + "See also:", + "The Wikipedia article: semiprime.", + "The Wikipedia article: almost prime.", + "The OEIS article: semiprimes which has a shorter definition: the product of two primes." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fd5", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Semordnilap", + "type": "Waypoint", + "description": [ + "

A semordnilap is a word (or phrase) that spells a different word (or phrase) backward.

", + "

\"Semordnilap\" is a word that itself is a semordnilap.

Example: lager and regal

", + " ", + "Task", + "

Using only words from the unixdict, report the total number of unique semordnilap pairs, and print 5 examples. (Note that lager/regal and regal/lager should be counted as one unique pair.)

", + " ", + "Related tasks", + "Palindrome detection" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{trans|Clojure}}", + "{{works with|Node.js}}", + "#!/usr/bin/env node", + "var fs = require('fs');", + "var sys = require('sys');", + "", + "var dictFile = process.argv[2] || \"unixdict.txt\";", + "", + "var dict = {};", + "fs.readFileSync(dictFile)", + " .toString()", + " .split('\\n')", + " .forEach(function(word) {", + " dict[word] = word.split(\"\").reverse().join(\"\");", + " });", + "", + "function isSemordnilap(word) { return dict[dict[word]]; };", + "", + "var semordnilaps = []", + "for (var key in dict) {", + " if (isSemordnilap(key)) {", + " var rev = dict[key];", + " if (key < rev) {", + " semordnilaps.push([key,rev]) ;", + " }", + " }", + "}", + "", + "var count = semordnilaps.length;", + "sys.puts(\"There are \" + count + \" semordnilaps in \" +", + " dictFile + \". Here are 5:\" );", + "", + "var indices=[]", + "for (var i=0; i", + "", + "{{works with|Rhino|1.7}}", + "", + "#!/usr/bin/env rhino", + "", + "importPackage (java.io)", + "", + "var dictFile = arguments[0] || \"unixdict.txt\";", + "", + "var reader = new BufferedReader(new FileReader(dictFile));", + "var dict = {};", + "var word;", + "while (word = reader.readLine()) {", + " dict[word] = word.split(\"\").reverse().join(\"\");", + "}", + "", + "function isSemordnilap(word) { return dict[dict[word]]; };", + "", + "var semordnilaps = []", + "for (var key in dict) {", + " if (isSemordnilap(key)) {", + " var rev = dict[key];", + " if (key < rev) {", + " semordnilaps.push([key,rev]) ;", + " }", + " }", + "}", + "", + "var count = semordnilaps.length;", + "print(\"There are \" + count + \" semordnilaps in \" +", + " dictFile + \". Here are 5:\" );", + "var indices=[]", + "for (var i=0; i", + "", + "{{out}}", + "
There are 158 semordnilaps in unixdict.txt.  Here are 5:",
+      "loot,tool",
+      "ah,ha",
+      "dial,laid",
+      "dine,enid",
+      "haw,wah
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fd6", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "#!/usr/bin/env node\nvar fs = require('fs');\nvar sys = require('sys');\n\nvar dictFile = process.argv[2] || \"unixdict.txt\";\n\nvar dict = {};\nfs.readFileSync(dictFile)\n .toString()\n .split('\\n')\n .forEach(function(word) {\n dict[word] = word.split(\"\").reverse().join(\"\");\n });\n\nfunction isSemordnilap(word) { return dict[dict[word]]; };\n\nvar semordnilaps = []\nfor (var key in dict) {\n if (isSemordnilap(key)) {\n var rev = dict[key];\n if (key < rev) {\n semordnilaps.push([key,rev]) ;\n }\n }\n}\n\nvar count = semordnilaps.length;\nsys.puts(\"There are \" + count + \" semordnilaps in \" +\n dictFile + \". Here are 5:\" );\n\nvar indices=[]\nfor (var i=0; ireplaceMe is a function.');" + ] + }, + { + "title": "Sequence of non-squares", + "type": "Waypoint", + "description": [ + "Task:", + "

Show that the following remarkable formula gives the sequence of non-square natural numbers:

", + "

n + floor(1/2 + sqrt(n))

", + "Print out the values for n in the range 1 to 22", + "Show that no squares occur for n less than one million

This sequence is also known as A000037 in the OEIS database.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "Iterative", + "", + "var a = [];", + "for (var i = 1; i < 23; i++) a[i] = i + Math.floor(1/2 + Math.sqrt(i));", + "console.log(a);", + "", + "for (i = 1; i < 1000000; i++) if (Number.isInteger(i + Math.floor(1/2 + Math.sqrt(i))) === false) {", + " console.log(\"The \",i,\"th element of the sequence is a square\");", + "}", + "", + "===ES6===", + "", + "", + "By functional composition", + "", + "(() => {", + "", + " // nonSquare :: Int -> Int", + " let nonSquare = n =>", + " n + floor(1 / 2 + sqrt(n));", + "", + "", + "", + " // floor :: Num -> Int", + " let floor = Math.floor,", + "", + " // sqrt :: Num -> Num", + " sqrt = Math.sqrt,", + "", + " // isSquare :: Int -> Bool", + " isSquare = n => {", + " let root = sqrt(n);", + "", + " return root === floor(root);", + " };", + "", + "", + " // TEST", + " return {", + " first22: Array.from({", + " length: 22", + " }, (_, i) => nonSquare(i + 1)),", + "", + " firstMillionNotSquare: Array.from({", + " length: 10E6", + " }, (_, i) => nonSquare(i + 1))", + " .filter(isSquare)", + " .length === 0", + " };", + "", + "})();", + "", + "{{Out}}", + "{", + " \"first22\":[2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15,", + " 17, 18, 19, 20, 21, 22, 23, 24, 26, 27], ", + " \"firstMillionNotSquare\":true", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fd9", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var a = [];\nfor (var i = 1; i < 23; i++) a[i] = i + Math.floor(1/2 + Math.sqrt(i));\nconsole.log(a);\n\nfor (i = 1; i < 1000000; i++) if (Number.isInteger(i + Math.floor(1/2 + Math.sqrt(i))) === false) {\n console.log(\"The \",i,\"th element of the sequence is a square\");\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sequence of primes by Trial Division", + "type": "Waypoint", + "description": [ + "Task:", + "

Generate a sequence of primes by means of trial division.

", + "

Trial division is an algorithm where a candidate number is tested for being a prime by trying to divide it by other numbers.

You may use primes, or any numbers of your choosing, as long as the result is indeed a sequence of primes.

The sequence may be bounded (i.e. up to some limit), unbounded, starting from the start (i.e. 2) or above some given value.

Organize your function as you wish, in particular, it might resemble a filtering operation, or a sieving operation.

If you want to use a ready-made is_prime function, use one from the Primality by trial division page (i.e., add yours there if it isn't there already).

", + "Related tasks:", + " count in factors", + " prime decomposition", + " factors of an integer", + " Sieve of Eratosthenes", + " primality by trial division", + " factors of a Mersenne number", + " trial factoring of a Mersenne number", + " partition an integer X into N primes" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fda", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Set consolidation", + "type": "Waypoint", + "description": [ + "

Given two sets of items then if any item is common to any set then the result of applying consolidation to those sets is a set of sets whose contents is:

", + " The two input sets if no common item exists between the two input sets of items.", + " The single set that is the union of the two input sets if they share a common item.", + "Given N sets of items where N>2 then the result is the same as repeatedly replacing all combinations of two sets by their consolidation until no further consolidation between set pairs is possible.", + "

If N<2 then consolidation has no strict meaning and the input can be returned.

Example 1:", + "

Given the two sets {A,B} and {C,D} then there is no common element between the sets and the result is the same as the input.

", + "Example 2:", + "

Given the two sets {A,B} and {B,D} then there is a common element B between the sets and the result is the single set {B,D,A}. (Note that order of items in a set is immaterial: {A,B,D} is the same as {B,D,A} and {D,A,B}, etc).

", + "Example 3:", + "

Given the three sets {A,B} and {C,D} and {D,B} then there is no common element between the sets {A,B} and {C,D} but the sets {A,B} and {D,B} do share a common element that consolidates to produce the result {B,D,A}. On examining this result with the remaining set, {C,D}, they share a common element and so consolidate to the final output of the single set {A,B,C,D}

", + "Example 4:", + "

The consolidation of the five sets:

", + "

:{H,I,K}, {A,B}, {C,D}, {D,B}, and {F,G,H}

", + "

Is the two sets:

", + "

:{A, C, B, D}, and {G, F, I, H, K}

", + "

See also

", + "Connected component (graph theory)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fdb", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Set of real numbers", + "type": "Waypoint", + "description": [ + "

All real numbers form the uncountable set ℝ. Among its subsets, relatively simple are the convex sets, each expressed as a range between two real numbers a and b where a ≤ b. There are actually four cases for the meaning of \"between\", depending on open or closed boundary:

", + "[a, b]: {x | a ≤ x and x ≤ b }", + "(a, b): {x | a < x and x < b }", + "[a, b): {x | a ≤ x and x < b }", + "(a, b]: {x | a < x and x ≤ b }Note that if a = b, of the four only [a, a] would be non-empty.

Task

", + "Devise a way to represent any set of real numbers, for the definition of 'any' in the implementation notes below.", + "Provide methods for these common set operations (x is a real number; A and B are sets):* x ∈ A: determine if x is an element of A", + "

: example: 1 is in [1, 2), while 2, 3, ... are not.

", + "

* A ∪ B: union of A and B, i.e. {x | x ∈ A or x ∈ B}

", + "

: example: [0, 2) ∪ (1, 3) = [0, 3); [0, 1) ∪ (2, 3] = well, [0, 1) ∪ (2, 3]

", + "

* A ∩ B: intersection of A and B, i.e. {x | x ∈ A and x ∈ B}

", + "

: example: [0, 2) ∩ (1, 3) = (1, 2); [0, 1) ∩ (2, 3] = empty set

", + "

* A - B: difference between A and B, also written as A \\ B, i.e. {x | x ∈ A and x ∉ B}

", + "

: example: [0, 2) − (1, 3) = [0, 1]

", + "Test your implementation by checking if numbers 0, 1, and 2 are in any of the following sets:* (0, 1] ∪ [0, 2)", + "

* [0, 2) ∩ (1, 2]

", + "

* [0, 3) − (0, 1)

", + "

* [0, 3) − [0, 1]

Implementation notes

", + "'Any' real set means 'sets that can be expressed as the union of a finite number of convex real sets'. Cantor's set needs not apply.", + "Infinities should be handled gracefully; indeterminate numbers (NaN) can be ignored.", + "You can use your machine's native real number representation, which is probably IEEE floating point, and assume it's good enough (it usually is).", + "

Optional work

", + "Create a function to determine if a given set is empty (contains no element).", + "Define A = {x | 0 < x < 10 and |sin(π x²)| > 1/2 }, B = {x | 0 < x < 10 and |sin(π x)| > 1/2}, calculate the length of the real axis covered by the set A − B. Note that |sin(π x)| > 1/2 is the same as n + 1/6 < x < n + 5/6 for all integers n; your program does not need to derive this by itself." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fdc", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Set puzzle", + "type": "Waypoint", + "description": [ + "

Set Puzzles are created with a deck of cards from the Set Game™. The object of the puzzle is to find sets of 3 cards in a rectangle of cards that have been dealt face up.

", + "

There are 81 cards in a deck.

", + "

Each card contains a unique variation of the following four features: color, symbol, number and shading.

there are three colors: red, green, purple", + "there are three symbols: oval, squiggle, diamond", + "there is a number of symbols on the card: one, two, three", + "there are three shadings: solid, open, striped", + "

Three cards form a set if each feature is either the same on each card, or is different on each card. For instance: all 3 cards are red, all 3 cards have a different symbol, all 3 cards have a different number of symbols, all 3 cards are striped.

There are two degrees of difficulty: basic and advanced. The basic mode deals 9 cards, that contain exactly 4 sets; the advanced mode deals 12 cards that contain exactly 6 sets.

When creating sets you may use the same card more than once.

", + "Task", + "

Write code that deals the cards (9 or 12, depending on selected mode) from a shuffled deck in which the total number of sets that could be found is 4 (or 6, respectively); and print the contents of the cards and the sets.

For instance:

DEALT 9 CARDS:

green, one, oval, striped

green, one, diamond, open

green, one, diamond, striped

green, one, diamond, solid

purple, one, diamond, open

purple, two, squiggle, open

purple, three, oval, open

red, three, oval, open

red, three, diamond, solid

", + "

CONTAINING 4 SETS:

green, one, oval, striped

purple, two, squiggle, open

red, three, diamond, solid

", + "

green, one, diamond, open

green, one, diamond, striped

green, one, diamond, solid

", + "

green, one, diamond, open

purple, two, squiggle, open

red, three, oval, open

", + "

purple, one, diamond, open

purple, two, squiggle, open

purple, three, oval, open

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fdd", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Set", + "type": "Waypoint", + "description": [ + "

A set is a collection of elements, without duplicates and without order.

", + "Task:", + "

Show each of these set operations:

Set creation", + "Test m ∈ S -- \"m is an element in set S\"", + "A ∪ B -- union; a set of all elements either in set A or in set B.", + "A ∩ B -- intersection; a set of all elements in both set A and set B.", + "A ∖ B -- difference; a set of all elements in set A, except those in set B.", + "A ⊆ B -- subset; true if every element in set A is also in set B.", + "A = B -- equality; true if every element of set A is in set B and vice versa.", + "

As an option, show some other set operations.

", + "(If A ⊆ B, but A ≠ B, then A is called a true or proper subset of B, written A ⊂ B or A ⊊ B.)

As another option, show how to modify a mutable set.

", + "

One might implement a set using an associative array (with set elements as array keys and some dummy value as the values).

One might also implement a set with a binary search tree, or with a hash table, or with an ordered array of binary bits (operated on with bit-wise binary operators).

The basic test, m ∈ S, is O(n) with a sequential list of elements, O(log n) with a balanced binary search tree, or (O(1) average-case, O(n) worst case) with a hash table.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "JavaScript does not support native sets before ECMAScript 6. ", + "", + "", + "var set = new Set();", + "", + "set.add(0);", + "set.add(1);", + "set.add('two');", + "set.add('three');", + "", + "set.has(0); //=> true", + "set.has(3); //=> false", + "set.has('two'); // true", + "set.has(Math.sqrt(4)); //=> false", + "set.has('TWO'.toLowerCase()); //=> true", + "", + "set.size; //=> 4", + "", + "set.delete('two');", + "set.has('two'); //==> false", + "set.size; //=> 3", + "", + "//iterating set using ES6 for..of", + "//Set order is preserved in order items are added.", + "for (var item of set) {", + " console.log('item is ' + item);", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fde", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nvar set = new Set();\n\nset.add(0);\nset.add(1);\nset.add('two');\nset.add('three');\n\nset.has(0); //=> true\nset.has(3); //=> false\nset.has('two'); // true\nset.has(Math.sqrt(4)); //=> false\nset.has('TWO'.toLowerCase()); //=> true\n\nset.size; //=> 4\n\nset.delete('two');\nset.has('two'); //==> false\nset.size; //=> 3\n\n//iterating set using ES6 for..of\n//Set order is preserved in order items are added.\nfor (var item of set) {\n console.log('item is ' + item);\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Seven-sided dice from five-sided dice", + "type": "Waypoint", + "description": [ + "Task:", + "

(Given an equal-probability generator of one of the integers 1 to 5

", + "

as dice5), create dice7 that generates a pseudo-random integer from

", + "

1 to 7 in equal probability using only dice5 as a source of random

", + "

numbers, and check the distribution for at least one million calls using the function created in Simple Random Distribution Checker.

", + "

Implementation suggestion:

", + "

dice7 might call dice5 twice, re-call if four of the 25

", + "

combinations are given, otherwise split the other 21 combinations

", + "

into 7 groups of three, and return the group index from the rolls.

(Task adapted from an answer here)

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{trans|Ruby}}", + "function dice5()", + "{", + " return 1 + Math.floor(5 * Math.random());", + "}", + "", + "function dice7()", + "{", + " while (true)", + " {", + " var dice55 = 5 * dice5() + dice5() - 6;", + " if (dice55 < 21)", + " return dice55 % 7 + 1;", + " }", + "}", + "", + "distcheck(dice5, 1000000);", + "print();", + "distcheck(dice7, 1000000);", + "{{out}}", + "
1       199792",
+      "2       200425",
+      "3       199243",
+      "4       200407",
+      "5       200133",
+      "",
+      "1       143617",
+      "2       142209",
+      "3       143023",
+      "4       142990",
+      "5       142894",
+      "6       142648",
+      "7       142619 
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fdf", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function dice5()\n{\n return 1 + Math.floor(5 * Math.random());\n}\n\nfunction dice7()\n{\n while (true)\n {\n var dice55 = 5 * dice5() + dice5() - 6;\n if (dice55 < 21)\n return dice55 % 7 + 1;\n }\n}\n\ndistcheck(dice5, 1000000);\nprint();\ndistcheck(dice7, 1000000);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "SHA-1", + "type": "Waypoint", + "description": [ + "

SHA-1 or SHA1 is a one-way hash function;

", + "

it computes a 160-bit message digest.

", + "

SHA-1 often appears in security protocols; for example,

", + "

many HTTPS websites use RSA with SHA-1 to secure their connections.

", + "

BitTorrent uses SHA-1 to verify downloads.

", + "

Git and Mercurial use SHA-1 digests to identify commits.

A US government standard, FIPS 180-1, defines SHA-1.

Find the SHA-1 message digest for a string of octets. You may either call a SHA-1 library, or implement SHA-1 in your language. Both approaches interest Rosetta Code.

{{alertbox|lightgray|Warning: SHA-1 has known weaknesses. Theoretical attacks may find a collision after 252 operations, or perhaps fewer.

", + "

This is much faster than a brute force attack of 280 operations. USgovernment deprecated SHA-1.

", + "

For production-grade cryptography, users may consider a stronger alternative, such as SHA-256 (from the SHA-2 family) or the upcoming SHA-3.}}

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fe1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "SHA-256", + "type": "Waypoint", + "description": [ + "

SHA-256 is the recommended stronger alternative to SHA-1. See FIPS PUB 180-4 for implementation details.

Either by using a dedicated library or implementing the algorithm in your language, show that the SHA-256 digest of the string \"Rosetta code\" is: 764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fe2", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Shell one-liner", + "type": "Waypoint", + "description": [ + "Task:", + "

Show how to specify and execute a short program in the language from a command shell, where the input to the command shell is only one line in length.

Avoid depending on the particular shell or operating system used as much as is reasonable; if the language has notable implementations which have different command argument syntax, or the systems those implementations run on have different styles of shells, it would be good to show multiple examples.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|SpiderMonkey}}", + "$ js -e 'print(\"hello\")'", + "hello", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fe3", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["null\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Short-circuit evaluation", + "type": "Waypoint", + "description": [ + "

Assume functions a and b return boolean values, and further, the execution of function b takes considerable resources without side effects, and is to be minimized.

If we needed to compute the conjunction (and):

", + "

::: x = a() and b()

Then it would be best to not compute the value of b() if the value of a() is computed as false, as the value of x can then only ever be false.

Similarly, if we needed to compute the disjunction (or):

", + "

::: y = a() or b()

Then it would be best to not compute the value of b() if the value of a() is computed as true, as the value of y can then only ever be true.

Some languages will stop further computation of boolean equations as soon as the result is known, so-called short-circuit evaluation of boolean expressions

", + "Task:", + "

Create two functions named a and b, that take and return the same boolean value.

The functions should also print their name whenever they are called.

Calculate and assign the values of the following equations to a variable in such a way that function b is only called when necessary:

", + "

::: x = a(i) and b(j)

", + "

::: y = a(i) or b(j)

If the language does not have short-circuit evaluation, this might be achieved with nested if statements." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "Short-circuiting evaluation of boolean expressions has been the default since the first versions of JavaScript.", + "", + "(function () {", + " 'use strict';", + "", + " function a(bool) {", + " console.log('a -->', bool);", + "", + " return bool;", + " }", + "", + " function b(bool) {", + " console.log('b -->', bool);", + "", + " return bool;", + " }", + " ", + " ", + " var x = a(false) && b(true),", + " y = a(true) || b(false),", + " z = true ? a(true) : b(false);", + " ", + " return [x, y, z];", + "})();", + "", + "The console log shows that in each case (the binding of all three values), only the left-hand part of the expression (the application of ''a(expr)'') was evaluated – ''b(expr)'' was skipped by logical short-circuiting.", + "", + "{{Out}}", + "", + "Console:", + "
/* a --> false */",
+      "/* a --> true */",
+      "/* a --> true */
", + "", + "Return value:", + "
[false, true, true]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fe4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function () {\n 'use strict';\n\n function a(bool) {\n console.log('a -->', bool);\n\n return bool;\n }\n\n function b(bool) {\n console.log('b -->', bool);\n\n return bool;\n }\n \n \n var x = a(false) && b(true),\n y = a(true) || b(false),\n z = true ? a(true) : b(false);\n \n return [x, y, z];\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sieve of Eratosthenes", + "type": "Waypoint", + "description": [ + "

The Sieve of Eratosthenes is a simple algorithm that finds the prime numbers up to a given integer.

", + "Task:", + "

Implement the Sieve of Eratosthenes algorithm, with the only allowed optimization that the outer loop can stop at the square root of the limit, and the inner loop may start at the square of the prime just found.

That means especially that you shouldn't optimize by using pre-computed wheels, i.e. don't assume you need only to cross out odd numbers (wheel based on 2), numbers equal to 1 or 5 modulo 6 (wheel based on 2 and 3), or similar wheels based on low primes.

If there's an easy way to add such a wheel based optimization, implement it as an alternative version.

", + "Note:", + "It is important that the sieve algorithm be the actual algorithm used to find prime numbers for the task.Related tasks:", + " Emirp primes", + " count in factors", + " prime decomposition", + " factors of an integer", + " extensible prime generator", + " primality by trial division", + " factors of a Mersenne number", + " trial factoring of a Mersenne number", + " partition an integer X into N primes", + " sequence of primes by Trial Division" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function eratosthenes(limit) {", + " var primes = [];", + " if (limit >= 2) {", + " var sqrtlmt = Math.sqrt(limit) - 2;", + " var nums = new Array(); // start with an empty Array...", + " for (var i = 2; i <= limit; i++) // and", + " nums.push(i); // only initialize the Array once...", + " for (var i = 0; i <= sqrtlmt; i++) {", + " var p = nums[i]", + " if (p)", + " for (var j = p * p - 2; j < nums.length; j += p)", + " nums[j] = 0;", + " }", + " for (var i = 0; i < nums.length; i++) {", + " var p = nums[i];", + " if (p)", + " primes.push(p);", + " }", + " }", + " return primes;", + "}", + "", + "var primes = eratosthenes(100);", + "", + "if (typeof print == \"undefined\")", + " print = (typeof WScript != \"undefined\") ? WScript.Echo : alert;", + "print(primes);", + "outputs:", + "
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97
", + "", + "Substituting the following code for the function for '''an odds-only algorithm using bit packing''' for the array produces code that is many times faster than the above:", + "", + "function eratosthenes(limit) {", + " var prms = [];", + " if (limit >= 2) prms = [2];", + " if (limit >= 3) {", + " var sqrtlmt = (Math.sqrt(limit) - 3) >> 1;", + " var lmt = (limit - 3) >> 1;", + " var bfsz = (lmt >> 5) + 1", + " var buf = [];", + " for (var i = 0; i < bfsz; i++)", + " buf.push(0);", + " for (var i = 0; i <= sqrtlmt; i++)", + " if ((buf[i >> 5] & (1 << (i & 31))) == 0) {", + " var p = i + i + 3;", + " for (var j = (p * p - 3) >> 1; j <= lmt; j += p)", + " buf[j >> 5] |= 1 << (j & 31);", + " }", + " for (var i = 0; i <= lmt; i++)", + " if ((buf[i >> 5] & (1 << (i & 31))) == 0)", + " prms.push(i + i + 3);", + " }", + " return prms;", + "}", + "", + "While the above code is quite fast especially using an efficient JavaScript engine such as Google Chrome's V8, it isn't as elegant as it could be using the features of the new EcmaScript6 specification when it comes out about the end of 2014 and when JavaScript engines including those of browsers implement that standard in that we might choose to implement an incremental algorithm iterators or generators similar to as implemented in Python or F# (yield). Meanwhile, we can emulate some of those features by using a simulation of an iterator class (which is easier than using a call-back function) for an '''\"infinite\" generator based on an Object dictionary''' as in the following odds-only code written as a JavaScript class:", + "", + "var SoEIncClass = (function () {", + " function SoEIncClass() {", + " this.n = 0;", + " }", + " SoEIncClass.prototype.next = function () {", + " this.n += 2;", + " if (this.n < 7) { // initialization of sequence to avoid runaway:", + " if (this.n < 3) { // only even of two:", + " this.n = 1; // odds from here...", + " return 2;", + " }", + " if (this.n < 5)", + " return 3;", + " this.dict = {}; // n must be 5...", + " this.bps = new SoEIncClass(); // new source of base primes", + " this.bps.next(); // advance past the even prime of two...", + " this.p = this.bps.next(); // first odd prime (3 in this case)", + " this.q = this.p * this.p; // set guard", + " return 5;", + " } else { // past initialization:", + " var s = this.dict[this.n]; // may or may not be defined...", + " if (!s) { // not defined:", + " if (this.n < this.q) // haven't reached the guard:", + " return this.n; // found a prime", + " else { // n === q => not prime but at guard, so:", + " var p2 = this.p << 1; // the span odds-only is twice prime", + " this.dict[this.n + p2] = p2; // add next composite of prime to dict", + " this.p = this.bps.next();", + " this.q = this.p * this.p; // get next base prime guard", + " return this.next(); // not prime so advance...", + " }", + " } else { // is a found composite of previous base prime => not prime", + " delete this.dict[this.n]; // advance to next composite of this prime:", + " var nxt = this.n + s;", + " while (this.dict[nxt]) nxt += s; // find unique empty slot in dict", + " this.dict[nxt] = s; // to put the next composite for this base prime", + " return this.next(); // not prime so advance...", + " }", + " }", + " };", + " return SoEIncClass;", + "})();", + "", + "The above code can be used to find the nth prime (which would require estimating the required range limit using the previous fixed range code) by using the following code:", + "", + "var gen = new SoEIncClass(); ", + "for (var i = 1; i < 1000000; i++, gen.next());", + "var prime = gen.next();", + " ", + "if (typeof print == \"undefined\")", + " print = (typeof WScript != \"undefined\") ? WScript.Echo : alert;", + "print(prime);", + "", + "to produce the following output (about five seconds using Google Chrome's V8 JavaScript engine):", + "", + "
15485863
", + "", + "The above code is considerably slower than the fixed range code due to the multiple method calls and the use of an object as a dictionary, which (using a hash table as its basis for most implementations) will have about a constant O(1) amortized time per operation but has quite a high constant overhead to convert the numeric indices to strings which are then hashed to be used as table keys for the look-up operations as compared to doing this more directly in implementations such as the Python dict with Python's built-in hashing functions for every supported type.", + "", + "This can be implemented as '''an \"infinite\" odds-only generator using page segmentation''' for a considerable speed-up with the alternate JavaScript class code as follows:", + "", + "var SoEPgClass = (function () {", + " function SoEPgClass() {", + " this.bi = -1; // constructor resets the enumeration to start...", + " }", + " SoEPgClass.prototype.next = function () {", + " if (this.bi < 1) {", + " if (this.bi < 0) {", + " this.bi++;", + " this.lowi = 0; // other initialization done here...", + " this.bpa = [];", + " return 2;", + " } else { // bi must be zero:", + " var nxt = 3 + (this.lowi << 1) + 262144;", + " this.buf = new Array();", + " for (var i = 0; i < 4096; i++) // faster initialization:", + " this.buf.push(0);", + " if (this.lowi <= 0) { // special culling for first page as no base primes yet:", + " for (var i = 0, p = 3, sqr = 9; sqr < nxt; i++, p += 2, sqr = p * p)", + " if ((this.buf[i >> 5] & (1 << (i & 31))) === 0)", + " for (var j = (sqr - 3) >> 1; j < 131072; j += p)", + " this.buf[j >> 5] |= 1 << (j & 31);", + " } else { // after the first page:", + " if (!this.bpa.length) { // if this is the first page after the zero one:", + " this.bps = new SoEPgClass(); // initialize separate base primes stream:", + " this.bps.next(); // advance past the only even prime of two", + " this.bpa.push(this.bps.next()); // get the next prime (3 in this case)", + " }", + " // get enough base primes for the page range...", + " for (var p = this.bpa[this.bpa.length - 1], sqr = p * p; sqr < nxt;", + " p = this.bps.next(), this.bpa.push(p), sqr = p * p) ;", + " for (var i = 0; i < this.bpa.length; i++) {", + " var p = this.bpa[i];", + " var s = (p * p - 3) >> 1;", + " if (s >= this.lowi) // adjust start index based on page lower limit...", + " s -= this.lowi;", + " else {", + " var r = (this.lowi - s) % p;", + " s = (r != 0) ? p - r : 0;", + " }", + " for (var j = s; j < 131072; j += p)", + " this.buf[j >> 5] |= 1 << (j & 31);", + " }", + " }", + " }", + " }", + " while (this.bi < 131072 && this.buf[this.bi >> 5] & (1 << (this.bi & 31)))", + " this.bi++; // find next marker still with prime status", + " if (this.bi < 131072) // within buffer: output computed prime", + " return 3 + ((this.lowi + this.bi++) << 1);", + " else { // beyond buffer range: advance buffer", + " this.bi = 0;", + " this.lowi += 131072;", + " return this.next(); // and recursively loop", + " }", + " };", + " return SoEPgClass;", + "})();", + "", + "The above code is about fifty times faster (about five seconds to calculate 50 million primes to about a billion on the Google Chrome V8 JavaScript engine) than the above dictionary based code.", + "", + "The speed for both of these \"infinite\" solutions will also respond to further wheel factorization techniques, especially for the dictionary based version where any added overhead to deal with the factorization wheel will be negligible compared to the dictionary overhead. The dictionary version would likely speed up about a factor of three or a little more with maximum wheel factorization applied; the page segmented version probably won't gain more than a factor of two and perhaps less due to the overheads of array look-up operations.", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fea", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function eratosthenes(limit) {\n var primes = [];\n if (limit >= 2) {\n var sqrtlmt = Math.sqrt(limit) - 2;\n var nums = new Array(); // start with an empty Array...\n for (var i = 2; i <= limit; i++) // and\n nums.push(i); // only initialize the Array once...\n for (var i = 0; i <= sqrtlmt; i++) {\n var p = nums[i]\n if (p)\n for (var j = p * p - 2; j < nums.length; j += p)\n nums[j] = 0;\n }\n for (var i = 0; i < nums.length; i++) {\n var p = nums[i];\n if (p)\n primes.push(p);\n }\n }\n return primes;\n}\n\nvar primes = eratosthenes(100);\n\nif (typeof print == \"undefined\")\n print = (typeof WScript != \"undefined\") ? WScript.Echo : alert;\nprint(primes);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Singleton", + "type": "Waypoint", + "description": [ + "

A Global Singleton is a class of which only one instance exists within a program.

Any attempt to use non-static members of the class involves performing operations on this one instance.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function Singleton() {", + "\tif(Singleton._instance) return Singleton._instance;", + "\tthis.set(\"\");", + "\tSingleton._instance = this;", + "}", + "", + "Singleton.prototype.set = function(msg) { this.msg = msg; }", + "Singleton.prototype.append = function(msg) { this.msg += msg; }", + "Singleton.prototype.get = function() { return this.msg; }", + "", + "", + "var a = new Singleton();", + "var b = new Singleton();", + "var c = new Singleton();", + "", + "a.set(\"Hello\");", + "b.append(\" World\");", + "c.append(\"!!!\");", + "", + "document.write( (new Singleton()).get() );", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fef", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function Singleton() {\n\tif(Singleton._instance) return Singleton._instance;\n\tthis.set(\"\");\n\tSingleton._instance = this;\n}\n\nSingleton.prototype.set = function(msg) { this.msg = msg; }\nSingleton.prototype.append = function(msg) { this.msg += msg; }\nSingleton.prototype.get = function() { return this.msg; }\n\n\nvar a = new Singleton();\nvar b = new Singleton();\nvar c = new Singleton();\n\na.set(\"Hello\");\nb.append(\" World\");\nc.append(\"!!!\");\n\ndocument.write( (new Singleton()).get() );\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Singly-linked list/Element definition", + "type": "Waypoint", + "description": [ + "

Define the data structure for a singly-linked list element. Said element should contain a data member capable of holding a numeric value, and the link to the next element should be mutable.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function LinkedList(value, next) {", + " this._value = value;", + " this._next = next;", + "}", + "LinkedList.prototype.value = function() {", + " if (arguments.length == 1) ", + " this._value = arguments[0];", + " else", + " return this._value;", + "}", + "LinkedList.prototype.next = function() {", + " if (arguments.length == 1) ", + " this._next = arguments[0];", + " else", + " return this._next;", + "}", + "", + "// convenience function to assist the creation of linked lists.", + "function createLinkedListFromArray(ary) {", + " var head = new LinkedList(ary[0], null);", + " var prev = head;", + " for (var i = 1; i < ary.length; i++) {", + " var node = new LinkedList(ary[i], null);", + " prev.next(node);", + " prev = node;", + " }", + " return head;", + "}", + "", + "var head = createLinkedListFromArray([10,20,30,40]);", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ff0", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function LinkedList(value, next) {\n this._value = value;\n this._next = next;\n}\nLinkedList.prototype.value = function() {\n if (arguments.length == 1) \n this._value = arguments[0];\n else\n return this._value;\n}\nLinkedList.prototype.next = function() {\n if (arguments.length == 1) \n this._next = arguments[0];\n else\n return this._next;\n}\n\n// convenience function to assist the creation of linked lists.\nfunction createLinkedListFromArray(ary) {\n var head = new LinkedList(ary[0], null);\n var prev = head;\n for (var i = 1; i < ary.length; i++) {\n var node = new LinkedList(ary[i], null);\n prev.next(node);\n prev = node;\n }\n return head;\n}\n\nvar head = createLinkedListFromArray([10,20,30,40]);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Singly-linked list/Element insertion", + "type": "Waypoint", + "description": [ + "

Using the link element defined in Singly-Linked List (element), define a method to insert an element into a singly-linked list following a given element.

Using this method, insert an element C into a list comprised of elements A->B, following element A.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Extending [[Singly-Linked_List_(element)#JavaScript]]", + "LinkedList.prototype.insertAfter = function(searchValue, nodeToInsert) {", + " if (this._value == searchValue) {", + " nodeToInsert.next(this.next());", + " this.next(nodeToInsert);", + " }", + " else if (this.next() == null) ", + " throw new Error(0, \"value '\" + searchValue + \"' not found in linked list.\")", + " else", + " this.next().insertAfter(searchValue, nodeToInsert);", + "}", + "var list = createLinkedListFromArray(['A','B']);", + "list.insertAfter('A', new LinkedList('C', null));", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ff1", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "LinkedList.prototype.insertAfter = function(searchValue, nodeToInsert) {\n if (this._value == searchValue) {\n nodeToInsert.next(this.next());\n this.next(nodeToInsert);\n }\n else if (this.next() == null) \n throw new Error(0, \"value '\" + searchValue + \"' not found in linked list.\")\n else\n this.next().insertAfter(searchValue, nodeToInsert);\n}\nvar list = createLinkedListFromArray(['A','B']);\nlist.insertAfter('A', new LinkedList('C', null));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Singly-linked list/Traversal", + "type": "Waypoint", + "description": [ + "

Traverse from the beginning of a singly-linked list to the end.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Extending [[Singly-Linked_List_(element)#JavaScript]]", + "LinkedList.prototype.traverse = function(func) {", + " func(this);", + " if (this.next() != null)", + " this.next().traverse(func);", + "}", + "", + "LinkedList.prototype.print = function() {", + " this.traverse( function(node) {print(node.value())} );", + "}", + "", + "var head = createLinkedListFromArray([10,20,30,40]);", + "head.print();", + "Uses the print() function from [[Rhino]]", + "", + "", + "Alternatively, translating the [[#Haskell | Haskell]] examples in terms of JavaScript's Array.map, Array.reduce, and Array.forEach:", + "", + "var map = function (fn, list) {", + " return list.map(fn);", + " },", + "", + " foldr = function (fn, acc, list) {", + " var listr = list.slice();", + " listr.reverse();", + "", + " return listr.reduce(fn, acc);", + " },", + "", + " traverse = function (list, fn) {", + " return list.forEach(fn);", + " };", + "", + "var range = function (m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(", + " function (x, i) {", + " return m + i;", + " }", + " );", + "};", + "", + "// --> [false, false, false, false, false, true, true, true, true, true]", + "map(function (x) {", + " return x > 5;", + "}, range(1, 10));", + "", + "// --> [\"Apples\", \"Oranges\", \"Mangos\", \"Pears\"]", + "map(function (x) {", + " return x + 's';", + "}, [\"Apple\", \"Orange\", \"Mango\", \"Pear\"])", + "", + "// --> 55", + "foldr(function (acc, x) {", + " return acc + x;", + "}, 0, range(1, 10))", + "", + "", + "traverse([\"Apple\", \"Orange\", \"Mango\", \"Pear\"], function (x) {", + " console.log(x);", + "})", + "/* Apple */", + "/* Orange */", + "/* Mango */", + "/* Pear */", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ff2", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "LinkedList.prototype.traverse = function(func) {\n func(this);\n if (this.next() != null)\n this.next().traverse(func);\n}\n\nLinkedList.prototype.print = function() {\n this.traverse( function(node) {print(node.value())} );\n}\n\nvar head = createLinkedListFromArray([10,20,30,40]);\nhead.print();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Smith numbers", + "type": "Waypoint", + "description": [ + "

Smith numbers are numbers such that the sum of the decimal digits of the integers that make up that number is the same as the sum of the decimal digits of its prime factors excluding 1.

By definition, all primes are excluded as they (naturally) satisfy this condition!

Smith numbers are also known as joke numbers.

", + "Example", + "

Using the number 166

", + "

Find the prime factors of 166 which are: 2 x 83

", + "

Then, take those two prime factors and sum all their decimal digits: 2 + 8 + 3 which is 13

", + "

Then, take the decimal digits of 166 and add their decimal digits: 1 + 6 + 6 which is 13

", + "

Therefore, the number 166 is a Smith number.

", + "Task", + "

Write a program to find all Smith numbers below 10000.

", + "See also", + "from Wikipedia: https://en.wikipedia.org/wiki/Smith_number Smith number.", + "from MathWorld: http://mathworld.wolfram.com/SmithNumber.html Smith number. ", + "from OEIS A6753: https://oeis.org/A006753 OEIS sequence A6753.", + "from OEIS A104170: https://oeis.org/A104170 Number of Smith numbers below 10^n. ", + "from The Prime pages: http://primes.utm.edu/glossary/xpage/SmithNumber.html Smith numbers." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS -----------------------------------------------------", + "", + " // concat :: [[a]] -> [a] | [String] -> String", + " const concat = xs => {", + " if (xs.length > 0) {", + " const unit = typeof xs[0] === 'string' ? '' : [];", + " return unit.concat.apply(unit, xs);", + " } else return [];", + " }", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // dropWhile :: (a -> Bool) -> [a] -> [a]", + " const dropWhile = (p, xs) => {", + " let i = 0;", + " for (let lng = xs.length;", + " (i < lng) && p(xs[i]); i++) {}", + " return xs.slice(i);", + " }", + "", + " // head :: [a] -> a", + " const head = xs => xs.length ? xs[0] : undefined;", + "", + " // Int -> [a] -> [a]", + " const take = (n, xs) => xs.slice(0, n);", + "", + " // drop :: Int -> [a] -> [a]", + " const drop = (n, xs) => xs.slice(n);", + "", + " // floor :: Num a => a -> Int", + " const floor = Math.floor;", + "", + " // floor :: Num -> Num", + " const sqrt = Math.sqrt;", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x, null, 2);", + "", + " // unwords :: [String] -> String", + " const unwords = xs => xs.join(' ');", + "", + "", + " // MAIN -----------------------------------------------------------------", + "", + " // primeFactors :: Int -> [Int]", + " const primeFactors = n => {", + " const fs = take(1, (dropWhile(x => n % x !== 0, range(2, floor(sqrt(n))))));", + " return fs.length === 0 ? (", + " [n]", + " ) : fs.concat(primeFactors(floor(n / head(fs))));", + " };", + "", + " // digitSum :: [Char] -> Int", + " const digitSum = ds =>", + " ds", + " .reduce((a, b) => parseInt(a, 10) + parseInt(b, 10), 0);", + "", + " // isSmith :: Int -> Bool", + " const isSmith = n => {", + " const pfs = primeFactors(n);", + " return (head(pfs) !== n) &&", + " digitSum(n.toString()", + " .split('')) == digitSum(", + " concat(pfs.map(x => x.toString()))", + " .split('')", + " );", + " }", + "", + " // TEST ------------------------------------------------------------------", + "", + " // lowSmiths :: [Int]", + " const lowSmiths = range(2, 9999)", + " .filter(isSmith);", + "", + " // lowSmithCount :: Int", + " const lowSmithCount = lowSmiths.length;", + "", + " return [", + " \"Count of Smith Numbers below 10k:\",", + " show(lowSmithCount),", + " \"\\nFirst 15 Smith Numbers:\",", + " unwords(take(15, lowSmiths)),", + " \"\\nLast 12 Smith Numbers below 10000:\",", + " unwords(drop(lowSmithCount - 12, lowSmiths))", + " ].join('\\n');", + "})();", + "{{Out}}", + "
Count of Smith Numbers below 10k:",
+      "376",
+      "",
+      "First 15 Smith Numbers:",
+      "4 22 27 58 85 94 121 166 202 265 274 319 346 355 378",
+      "",
+      "Last 12 Smith Numbers below 10000:",
+      "9778 9840 9843 9849 9861 9880 9895 9924 9942 9968 9975 9985
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ff4", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // GENERIC FUNCTIONS -----------------------------------------------------\n\n // concat :: [[a]] -> [a] | [String] -> String\n const concat = xs => {\n if (xs.length > 0) {\n const unit = typeof xs[0] === 'string' ? '' : [];\n return unit.concat.apply(unit, xs);\n } else return [];\n }\n\n // range :: Int -> Int -> [Int]\n const range = (m, n) =>\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i);\n\n // dropWhile :: (a -> Bool) -> [a] -> [a]\n const dropWhile = (p, xs) => {\n let i = 0;\n for (let lng = xs.length;\n (i < lng) && p(xs[i]); i++) {}\n return xs.slice(i);\n }\n\n // head :: [a] -> a\n const head = xs => xs.length ? xs[0] : undefined;\n\n // Int -> [a] -> [a]\n const take = (n, xs) => xs.slice(0, n);\n\n // drop :: Int -> [a] -> [a]\n const drop = (n, xs) => xs.slice(n);\n\n // floor :: Num a => a -> Int\n const floor = Math.floor;\n\n // floor :: Num -> Num\n const sqrt = Math.sqrt;\n\n // show :: a -> String\n const show = x => JSON.stringify(x, null, 2);\n\n // unwords :: [String] -> String\n const unwords = xs => xs.join(' ');\n\n\n // MAIN -----------------------------------------------------------------\n\n // primeFactors :: Int -> [Int]\n const primeFactors = n => {\n const fs = take(1, (dropWhile(x => n % x !== 0, range(2, floor(sqrt(n))))));\n return fs.length === 0 ? (\n [n]\n ) : fs.concat(primeFactors(floor(n / head(fs))));\n };\n\n // digitSum :: [Char] -> Int\n const digitSum = ds =>\n ds\n .reduce((a, b) => parseInt(a, 10) + parseInt(b, 10), 0);\n\n // isSmith :: Int -> Bool\n const isSmith = n => {\n const pfs = primeFactors(n);\n return (head(pfs) !== n) &&\n digitSum(n.toString()\n .split('')) == digitSum(\n concat(pfs.map(x => x.toString()))\n .split('')\n );\n }\n\n // TEST ------------------------------------------------------------------\n\n // lowSmiths :: [Int]\n const lowSmiths = range(2, 9999)\n .filter(isSmith);\n\n // lowSmithCount :: Int\n const lowSmithCount = lowSmiths.length;\n\n return [\n \"Count of Smith Numbers below 10k:\",\n show(lowSmithCount),\n \"\\nFirst 15 Smith Numbers:\",\n unwords(take(15, lowSmiths)),\n \"\\nLast 12 Smith Numbers below 10000:\",\n unwords(drop(lowSmithCount - 12, lowSmiths))\n ].join('\\n');\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "SOAP", + "type": "Waypoint", + "description": [ + "

In this task, the goal is to create a SOAP client which accesses functions defined at http://example.com/soap/wsdl, and calls the functions soapFunc( ) and anotherSoapFunc( ).

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ff5", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sokoban", + "type": "Waypoint", + "description": [ + "

Demonstrate how to find a solution to a given Sokoban level. For the purpose of this task (formally, a PSPACE-complete problem) any method may be used. However a move-optimal or push-optimal (or any other -optimal) solutions is preferred.

Sokoban levels are usually stored as a character array where

", + "space is an empty square", + "# is a wall", + "@ is the player", + "$ is a box", + ". is a goal", + "+ is the player on a goal", + "* is a box on a goal", + "

Sokoban solutions are usually stored in the LURD format, where lowercase l, u, r and d represent a move in that (left, up, right, down) direction and capital LURD represents a push.

Please state if you use some other format for either the input or output, and why.

For more information, see the Sokoban wiki.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ff7", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Solve a Hidato puzzle", + "type": "Waypoint", + "description": [ + "

The task is to write a program which solves Hidato (aka Hidoku) puzzles.

The rules are:

", + "You are given a grid with some numbers placed in it. The other squares in the grid will be blank.", + "* The grid is not necessarily rectangular.", + "* The grid may have holes in it.", + "* The grid is always connected.", + "* The number “1” is always present, as is another number that is equal to the number of squares in the grid. Other numbers are present so as to force the solution to be unique.", + "* It may be assumed that the difference between numbers present on the grid is not greater than lucky 13.", + "The aim is to place a natural number in each blank square so that in the sequence of numbered squares from “1” upwards, each square is in the [[wp:Moore neighborhood]] of the squares immediately before and after it in the sequence (except for the first and last squares, of course, which only have one-sided constraints).", + "* Thus, if the grid was overlaid on a chessboard, a king would be able to make legal moves along the path from first to last square in numerical order.", + "* A square may only contain one number.", + "In a proper Hidato puzzle, the solution is unique.", + "For example the following problem", + "

has the following solution, with path marked on it:

", + "Related tasks:", + "A* search algorithm", + "N-queens problem", + "Solve a Holy Knight's tour", + "Solve a Knight's tour", + "Solve a Hopido puzzle", + "Solve a Numbrix puzzle", + "Solve the no connection puzzle;" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ff8", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Solve a Holy Knight's tour", + "type": "Waypoint", + "description": [ + "

Chess coaches have been known to inflict a kind of torture on beginners by taking a chess board, placing pennies on some squares and requiring that a Knight's tour be constructed that avoids the squares with pennies.

This kind of knight's tour puzzle is similar to Hidato.

The present task is to produce a solution to such problems. At least demonstrate your program by solving the following:

Example 1", + "
",
+      "  0 0 0 ",
+      "  0   0 0 ",
+      "  0 0 0 0 0 0 0",
+      "0 0 0     0   0",
+      "0   0     0 0 0",
+      "1 0 0 0 0 0 0",
+      "    0 0   0",
+      "      0 0 0",
+      "

Note that the zeros represent the available squares, not the pennies.

Extra credit is available for other interesting examples.

", + "Related tasks:", + "A* search algorithm", + "Knight's tour", + "N-queens problem", + "Solve a Hidato puzzle", + "Solve a Hopido puzzle", + "Solve a Numbrix puzzle", + "Solve the no connection puzzle" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "By composition of generic functions, cacheing degree-sorted moves for each node.", + "(() => {", + " 'use strict';", + "", + " // problems :: [[String]]", + " const problems = [", + " [", + " \" 000 \" //", + " , \" 0 00 \" //", + " , \" 0000000\" //", + " , \"000 0 0\" //", + " , \"0 0 000\" //", + " , \"1000000 \" //", + " , \" 00 0 \" //", + " , \" 000 \" //", + " ],", + " [", + " \"-----1-0-----\" //", + " , \"-----0-0-----\" //", + " , \"----00000----\" //", + " , \"-----000-----\" //", + " , \"--0--0-0--0--\" //", + " , \"00000---00000\" //", + " , \"--00-----00--\" //", + " , \"00000---00000\" //", + " , \"--0--0-0--0--\" //", + " , \"-----000-----\" //", + " , \"----00000----\" //", + " , \"-----0-0-----\" //", + " , \"-----0-0-----\" //", + " ]", + " ];", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // comparing :: (a -> b) -> (a -> a -> Ordering)", + " const comparing = f =>", + " (x, y) => {", + " const", + " a = f(x),", + " b = f(y);", + " return a < b ? -1 : a > b ? 1 : 0", + " };", + "", + " // concat :: [[a]] -> [a] | [String] -> String", + " const concat = xs =>", + " xs.length > 0 ? (() => {", + " const unit = typeof xs[0] === 'string' ? '' : [];", + " return unit.concat.apply(unit, xs);", + " })() : [];", + "", + " // charColRow :: Char -> [String] -> Maybe (Int, Int)", + " const charColRow = (c, rows) =>", + " foldr((a, xs, iRow) =>", + " a.nothing ? (() => {", + " const mbiCol = elemIndex(c, xs);", + " return mbiCol.nothing ? mbiCol : {", + " just: [mbiCol.just, iRow],", + " nothing: false", + " };", + " })() : a, {", + " nothing: true", + " }, rows);", + "", + " // 2 or more arguments", + " // curry :: Function -> Function", + " const curry = (f, ...args) => {", + " const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :", + " function () {", + " return go(xs.concat(Array.from(arguments)));", + " };", + " return go([].slice.call(args, 1));", + " };", + "", + " // elem :: Eq a => a -> [a] -> Bool", + " const elem = (x, xs) => xs.indexOf(x) !== -1;", + "", + " // elemIndex :: Eq a => a -> [a] -> Maybe Int", + " const elemIndex = (x, xs) => {", + " const i = xs.indexOf(x);", + " return {", + " nothing: i === -1,", + " just: i", + " };", + " };", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " const enumFromTo = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // filter :: (a -> Bool) -> [a] -> [a]", + " const filter = (f, xs) => xs.filter(f);", + "", + " // findIndex :: (a -> Bool) -> [a] -> Maybe Int", + " const findIndex = (f, xs) => {", + " for (var i = 0, lng = xs.length; i < lng; i++) {", + " if (f(xs[i])) return {", + " nothing: false,", + " just: i", + " };", + " }", + " return {", + " nothing: true", + " };", + " };", + "", + " // foldl :: (b -> a -> b) -> b -> [a] -> b", + " const foldl = (f, a, xs) => xs.reduce(f, a);", + "", + " // foldr (a -> b -> b) -> b -> [a] -> b", + " const foldr = (f, a, xs) => xs.reduceRight(f, a);", + "", + " // groupBy :: (a -> a -> Bool) -> [a] -> [[a]]", + " const groupBy = (f, xs) => {", + " const dct = xs.slice(1)", + " .reduce((a, x) => {", + " const", + " h = a.active.length > 0 ? a.active[0] : undefined,", + " blnGroup = h !== undefined && f(h, x);", + " return {", + " active: blnGroup ? a.active.concat([x]) : [x],", + " sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])", + " };", + " }, {", + " active: xs.length > 0 ? [xs[0]] : [],", + " sofar: []", + " });", + " return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);", + " };", + "", + " // intercalate :: String -> [a] -> String", + " const intercalate = (s, xs) => xs.join(s);", + "", + " // intersectBy::(a - > a - > Bool) - > [a] - > [a] - > [a]", + " const intersectBy = (eq, xs, ys) =>", + " (xs.length > 0 && ys.length > 0) ?", + " xs.filter(x => ys.some(curry(eq)(x))) : [];", + "", + " // justifyRight :: Int -> Char -> Text -> Text", + " const justifyRight = (n, cFiller, strText) =>", + " n > strText.length ? (", + " (cFiller.repeat(n) + strText)", + " .slice(-n)", + " ) : strText;", + "", + " // length :: [a] -> Int", + " const length = xs => xs.length;", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // mappendComparing :: [(a -> b)] -> (a -> a -> Ordering)", + " const mappendComparing = fs => (x, y) =>", + " fs.reduce((ord, f) => {", + " if (ord !== 0) return ord;", + " const", + " a = f(x),", + " b = f(y);", + " return a < b ? -1 : a > b ? 1 : 0", + " }, 0);", + "", + " // maximumBy :: (a -> a -> Ordering) -> [a] -> a", + " const maximumBy = (f, xs) =>", + " xs.reduce((a, x) => a === undefined ? x : (", + " f(x, a) > 0 ? x : a", + " ), undefined);", + "", + " // min :: Ord a => a -> a -> a", + " const min = (a, b) => b < a ? b : a;", + "", + " // replicate :: Int -> a -> [a]", + " const replicate = (n, a) => {", + " let v = [a],", + " o = [];", + " if (n < 1) return o;", + " while (n > 1) {", + " if (n & 1) o = o.concat(v);", + " n >>= 1;", + " v = v.concat(v);", + " }", + " return o.concat(v);", + " };", + "", + " // sortBy :: (a -> a -> Ordering) -> [a] -> [a]", + " const sortBy = (f, xs) => xs.slice()", + " .sort(f);", + "", + " // splitOn :: String -> String -> [String]", + " const splitOn = (s, xs) => xs.split(s);", + "", + " // take :: Int -> [a] -> [a]", + " const take = (n, xs) => xs.slice(0, n);", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // until :: (a -> Bool) -> (a -> a) -> a -> a", + " const until = (p, f, x) => {", + " let v = x;", + " while (!p(v)) v = f(v);", + " return v;", + " };", + "", + " // zip :: [a] -> [b] -> [(a,b)]", + " const zip = (xs, ys) =>", + " xs.slice(0, Math.min(xs.length, ys.length))", + " .map((x, i) => [x, ys[i]]);", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) =>", + " Array.from({", + " length: min(xs.length, ys.length)", + " }, (_, i) => f(xs[i], ys[i]));", + "", + " // HOLY KNIGHT's TOUR FUNCTIONS -------------------------------------------", + "", + " // kmoves :: (Int, Int) -> [(Int, Int)]", + " const kmoves = ([x, y]) => map(", + " ([a, b]) => [a + x, b + y], [", + " [1, 2],", + " [1, -2],", + " [-1, 2],", + " [-1, -2],", + " [2, 1],", + " [2, -1],", + " [-2, 1],", + " [-2, -1]", + " ]);", + "", + " // rowPosns :: Int -> String -> [(Int, Int)]", + " const rowPosns = (iRow, s) => {", + " return foldl((a, x, i) => (elem(x, ['0', '1']) ? (", + " a.concat([", + " [i, iRow]", + " ])", + " ) : a), [], splitOn('', s));", + " };", + "", + " // hash :: (Int, Int) -> String", + " const hash = ([col, row]) => col.toString() + '.' + row.toString();", + "", + " // Start node, and degree-sorted cache of moves from each node", + " // All node references are hash strings (for this cache)", + "", + " // problemModel :: [[String]] -> {cache: {nodeKey: [nodeKey], start:String}}", + " const problemModel = boardLines => {", + " const", + " steps = foldl((a, xs, i) =>", + " a.concat(rowPosns(i, xs)), [], boardLines),", + " courseMoves = (xs, [x, y]) => intersectBy(", + " ([a, b], [c, d]) => a === c && b === d, kmoves([x, y]), xs", + " ),", + " maybeStart = charColRow('1', boardLines);", + " return {", + " start: maybeStart.nothing ? '' : hash(maybeStart.just),", + " boardWidth: boardLines.length > 0 ? boardLines[0].length : 0,", + " stepCount: steps.length,", + " cache: (() => {", + " const moveCache = foldl((a, xy) => (", + " a[hash(xy)] = map(hash, courseMoves(steps, xy)),", + " a", + " ), {}, steps),", + " lstMoves = Object.keys(moveCache),", + " dctDegree = foldl((a, k) =>", + " (a[k] = moveCache[k].length,", + " a), {}, lstMoves);", + "", + " return foldl((a, k) => (", + " a[k] = sortBy(comparing(x => dctDegree[x]), moveCache[k]),", + " a", + " ), {}, lstMoves);", + " })()", + " };", + " };", + "", + " // firstSolution :: {nodeKey: [nodeKey]} -> Int ->", + " // nodeKey -> nodeKey -> [nodeKey] ->", + " // -> {path::[nodeKey], pathLen::Int, found::Bool}", + " const firstSolution = (dctMoves, intTarget, strStart, strNodeKey, path) => {", + " const", + " intPath = path.length,", + " moves = dctMoves[strNodeKey];", + "", + " if ((intTarget - intPath) < 2 && elem(strStart, moves)) {", + " return {", + " nothing: false,", + " just: [strStart, strNodeKey].concat(path),", + " pathLen: intTarget", + " };", + " }", + "", + " const", + " nexts = filter(k => !elem(k, path), moves),", + " intNexts = nexts.length,", + " lstFullPath = [strNodeKey].concat(path);", + "", + " // Until we find a full path back to start", + " return until(", + " x => (x.nothing === false || x.i >= intNexts),", + " x => {", + " const", + " idx = x.i,", + " dctSoln = firstSolution(", + " dctMoves, intTarget, strStart, nexts[idx], lstFullPath", + " );", + " return {", + " i: idx + 1,", + " nothing: dctSoln.nothing,", + " just: dctSoln.just,", + " pathLen: dctSoln.pathLen", + " };", + " }, {", + " nothing: true,", + " just: [],", + " i: 0", + " }", + " );", + " };", + "", + " // maybeTour :: [String] -> {", + " // nothing::Bool, Just::[nodeHash], i::Int: pathLen::Int }", + " const maybeTour = trackLines => {", + " const", + " dctModel = problemModel(trackLines),", + " strStart = dctModel.start;", + " return strStart !== '' ? firstSolution(", + " dctModel.cache, dctModel.stepCount, strStart, strStart, []", + " ) : {", + " nothing: true", + " };", + " };", + "", + " // showLine :: Int -> Int -> String -> Maybe (Int, Int) ->", + " // [(Int, Int, String)] -> String", + " const showLine = curry((intCell, strFiller, maybeStart, xs) => {", + " const", + " blnSoln = maybeStart.nothing,", + " [startCol, startRow] = blnSoln ? [0, 0] : maybeStart.just;", + " return foldl((a, [iCol, iRow, sVal], i, xs) => ({", + " col: iCol + 1,", + " txt: a.txt +", + " concat(replicate((iCol - a.col) * intCell, strFiller)) +", + " justifyRight(", + " intCell, strFiller,", + " (blnSoln ? sVal : (", + " iRow === startRow &&", + " iCol === startCol ? '1' : '0')", + " )", + " )", + " }), {", + " col: 0,", + " txt: ''", + " },", + " xs", + " )", + " .txt", + " });", + "", + " // solutionString :: [String] -> Int -> String", + " const solutionString = (boardLines, iProblem) => {", + " const", + " dtePre = Date.now(),", + " intCols = boardLines.length > 0 ? boardLines[0].length : 0,", + " soln = maybeTour(boardLines),", + " intMSeconds = Date.now() - dtePre;", + "", + " if (soln.nothing) return 'No solution found …';", + "", + " const", + " kCol = 0,", + " kRow = 1,", + " kSeq = 2,", + " steps = soln.just,", + " lstTriples = zipWith((h, n) => {", + " const [col, row] = map(", + " x => parseInt(x, 10), splitOn('.', h)", + " );", + " return [col, row, n.toString()];", + " },", + " steps,", + " enumFromTo(1, soln.pathLen)),", + " cellWidth = length(maximumBy(", + " comparing(x => length(x[kSeq])), lstTriples", + " )[kSeq]) + 1,", + " lstGroups = groupBy(", + " (a, b) => a[kRow] === b[kRow],", + " sortBy(", + " mappendComparing([x => x[kRow], x => x[kCol]]),", + " lstTriples", + " )),", + " startXY = take(2, lstTriples[0]),", + " strMap = 'PROBLEM ' + (parseInt(iProblem, 10) + 1) + '.\\n\\n' +", + " unlines(map(showLine(cellWidth, ' ', {", + " nothing: false,", + " just: startXY", + " }), lstGroups)),", + " strSoln = 'First solution found in c. ' +", + " intMSeconds + ' milliseconds:\\n\\n' +", + " unlines(map(showLine(cellWidth, ' ', {", + " nothing: true,", + " just: startXY", + " }), lstGroups)) + '\\n\\n';", + "", + " console.log(strSoln);", + " return strMap + '\\n\\n' + strSoln;", + " };", + "", + " // TEST -------------------------------------------------------------------", + " return unlines(map(solutionString, problems));", + "})();", + "{{Out}}", + "(Executed in Atom editor, using 'Script' package).", + "
PROBLEM 1.",
+      "",
+      "     0  0  0",
+      "     0     0  0",
+      "     0  0  0  0  0  0  0",
+      "  0  0  0        0     0",
+      "  0     0        0  0  0",
+      "  1  0  0  0  0  0  0",
+      "        0  0     0",
+      "           0  0  0",
+      "",
+      "First solution found in c. 21 milliseconds:",
+      "",
+      "    25 14 23",
+      "     8    26 15",
+      "    13 24  7 22 27 16 31",
+      "  9 36 11       30    28",
+      " 12     6       21 32 17",
+      "  1 10 35 20  3 18 29",
+      "        2  5    33",
+      "          34 19  4",
+      "",
+      "",
+      "PROBLEM 2.",
+      "",
+      "                 1     0",
+      "                 0     0",
+      "              0  0  0  0  0",
+      "                 0  0  0",
+      "        0        0     0        0",
+      "  0  0  0  0  0           0  0  0  0  0",
+      "        0  0                 0  0",
+      "  0  0  0  0  0           0  0  0  0  0",
+      "        0        0     0        0",
+      "                 0  0  0",
+      "              0  0  0  0  0",
+      "                 0     0",
+      "                 0     0",
+      "",
+      "First solution found in c. 7084 milliseconds:",
+      "",
+      "                 1     3",
+      "                50    52",
+      "             56 53  2 49  4",
+      "                48 51 54",
+      "       46       55     5       10",
+      " 45 42 35 40 47          11  6 13  8 15",
+      "       44 37                 9 16",
+      " 43 36 41 34 39          19 12  7 14 17",
+      "       38       33    27       18",
+      "                26 23 20",
+      "             32 21 30 25 28",
+      "                24    22",
+      "                31    29",
+      "",
+      "",
+      "[Finished in 7.2s]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ff9", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // problems :: [[String]]\n const problems = [\n [\n \" 000 \" //\n , \" 0 00 \" //\n , \" 0000000\" //\n , \"000 0 0\" //\n , \"0 0 000\" //\n , \"1000000 \" //\n , \" 00 0 \" //\n , \" 000 \" //\n ],\n [\n \"-----1-0-----\" //\n , \"-----0-0-----\" //\n , \"----00000----\" //\n , \"-----000-----\" //\n , \"--0--0-0--0--\" //\n , \"00000---00000\" //\n , \"--00-----00--\" //\n , \"00000---00000\" //\n , \"--0--0-0--0--\" //\n , \"-----000-----\" //\n , \"----00000----\" //\n , \"-----0-0-----\" //\n , \"-----0-0-----\" //\n ]\n ];\n\n // GENERIC FUNCTIONS ------------------------------------------------------\n\n // comparing :: (a -> b) -> (a -> a -> Ordering)\n const comparing = f =>\n (x, y) => {\n const\n a = f(x),\n b = f(y);\n return a < b ? -1 : a > b ? 1 : 0\n };\n\n // concat :: [[a]] -> [a] | [String] -> String\n const concat = xs =>\n xs.length > 0 ? (() => {\n const unit = typeof xs[0] === 'string' ? '' : [];\n return unit.concat.apply(unit, xs);\n })() : [];\n\n // charColRow :: Char -> [String] -> Maybe (Int, Int)\n const charColRow = (c, rows) =>\n foldr((a, xs, iRow) =>\n a.nothing ? (() => {\n const mbiCol = elemIndex(c, xs);\n return mbiCol.nothing ? mbiCol : {\n just: [mbiCol.just, iRow],\n nothing: false\n };\n })() : a, {\n nothing: true\n }, rows);\n\n // 2 or more arguments\n // curry :: Function -> Function\n const curry = (f, ...args) => {\n const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :\n function () {\n return go(xs.concat(Array.from(arguments)));\n };\n return go([].slice.call(args, 1));\n };\n\n // elem :: Eq a => a -> [a] -> Bool\n const elem = (x, xs) => xs.indexOf(x) !== -1;\n\n // elemIndex :: Eq a => a -> [a] -> Maybe Int\n const elemIndex = (x, xs) => {\n const i = xs.indexOf(x);\n return {\n nothing: i === -1,\n just: i\n };\n };\n\n // enumFromTo :: Int -> Int -> [Int]\n const enumFromTo = (m, n) =>\n Array.from({\n length: Math.floor(n - m) + 1\n }, (_, i) => m + i);\n\n // filter :: (a -> Bool) -> [a] -> [a]\n const filter = (f, xs) => xs.filter(f);\n\n // findIndex :: (a -> Bool) -> [a] -> Maybe Int\n const findIndex = (f, xs) => {\n for (var i = 0, lng = xs.length; i < lng; i++) {\n if (f(xs[i])) return {\n nothing: false,\n just: i\n };\n }\n return {\n nothing: true\n };\n };\n\n // foldl :: (b -> a -> b) -> b -> [a] -> b\n const foldl = (f, a, xs) => xs.reduce(f, a);\n\n // foldr (a -> b -> b) -> b -> [a] -> b\n const foldr = (f, a, xs) => xs.reduceRight(f, a);\n\n // groupBy :: (a -> a -> Bool) -> [a] -> [[a]]\n const groupBy = (f, xs) => {\n const dct = xs.slice(1)\n .reduce((a, x) => {\n const\n h = a.active.length > 0 ? a.active[0] : undefined,\n blnGroup = h !== undefined && f(h, x);\n return {\n active: blnGroup ? a.active.concat([x]) : [x],\n sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])\n };\n }, {\n active: xs.length > 0 ? [xs[0]] : [],\n sofar: []\n });\n return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);\n };\n\n // intercalate :: String -> [a] -> String\n const intercalate = (s, xs) => xs.join(s);\n\n // intersectBy::(a - > a - > Bool) - > [a] - > [a] - > [a]\n const intersectBy = (eq, xs, ys) =>\n (xs.length > 0 && ys.length > 0) ?\n xs.filter(x => ys.some(curry(eq)(x))) : [];\n\n // justifyRight :: Int -> Char -> Text -> Text\n const justifyRight = (n, cFiller, strText) =>\n n > strText.length ? (\n (cFiller.repeat(n) + strText)\n .slice(-n)\n ) : strText;\n\n // length :: [a] -> Int\n const length = xs => xs.length;\n\n // map :: (a -> b) -> [a] -> [b]\n const map = (f, xs) => xs.map(f);\n\n // mappendComparing :: [(a -> b)] -> (a -> a -> Ordering)\n const mappendComparing = fs => (x, y) =>\n fs.reduce((ord, f) => {\n if (ord !== 0) return ord;\n const\n a = f(x),\n b = f(y);\n return a < b ? -1 : a > b ? 1 : 0\n }, 0);\n\n // maximumBy :: (a -> a -> Ordering) -> [a] -> a\n const maximumBy = (f, xs) =>\n xs.reduce((a, x) => a === undefined ? x : (\n f(x, a) > 0 ? x : a\n ), undefined);\n\n // min :: Ord a => a -> a -> a\n const min = (a, b) => b < a ? b : a;\n\n // replicate :: Int -> a -> [a]\n const replicate = (n, a) => {\n let v = [a],\n o = [];\n if (n < 1) return o;\n while (n > 1) {\n if (n & 1) o = o.concat(v);\n n >>= 1;\n v = v.concat(v);\n }\n return o.concat(v);\n };\n\n // sortBy :: (a -> a -> Ordering) -> [a] -> [a]\n const sortBy = (f, xs) => xs.slice()\n .sort(f);\n\n // splitOn :: String -> String -> [String]\n const splitOn = (s, xs) => xs.split(s);\n\n // take :: Int -> [a] -> [a]\n const take = (n, xs) => xs.slice(0, n);\n\n // unlines :: [String] -> String\n const unlines = xs => xs.join('\\n');\n\n // until :: (a -> Bool) -> (a -> a) -> a -> a\n const until = (p, f, x) => {\n let v = x;\n while (!p(v)) v = f(v);\n return v;\n };\n\n // zip :: [a] -> [b] -> [(a,b)]\n const zip = (xs, ys) =>\n xs.slice(0, Math.min(xs.length, ys.length))\n .map((x, i) => [x, ys[i]]);\n\n // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]\n const zipWith = (f, xs, ys) =>\n Array.from({\n length: min(xs.length, ys.length)\n }, (_, i) => f(xs[i], ys[i]));\n\n // HOLY KNIGHT's TOUR FUNCTIONS -------------------------------------------\n\n // kmoves :: (Int, Int) -> [(Int, Int)]\n const kmoves = ([x, y]) => map(\n ([a, b]) => [a + x, b + y], [\n [1, 2],\n [1, -2],\n [-1, 2],\n [-1, -2],\n [2, 1],\n [2, -1],\n [-2, 1],\n [-2, -1]\n ]);\n\n // rowPosns :: Int -> String -> [(Int, Int)]\n const rowPosns = (iRow, s) => {\n return foldl((a, x, i) => (elem(x, ['0', '1']) ? (\n a.concat([\n [i, iRow]\n ])\n ) : a), [], splitOn('', s));\n };\n\n // hash :: (Int, Int) -> String\n const hash = ([col, row]) => col.toString() + '.' + row.toString();\n\n // Start node, and degree-sorted cache of moves from each node\n // All node references are hash strings (for this cache)\n\n // problemModel :: [[String]] -> {cache: {nodeKey: [nodeKey], start:String}}\n const problemModel = boardLines => {\n const\n steps = foldl((a, xs, i) =>\n a.concat(rowPosns(i, xs)), [], boardLines),\n courseMoves = (xs, [x, y]) => intersectBy(\n ([a, b], [c, d]) => a === c && b === d, kmoves([x, y]), xs\n ),\n maybeStart = charColRow('1', boardLines);\n return {\n start: maybeStart.nothing ? '' : hash(maybeStart.just),\n boardWidth: boardLines.length > 0 ? boardLines[0].length : 0,\n stepCount: steps.length,\n cache: (() => {\n const moveCache = foldl((a, xy) => (\n a[hash(xy)] = map(hash, courseMoves(steps, xy)),\n a\n ), {}, steps),\n lstMoves = Object.keys(moveCache),\n dctDegree = foldl((a, k) =>\n (a[k] = moveCache[k].length,\n a), {}, lstMoves);\n\n return foldl((a, k) => (\n a[k] = sortBy(comparing(x => dctDegree[x]), moveCache[k]),\n a\n ), {}, lstMoves);\n })()\n };\n };\n\n // firstSolution :: {nodeKey: [nodeKey]} -> Int ->\n // nodeKey -> nodeKey -> [nodeKey] ->\n // -> {path::[nodeKey], pathLen::Int, found::Bool}\n const firstSolution = (dctMoves, intTarget, strStart, strNodeKey, path) => {\n const\n intPath = path.length,\n moves = dctMoves[strNodeKey];\n\n if ((intTarget - intPath) < 2 && elem(strStart, moves)) {\n return {\n nothing: false,\n just: [strStart, strNodeKey].concat(path),\n pathLen: intTarget\n };\n }\n\n const\n nexts = filter(k => !elem(k, path), moves),\n intNexts = nexts.length,\n lstFullPath = [strNodeKey].concat(path);\n\n // Until we find a full path back to start\n return until(\n x => (x.nothing === false || x.i >= intNexts),\n x => {\n const\n idx = x.i,\n dctSoln = firstSolution(\n dctMoves, intTarget, strStart, nexts[idx], lstFullPath\n );\n return {\n i: idx + 1,\n nothing: dctSoln.nothing,\n just: dctSoln.just,\n pathLen: dctSoln.pathLen\n };\n }, {\n nothing: true,\n just: [],\n i: 0\n }\n );\n };\n\n // maybeTour :: [String] -> {\n // nothing::Bool, Just::[nodeHash], i::Int: pathLen::Int }\n const maybeTour = trackLines => {\n const\n dctModel = problemModel(trackLines),\n strStart = dctModel.start;\n return strStart !== '' ? firstSolution(\n dctModel.cache, dctModel.stepCount, strStart, strStart, []\n ) : {\n nothing: true\n };\n };\n\n // showLine :: Int -> Int -> String -> Maybe (Int, Int) ->\n // [(Int, Int, String)] -> String\n const showLine = curry((intCell, strFiller, maybeStart, xs) => {\n const\n blnSoln = maybeStart.nothing,\n [startCol, startRow] = blnSoln ? [0, 0] : maybeStart.just;\n return foldl((a, [iCol, iRow, sVal], i, xs) => ({\n col: iCol + 1,\n txt: a.txt +\n concat(replicate((iCol - a.col) * intCell, strFiller)) +\n justifyRight(\n intCell, strFiller,\n (blnSoln ? sVal : (\n iRow === startRow &&\n iCol === startCol ? '1' : '0')\n )\n )\n }), {\n col: 0,\n txt: ''\n },\n xs\n )\n .txt\n });\n\n // solutionString :: [String] -> Int -> String\n const solutionString = (boardLines, iProblem) => {\n const\n dtePre = Date.now(),\n intCols = boardLines.length > 0 ? boardLines[0].length : 0,\n soln = maybeTour(boardLines),\n intMSeconds = Date.now() - dtePre;\n\n if (soln.nothing) return 'No solution found …';\n\n const\n kCol = 0,\n kRow = 1,\n kSeq = 2,\n steps = soln.just,\n lstTriples = zipWith((h, n) => {\n const [col, row] = map(\n x => parseInt(x, 10), splitOn('.', h)\n );\n return [col, row, n.toString()];\n },\n steps,\n enumFromTo(1, soln.pathLen)),\n cellWidth = length(maximumBy(\n comparing(x => length(x[kSeq])), lstTriples\n )[kSeq]) + 1,\n lstGroups = groupBy(\n (a, b) => a[kRow] === b[kRow],\n sortBy(\n mappendComparing([x => x[kRow], x => x[kCol]]),\n lstTriples\n )),\n startXY = take(2, lstTriples[0]),\n strMap = 'PROBLEM ' + (parseInt(iProblem, 10) + 1) + '.\\n\\n' +\n unlines(map(showLine(cellWidth, ' ', {\n nothing: false,\n just: startXY\n }), lstGroups)),\n strSoln = 'First solution found in c. ' +\n intMSeconds + ' milliseconds:\\n\\n' +\n unlines(map(showLine(cellWidth, ' ', {\n nothing: true,\n just: startXY\n }), lstGroups)) + '\\n\\n';\n\n console.log(strSoln);\n return strMap + '\\n\\n' + strSoln;\n };\n\n // TEST -------------------------------------------------------------------\n return unlines(map(solutionString, problems));\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Solve a Hopido puzzle", + "type": "Waypoint", + "description": [ + "

Hopido puzzles are similar to Hidato. The most important difference is that the only moves allowed are: hop over one tile diagonally; and over two tiles horizontally and vertically. It should be possible to start anywhere in the path, the end point isn't indicated and there are no intermediate clues. Hopido Design Post Mortem contains the following:

\"Big puzzles represented another problem. Up until quite late in the project our puzzle solver was painfully slow with most puzzles above 7×7 tiles. Testing the solution from each starting point could take hours. If the tile layout was changed even a little, the whole puzzle had to be tested again. We were just about to give up the biggest puzzles entirely when our programmer suddenly came up with a magical algorithm that cut the testing process down to only minutes. Hooray!\"

Knowing the kindness in the heart of every contributor to Rosetta Code, I know that we shall feel that as an act of humanity we must solve these puzzles for them in let's say milliseconds.

Example:

. 0 0 . 0 0 .

", + "

0 0 0 0 0 0 0

", + "

0 0 0 0 0 0 0

", + "

. 0 0 0 0 0 .

", + "

. . 0 0 0 . .

", + "

. . . 0 . . .

Extra credits are available for other interesting designs.

", + "Related tasks:", + "A* search algorithm", + "Solve a Holy Knight's tour", + "Knight's tour", + "N-queens problem", + "Solve a Hidato puzzle", + "Solve a Holy Knight's tour", + "Solve a Numbrix puzzle", + "Solve the no connection puzzle" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ffa", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Solve a Numbrix puzzle", + "type": "Waypoint", + "description": [ + "

Numbrix puzzles are similar to Hidato.

", + "

The most important difference is that it is only possible to move 1 node left, right, up, or down (sometimes referred to as the Von Neumann neighborhood).

", + "

Published puzzles also tend not to have holes in the grid and may not always indicate the end node.

", + "

Two examples follow:

Example 1", + "

Problem.

", + "
",
+      " 0  0  0  0  0  0  0  0  0",
+      " 0  0 46 45  0 55 74  0  0",
+      " 0 38  0  0 43  0  0 78  0",
+      " 0 35  0  0  0  0  0 71  0",
+      " 0  0 33  0  0  0 59  0  0",
+      " 0 17  0  0  0  0  0 67  0",
+      " 0 18  0  0 11  0  0 64  0",
+      " 0  0 24 21  0  1  2  0  0",
+      " 0  0  0  0  0  0  0  0  0",
+      "
", + "

Solution.

", + "
",
+      " 49 50 51 52 53 54 75 76 81",
+      " 48 47 46 45 44 55 74 77 80",
+      " 37 38 39 40 43 56 73 78 79",
+      " 36 35 34 41 42 57 72 71 70",
+      " 31 32 33 14 13 58 59 68 69",
+      " 30 17 16 15 12 61 60 67 66",
+      " 29 18 19 20 11 62 63 64 65",
+      " 28 25 24 21 10  1  2  3  4",
+      " 27 26 23 22  9  8  7  6  5",
+      "
", + "Example 2", + "

Problem.

", + "
",
+      " 0  0  0  0  0  0  0  0  0",
+      " 0 11 12 15 18 21 62 61  0",
+      " 0  6  0  0  0  0  0 60  0",
+      " 0 33  0  0  0  0  0 57  0",
+      " 0 32  0  0  0  0  0 56  0",
+      " 0 37  0  1  0  0  0 73  0",
+      " 0 38  0  0  0  0  0 72  0",
+      " 0 43 44 47 48 51 76 77  0",
+      " 0  0  0  0  0  0  0  0  0",
+      "
", + "

Solution.

", + "
",
+      "  9 10 13 14 19 20 63 64 65",
+      "  8 11 12 15 18 21 62 61 66",
+      "  7  6  5 16 17 22 59 60 67",
+      " 34 33  4  3 24 23 58 57 68",
+      " 35 32 31  2 25 54 55 56 69",
+      " 36 37 30  1 26 53 74 73 70",
+      " 39 38 29 28 27 52 75 72 71",
+      " 40 43 44 47 48 51 76 77 78",
+      " 41 42 45 46 49 50 81 80 79",
+      "
", + "Task", + "

Write a program to solve puzzles of this ilk,

", + "

demonstrating your program by solving the above examples.

", + "

Extra credit for other interesting examples.

", + "Related tasks:", + "A* search algorithm", + "Solve a Holy Knight's tour", + "Knight's tour", + "N-queens problem", + "Solve a Hidato puzzle", + "Solve a Holy Knight's tour", + "Solve a Hopido puzzle", + "Solve the no connection puzzle" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ffb", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Solve the no connection puzzle", + "type": "Waypoint", + "description": [ + "

You are given a box with eight holes labelled A-to-H, connected by fifteen

", + "

straight lines in the pattern as shown

A B

", + "

/|\\ /|\\

", + "

/ | X | \\

", + "

/ |/ \\| \\

", + "

C - D - E - F

", + "

\\ |\\ /| /

", + "

\\ | X | /

", + "

\\|/ \\|/

", + "

G H

You are also given eight pegs numbered 1-to-8. The idea is to place the pegs in

", + "

the holes so that the (absolute) difference between any two numbers connected by

", + "

any line is greater than one.

For example, in this attempt:

4 7

", + "

/|\\ /|\\

", + "

/ | X | \\

", + "

/ |/ \\| \\

", + "

8 - 1 - 6 - 2

", + "

\\ |\\ /| /

", + "

\\ | X | /

", + "

\\|/ \\|/

", + "

3 5

Note that 7 and 6 are connected and have a difference of 1 so it is not a solution.

", + "Task", + "

Produce and show here one solution to the puzzle.

", + "Related tasks:", + "A* search algorithm", + "Solve a Holy Knight's tour", + "Knight's tour", + "N-queens problem", + "Solve a Hidato puzzle", + "Solve a Holy Knight's tour", + "Solve a Hopido puzzle", + "Solve a Numbrix puzzle", + "4-rings or 4-squares puzzle", + "See also", + "

No Connection Puzzle (youtube).

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // abs :: Num a => a -> a", + " const abs = Math.abs;", + "", + " // all :: (a -> Bool) -> [a] -> Bool", + " const all = (f, xs) => xs.every(f);", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " const concatMap = (f, xs) => [].concat.apply([], xs.map(f));", + "", + " // delete_ :: Eq a => a -> [a] -> [a]", + " const delete_ = (x, xs) =>", + " deleteBy((a, b) => a === b, x, xs);", + "", + " // deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]", + " const deleteBy = (f, x, xs) =>", + " xs.length > 0 ? (", + " f(x, xs[0]) ? (", + " xs.slice(1)", + " ) : [xs[0]].concat(deleteBy(f, x, xs.slice(1)))", + " ) : [];", + "", + " // enumFromTo :: Enum a => a -> a -> [a]", + " const enumFromTo = (m, n) => {", + " const [tm, tn] = [typeof m, typeof n];", + " return tm !== tn ? undefined : (() => {", + " const", + " blnS = (tm === 'string'),", + " [base, end] = [m, n].map(blnS ? (s => s.codePointAt(0)) : id);", + " return Array.from({", + " length: Math.floor(end - base) + 1", + " }, (_, i) => blnS ? String.fromCodePoint(base + i) : m + i);", + " })();", + " };", + "", + " // id :: a -> a", + " const id = x => x;", + "", + " // justifyRight :: Int -> Char -> Text -> Text", + " const justifyRight = (n, cFiller, strText) =>", + " n > strText.length ? (", + " (cFiller.repeat(n) + strText)", + " .slice(-n)", + " ) : strText;", + "", + " // permutations :: [a] -> [[a]]", + " const permutations = xs =>", + " xs.length ? concatMap(x => concatMap(ys => [", + " [x].concat(ys)", + " ],", + " permutations(delete_(x, xs))), xs) : [", + " []", + " ];", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x);", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // until :: (a -> Bool) -> (a -> a) -> a -> a", + " const until = (p, f, x) => {", + " let v = x;", + " while (!p(v)) v = f(v);", + " return v;", + " };", + "", + " // unwords :: [String] -> String", + " const unwords = xs => xs.join(' ');", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) => {", + " const ny = ys.length;", + " return (xs.length <= ny ? xs : xs.slice(0, ny))", + " .map((x, i) => f(x, ys[i]));", + " };", + "", + "", + " // CONNECTION PUZZLE ------------------------------------------------------", + "", + " // universe :: [[Int]]", + " const universe = permutations(enumFromTo(1, 8));", + "", + " // isSolution :: [Int] -> Bool", + " const isSolution = ([a, b, c, d, e, f, g, h]) =>", + " all(x => abs(x) > 1, [a - d, c - d, g - d, e - d, a - c, c - g, g - e,", + " e - a, b - e, d - e, h - e, f - e, b - d, d - h, h - f, f - b", + " ]);", + "", + " // firstSolution :: [Int]", + " const firstSolution = universe[until(", + " i => isSolution(universe[i]),", + " i => i + 1,", + " 0", + " )];", + "", + " // TEST -------------------------------------------------------------------", + "", + " // [Int]", + " const [a, b, c, d, e, f, g, h] = firstSolution;", + "", + " return unlines(", + " zipWith(", + " (a, n) => a + ' = ' + n.toString(),", + " enumFromTo('A', 'H'),", + " firstSolution", + " )", + " .concat(", + " [", + " [],", + " [a, b],", + " [c, d, e, f],", + " [g, h]", + " ].map(xs => justifyRight(5, ' ', unwords(xs.map(show))))", + " )", + " );", + "})();", + "{{Out}}", + "
A = 3",
+      "B = 4",
+      "C = 7",
+      "D = 1",
+      "E = 8",
+      "F = 2",
+      "G = 5",
+      "H = 6",
+      "     ",
+      "  3 4",
+      "7 1 8 2",
+      "  5 6
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ffc", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // GENERIC FUNCTIONS ------------------------------------------------------\n\n // abs :: Num a => a -> a\n const abs = Math.abs;\n\n // all :: (a -> Bool) -> [a] -> Bool\n const all = (f, xs) => xs.every(f);\n\n // concatMap :: (a -> [b]) -> [a] -> [b]\n const concatMap = (f, xs) => [].concat.apply([], xs.map(f));\n\n // delete_ :: Eq a => a -> [a] -> [a]\n const delete_ = (x, xs) =>\n deleteBy((a, b) => a === b, x, xs);\n\n // deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]\n const deleteBy = (f, x, xs) =>\n xs.length > 0 ? (\n f(x, xs[0]) ? (\n xs.slice(1)\n ) : [xs[0]].concat(deleteBy(f, x, xs.slice(1)))\n ) : [];\n\n // enumFromTo :: Enum a => a -> a -> [a]\n const enumFromTo = (m, n) => {\n const [tm, tn] = [typeof m, typeof n];\n return tm !== tn ? undefined : (() => {\n const\n blnS = (tm === 'string'),\n [base, end] = [m, n].map(blnS ? (s => s.codePointAt(0)) : id);\n return Array.from({\n length: Math.floor(end - base) + 1\n }, (_, i) => blnS ? String.fromCodePoint(base + i) : m + i);\n })();\n };\n\n // id :: a -> a\n const id = x => x;\n\n // justifyRight :: Int -> Char -> Text -> Text\n const justifyRight = (n, cFiller, strText) =>\n n > strText.length ? (\n (cFiller.repeat(n) + strText)\n .slice(-n)\n ) : strText;\n\n // permutations :: [a] -> [[a]]\n const permutations = xs =>\n xs.length ? concatMap(x => concatMap(ys => [\n [x].concat(ys)\n ],\n permutations(delete_(x, xs))), xs) : [\n []\n ];\n\n // show :: a -> String\n const show = x => JSON.stringify(x);\n\n // unlines :: [String] -> String\n const unlines = xs => xs.join('\\n');\n\n // until :: (a -> Bool) -> (a -> a) -> a -> a\n const until = (p, f, x) => {\n let v = x;\n while (!p(v)) v = f(v);\n return v;\n };\n\n // unwords :: [String] -> String\n const unwords = xs => xs.join(' ');\n\n // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]\n const zipWith = (f, xs, ys) => {\n const ny = ys.length;\n return (xs.length <= ny ? xs : xs.slice(0, ny))\n .map((x, i) => f(x, ys[i]));\n };\n\n\n // CONNECTION PUZZLE ------------------------------------------------------\n\n // universe :: [[Int]]\n const universe = permutations(enumFromTo(1, 8));\n\n // isSolution :: [Int] -> Bool\n const isSolution = ([a, b, c, d, e, f, g, h]) =>\n all(x => abs(x) > 1, [a - d, c - d, g - d, e - d, a - c, c - g, g - e,\n e - a, b - e, d - e, h - e, f - e, b - d, d - h, h - f, f - b\n ]);\n\n // firstSolution :: [Int]\n const firstSolution = universe[until(\n i => isSolution(universe[i]),\n i => i + 1,\n 0\n )];\n\n // TEST -------------------------------------------------------------------\n\n // [Int]\n const [a, b, c, d, e, f, g, h] = firstSolution;\n\n return unlines(\n zipWith(\n (a, n) => a + ' = ' + n.toString(),\n enumFromTo('A', 'H'),\n firstSolution\n )\n .concat(\n [\n [],\n [a, b],\n [c, d, e, f],\n [g, h]\n ].map(xs => justifyRight(5, ' ', unwords(xs.map(show))))\n )\n );\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sort a list of object identifiers", + "type": "Waypoint", + "description": [ + "

Object identifiers (OID) are strings used to identify objects in network data.

", + "Task:", + "

Show how to sort a list of OIDs, in their natural sort order.

", + "An OID consists of one or more non-negative integers in base 10, separated by dots. It starts and ends with a number.", + "Their natural sort order is lexicographical with regard to the dot-separated fields, using numeric comparison between fields.", + "

{|

", + "

|-

", + "

! Input (list of strings)

", + "

! Output (list of strings)

", + "

|-

", + "

|

", + "

1.3.6.1.4.1.11.2.17.19.3.4.0.10

", + "

1.3.6.1.4.1.11.2.17.5.2.0.79

", + "

1.3.6.1.4.1.11.2.17.19.3.4.0.4

", + "

1.3.6.1.4.1.11150.3.4.0.1

", + "

1.3.6.1.4.1.11.2.17.19.3.4.0.1

", + "

1.3.6.1.4.1.11150.3.4.0

", + "

|

", + "

1.3.6.1.4.1.11.2.17.5.2.0.79

", + "

1.3.6.1.4.1.11.2.17.19.3.4.0.1

", + "

1.3.6.1.4.1.11.2.17.19.3.4.0.4

", + "

1.3.6.1.4.1.11.2.17.19.3.4.0.10

", + "

1.3.6.1.4.1.11150.3.4.0

", + "

1.3.6.1.4.1.11150.3.4.0.1

", + "

|}

", + "Natural sorting", + "Sort using a custom comparator", + "


" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ffd", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sort an array of composite structures", + "type": "Waypoint", + "description": [ + "

Sort an array of composite structures by a key.

", + "

For example, if you define a composite structure that presents a name-value pair (in pseudo-code):

Define structure pair such that:

", + "

name as a string

", + "

value as a string

and an array of such pairs:

x: array of pairs

then define a sort routine that sorts the array x by the key name.

This task can always be accomplished with Sorting Using a Custom Comparator. If your language is not listed here, please see the other article.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "var arr = [", + " {id: 3, value: \"foo\"},", + " {id: 2, value: \"bar\"},", + " {id: 4, value: \"baz\"},", + " {id: 1, value: 42},", + " {id: 5, something: \"another string\"} // Works with any object declaring 'id' as a number.", + "];", + "arr = arr.sort(function(a, b) {return a.id - b.id}); // Sort with comparator checking the id.", + "", + "", + "===ES6===", + "", + "(() => {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS FOR COMPARISONS", + "", + " // compare :: a -> a -> Ordering", + " const compare = (a, b) => a < b ? -1 : (a > b ? 1 : 0);", + "", + " // on :: (b -> b -> c) -> (a -> b) -> a -> a -> c", + " const on = (f, g) => (a, b) => f(g(a), g(b));", + "", + " // flip :: (a -> b -> c) -> b -> a -> c", + " const flip = f => (a, b) => f.apply(null, [b, a]);", + "", + " // arrayCopy :: [a] -> [a]", + " const arrayCopy = (xs) => xs.slice(0);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x, null, 2);", + "", + "", + " // TEST", + " const xs = [{", + " name: 'Shanghai',", + " pop: 24.2", + " }, {", + " name: 'Karachi',", + " pop: 23.5", + " }, {", + " name: 'Beijing',", + " pop: 21.5", + " }, {", + " name: 'Sao Paulo',", + " pop: 24.2", + " }, {", + " name: 'Dhaka',", + " pop: 17.0", + " }, {", + " name: 'Delhi',", + " pop: 16.8", + " }, {", + " name: 'Lagos',", + " pop: 16.1", + " }]", + "", + " // population :: Dictionary -> Num", + " const population = x => x.pop;", + "", + " // name :: Dictionary -> String", + " const name = x => x.name;", + "", + " return show({", + " byPopulation: arrayCopy(xs)", + " .sort(on(compare, population)),", + " byDescendingPopulation: arrayCopy(xs)", + " .sort(on(flip(compare), population)),", + " byName: arrayCopy(xs)", + " .sort(on(compare, name)),", + " byDescendingName: arrayCopy(xs)", + " .sort(on(flip(compare), name))", + " });", + "})();", + "", + "{{Out}}", + "
{",
+      "  \"byPopulation\": [",
+      "    {",
+      "      \"name\": \"Lagos\",",
+      "      \"pop\": 16.1",
+      "    },",
+      "    {",
+      "      \"name\": \"Delhi\",",
+      "      \"pop\": 16.8",
+      "    },",
+      "    {",
+      "      \"name\": \"Dhaka\",",
+      "      \"pop\": 17",
+      "    },",
+      "    {",
+      "      \"name\": \"Beijing\",",
+      "      \"pop\": 21.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Karachi\",",
+      "      \"pop\": 23.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Shanghai\",",
+      "      \"pop\": 24.2",
+      "    },",
+      "    {",
+      "      \"name\": \"Sao Paulo\",",
+      "      \"pop\": 24.2",
+      "    }",
+      "  ],",
+      "  \"byDescendingPopulation\": [",
+      "    {",
+      "      \"name\": \"Shanghai\",",
+      "      \"pop\": 24.2",
+      "    },",
+      "    {",
+      "      \"name\": \"Sao Paulo\",",
+      "      \"pop\": 24.2",
+      "    },",
+      "    {",
+      "      \"name\": \"Karachi\",",
+      "      \"pop\": 23.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Beijing\",",
+      "      \"pop\": 21.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Dhaka\",",
+      "      \"pop\": 17",
+      "    },",
+      "    {",
+      "      \"name\": \"Delhi\",",
+      "      \"pop\": 16.8",
+      "    },",
+      "    {",
+      "      \"name\": \"Lagos\",",
+      "      \"pop\": 16.1",
+      "    }",
+      "  ],",
+      "  \"byName\": [",
+      "    {",
+      "      \"name\": \"Beijing\",",
+      "      \"pop\": 21.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Delhi\",",
+      "      \"pop\": 16.8",
+      "    },",
+      "    {",
+      "      \"name\": \"Dhaka\",",
+      "      \"pop\": 17",
+      "    },",
+      "    {",
+      "      \"name\": \"Karachi\",",
+      "      \"pop\": 23.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Lagos\",",
+      "      \"pop\": 16.1",
+      "    },",
+      "    {",
+      "      \"name\": \"Sao Paulo\",",
+      "      \"pop\": 24.2",
+      "    },",
+      "    {",
+      "      \"name\": \"Shanghai\",",
+      "      \"pop\": 24.2",
+      "    }",
+      "  ],",
+      "  \"byDescendingName\": [",
+      "    {",
+      "      \"name\": \"Shanghai\",",
+      "      \"pop\": 24.2",
+      "    },",
+      "    {",
+      "      \"name\": \"Sao Paulo\",",
+      "      \"pop\": 24.2",
+      "    },",
+      "    {",
+      "      \"name\": \"Lagos\",",
+      "      \"pop\": 16.1",
+      "    },",
+      "    {",
+      "      \"name\": \"Karachi\",",
+      "      \"pop\": 23.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Dhaka\",",
+      "      \"pop\": 17",
+      "    },",
+      "    {",
+      "      \"name\": \"Delhi\",",
+      "      \"pop\": 16.8",
+      "    },",
+      "    {",
+      "      \"name\": \"Beijing\",",
+      "      \"pop\": 21.5",
+      "    }",
+      "  ]",
+      "}
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7ffe", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var arr = [\n {id: 3, value: \"foo\"},\n {id: 2, value: \"bar\"},\n {id: 4, value: \"baz\"},\n {id: 1, value: 42},\n {id: 5, something: \"another string\"} // Works with any object declaring 'id' as a number.\n];\narr = arr.sort(function(a, b) {return a.id - b.id}); // Sort with comparator checking the id.\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sort an integer array", + "type": "Waypoint", + "description": [ + "

Sort an array (or list) of integers in ascending numerical order.

Task:", + "

Use a sorting facility provided by the language/library if possible.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|Firefox|2.0}}", + "", + "JavaScript sorts lexically by default, so \"10000\" comes before \"2\". To sort numerically, a custom comparator is used.", + "", + "function int_arr(a, b) {", + " return a - b;", + "}", + "var numbers = [20, 7, 65, 10, 3, 0, 8, -60];", + "numbers.sort(int_arr);", + "document.write(numbers);", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc7fff", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function int_arr(a, b) {\n return a - b;\n}\nvar numbers = [20, 7, 65, 10, 3, 0, 8, -60];\nnumbers.sort(int_arr);\ndocument.write(numbers);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sort disjoint sublist", + "type": "Waypoint", + "description": [ + "

Given a list of values and a set of integer indices into that value list, the task is to sort the values at the given indices, but preserving the values at indices outside the set of those to be sorted.

Make your example work with the following list of values and set of indices:

", + "

", + "

values: [7, 6, 5, 4, 3, 2, 1, 0]

", + "

indices: {6, 1, 7}

", + "

Where the correct result would be:

", + "

[7, 0, 5, 4, 3, 2, 1, 6].

Note that for one based, rather than the zero-based indexing above, use the indices: {7, 2, 8}. The indices are described as a set rather than a list but any collection-type of those indices without duplication may be used as long as the example is insensitive to the order of indices given.

Cf.", + "Order disjoint list items" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Iterative====", + "", + "Does not check for duplicate indices.", + "function sort_disjoint(values, indices) {", + " var sublist = [];", + " indices.sort(function(a, b) { return a > b; });", + "", + " for (var i = 0; i < indices.length; i += 1) {", + " sublist.push(values[indices[i]]);", + " }", + "", + " sublist.sort(function(a, b) { return a < b; });", + "", + " for (var i = 0; i < indices.length; i += 1) {", + " values[indices[i]] = sublist.pop();", + " }", + "", + " return values;", + "}", + "", + "====Functional====", + "", + "(function () {", + " 'use strict';", + "", + " // disjointSort :: [a] -> [Int] -> [a]", + " function disjointSort(xs, indices) {", + "", + " // Sequence of indices discarded", + " var indicesSorted = indices.sort(),", + " subsetSorted = indicesSorted", + " .map(function (i) {", + " return xs[i];", + " })", + " .sort();", + "", + " return xs", + " .map(function (x, i) {", + " var iIndex = indicesSorted.indexOf(i);", + "", + " return iIndex !== -1 ? (", + " subsetSorted[iIndex]", + " ) : x;", + " });", + " }", + "", + " return disjointSort([7, 6, 5, 4, 3, 2, 1, 0], [6, 1, 7])", + "", + "})();", + "", + "{{Out}}", + "
[7, 0, 5, 4, 3, 2, 1, 6]
", + "", + "===ES6===", + "", + "(() => {", + " 'use strict';", + "", + " // disjointSort :: [a] -> [Int] -> [a]", + " const disjointSort = (xs, indices) => {", + "", + " // Sequence of indices discarded", + " const indicesSorted = indices.sort(),", + " subsetSorted = indicesSorted", + " .map(i => xs[i])", + " .sort();", + " ", + " return xs", + " .map((x, i) => {", + " const iIndex = indicesSorted.indexOf(i);", + " return iIndex !== -1 ? (", + " subsetSorted[iIndex]", + " ) : x;", + " });", + " };", + "", + " return disjointSort([7, 6, 5, 4, 3, 2, 1, 0], [6, 1, 7]);", + "})();", + "{{Out}}", + "
[7, 0, 5, 4, 3, 2, 1, 6]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8000", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function sort_disjoint(values, indices) {\n var sublist = [];\n indices.sort(function(a, b) { return a > b; });\n\n for (var i = 0; i < indices.length; i += 1) {\n sublist.push(values[indices[i]]);\n }\n\n sublist.sort(function(a, b) { return a < b; });\n\n for (var i = 0; i < indices.length; i += 1) {\n values[indices[i]] = sublist.pop();\n }\n\n return values;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Bead sort", + "type": "Waypoint", + "description": [ + "Task:", + "

Sort an array of positive integers using the Bead Sort Algorithm.

A bead sort is also known as a gravity sort.

", + "

Algorithm has O(S), where S is the sum of the integers in the input set: Each bead is moved individually.

This is the case when bead sort is implemented without a mechanism to assist in finding empty spaces below the beads, such as in software implementations.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8001", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Bogosort", + "type": "Waypoint", + "description": [ + "Task:", + "

Bogosort a list of numbers.

", + "

Bogosort simply shuffles a collection randomly until it is sorted.

\"Bogosort\" is a perversely inefficient algorithm only used as an in-joke.

Its average run-time is O(n!) because the chance that any given shuffle of a set will end up in sorted order is about one in n factorial, and the worst case is infinite since there's no guarantee that a random shuffling will ever produce a sorted sequence.

Its best case is O(n) since a single pass through the elements may suffice to order them.

", + "

Pseudocode:

", + "

while not InOrder(list) do

", + "

Shuffle(list)

", + "

done

", + "

The Knuth shuffle may be used to implement the shuffle part of this algorithm.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "shuffle = function(v) {", + " for(var j, x, i = v.length; i; j = Math.floor(Math.random() * i), x = v[--i], v[i] = v[j], v[j] = x);", + " return v;", + "};", + "", + "isSorted = function(v){", + " for(var i=1; i v[i]) { return false; }", + " }", + " return true;", + "}", + "\t\t", + "bogosort = function(v){", + " var sorted = false;", + " while(sorted == false){", + " v = shuffle(v);", + " sorted = isSorted(v);", + " }", + " return v;", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8002", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "shuffle = function(v) {\n for(var j, x, i = v.length; i; j = Math.floor(Math.random() * i), x = v[--i], v[i] = v[j], v[j] = x);\n return v;\n};\n\nisSorted = function(v){\n for(var i=1; i v[i]) { return false; }\n }\n return true;\n}\n\t\t\nbogosort = function(v){\n var sorted = false;\n while(sorted == false){\n v = shuffle(v);\n sorted = isSorted(v);\n }\n return v;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Bubble sort", + "type": "Waypoint", + "description": [ + "Task:", + "

Sort an array of elements using the bubble sort algorithm. The elements must have a total order and the index of the array can be of any discrete type. For languages where this is not possible, sort an array of integers.

The bubble sort is generally considered to be the simplest sorting algorithm.

Because of its simplicity and ease of visualization, it is often taught in introductory computer science courses.

Because of its abysmal O(n2) performance, it is not used often for large (or even medium-sized) datasets.

The bubble sort works by passing sequentially over a list, comparing each value to the one immediately after it. If the first value is greater than the second, their positions are switched. Over a number of passes, at most equal to the number of elements in the list, all of the values drift into their correct positions (large values \"bubble\" rapidly toward the end, pushing others down around them).

", + "

Because each pass finds the maximum item and puts it at the end, the portion of the list to be sorted can be reduced at each pass.

", + "

A boolean variable is used to track whether any changes have been made in the current pass; when a pass completes without changing anything, the algorithm exits.

This can be expressed in pseudo-code as follows (assuming 1-based indexing):

", + "

repeat

", + "

hasChanged := false

", + "

decrement itemCount

", + "

repeat with index from 1 to itemCount

", + "

if (item at index) > (item at (index + 1))

", + "

swap (item at index) with (item at (index + 1))

", + "

hasChanged := true

", + "

until hasChanged = false

", + "References:", + "The article on Wikipedia.", + "Dance interpretation." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Array.prototype.bubblesort = function() {", + " var done = false;", + " while (!done) {", + " done = true;", + " for (var i = 1; i this[i]) {", + " done = false;", + " [this[i-1], this[i]] = [this[i], this[i-1]]", + " }", + " }", + " }", + " return this;", + "}", + "", + "{{works with|SEE|3.0}}", + "{{works with|OSSP js|1.6.20070208}}", + "Array.prototype.bubblesort = function() {", + " var done = false;", + " while (! done) {", + " done = true;", + " for (var i = 1; i < this.length; i++) {", + " if (this[i - 1] > this[i]) {", + " done = false;", + " var tmp = this[i - 1];", + " this[i - 1] = this[i];", + " this[i] = tmp;", + " }", + " }", + " }", + " return this;", + "}", + "", + "Example:", + "var my_arr = [\"G\", \"F\", \"C\", \"A\", \"B\", \"E\", \"D\"];", + "my_arr.bubblesort();", + "print(my_arr);", + "", + "{{out}}", + "
",
+      " A,B,C,D,E,F,G",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8003", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "Array.prototype.bubblesort = function() {\n var done = false;\n while (!done) {\n done = true;\n for (var i = 1; i this[i]) {\n done = false;\n [this[i-1], this[i]] = [this[i], this[i-1]]\n }\n }\n }\n return this;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Cocktail sort", + "type": "Waypoint", + "description": [ + "

The cocktail shaker sort is an improvement on the Bubble Sort.

", + "

The improvement is basically that values \"bubble\" both directions through the array, because on each iteration the cocktail shaker sort bubble sorts once forwards and once backwards. Pseudocode for the algorithm (from wikipedia):

", + "

function cocktailSort( A : list of sortable items )

", + "

do

", + "

swapped := false

", + "

for each i in 0 to length( A ) - 2 do

", + "

if A[ i ] > A[ i+1 ] then // test whether the two

", + "

// elements are in the wrong

", + "

// order

", + "

swap( A[ i ], A[ i+1 ] ) // let the two elements

", + "

// change places

", + "

swapped := true;

", + "

if swapped = false then

", + "

// we can exit the outer loop here if no swaps occurred.

", + "

break do-while loop;

", + "

swapped := false

", + "

for each i in length( A ) - 2 down to 0 do

", + "

if A[ i ] > A[ i+1 ] then

", + "

swap( A[ i ], A[ i+1 ] )

", + "

swapped := true;

", + "

while swapped; // if no elements have been swapped,

", + "

// then the list is sorted

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + " // Node 5.4.1 tested implementation (ES6)", + "\"use strict\";", + "", + "let arr = [4, 9, 0, 3, 1, 5];", + "let isSorted = true;", + "while (isSorted){", + " for (let i = 0; i< arr.length - 1;i++){", + " if (arr[i] > arr[i + 1])", + " {", + " let temp = arr[i];", + " arr[i] = arr[i + 1];", + " arr[i+1] = temp;", + " isSorted = true;", + " }", + " }", + "", + " if (!isSorted)", + " break;", + " ", + " isSorted = false;", + "", + " for (let j = arr.length - 1; j > 0; j--){", + " if (arr[j-1] > arr[j])", + " {", + " let temp = arr[j];", + " arr[j] = arr[j - 1];", + " arr[j - 1] = temp;", + " isSorted = true;", + " }", + " }", + "}", + "console.log(arr);", + "", + "}", + "", + "", + "{{out}}", + "
",
+      " [0, 1, 3, 4, 5, 9]",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8004", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n // Node 5.4.1 tested implementation (ES6)\n\"use strict\";\n\nlet arr = [4, 9, 0, 3, 1, 5];\nlet isSorted = true;\nwhile (isSorted){\n for (let i = 0; i< arr.length - 1;i++){\n if (arr[i] > arr[i + 1])\n {\n let temp = arr[i];\n arr[i] = arr[i + 1];\n arr[i+1] = temp;\n isSorted = true;\n }\n }\n\n if (!isSorted)\n break;\n \n isSorted = false;\n\n for (let j = arr.length - 1; j > 0; j--){\n if (arr[j-1] > arr[j])\n {\n let temp = arr[j];\n arr[j] = arr[j - 1];\n arr[j - 1] = temp;\n isSorted = true;\n }\n }\n}\nconsole.log(arr);\n\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Comb sort", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement a comb sort.

", + "

The Comb Sort is a variant of the Bubble Sort.

Like the Shell sort, the Comb Sort increases the gap used in comparisons and exchanges.

Dividing the gap by $(1-e^{-\\varphi})^{-1} \\approx 1.247330950103979$ works best, but 1.3 may be more practical.

", + "

Some implementations use the insertion sort once the gap is less than a certain amount.

", + "Also see:", + " the Wikipedia article: Comb sort.

Variants:

", + "Combsort11 makes sure the gap ends in (11, 8, 6, 4, 3, 2, 1), which is significantly faster than the other two possible endings.", + "Combsort with different endings changes to a more efficient sort when the data is almost sorted (when the gap is small). Comb sort with a low gap isn't much better than the Bubble Sort.", + "

Pseudocode:

", + "

function combsort(array input)

", + "

gap := input.size //initialize gap size

", + "

loop until gap = 1 and swaps = 0

", + "

//update the gap value for a next comb. Below is an example

", + "

gap := int(gap / 1.25)

", + "

if gap < 1

", + "

//minimum gap is 1

", + "

gap := 1

", + "

end if

", + "

i := 0

", + "

swaps := 0 //see Bubble Sort for an explanation

", + "

//a single \"comb\" over the input list

", + "

loop until i + gap >= input.size //see Shell sort for similar idea

", + "

if input[i] > input[i+gap]

", + "

swap(input[i], input[i+gap])

", + "

swaps := 1 // Flag a swap has occurred, so the

", + "

// list is not guaranteed sorted

", + "

end if

", + "

i := i + 1

", + "

end loop

", + "

end loop

", + "

end function

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + " // Node 5.4.1 tested implementation (ES6)", + " function is_array_sorted(arr) {", + " var sorted = true;", + " for (var i = 0; i < arr.length - 1; i++) {", + " if (arr[i] > arr[i + 1]) {", + " sorted = false;", + " break;", + " }", + " }", + " return sorted;", + " }", + "", + " // Array to sort", + " var arr = [4, 9, 0, 3, 1, 5];", + "", + " var iteration_count = 0;", + " var gap = arr.length - 2;", + " var decrease_factor = 1.25;", + "", + " // Until array is not sorted, repeat iterations", + " while (!is_array_sorted(arr)) {", + " // If not first gap", + " if (iteration_count > 0)", + " // Calculate gap", + " gap = (gap == 1) ? gap : Math.floor(gap / decrease_factor);", + "", + " // Set front and back elements and increment to a gap", + " var front = 0;", + " var back = gap;", + " while (back <= arr.length - 1) {", + " // If elements are not ordered swap them", + " if (arr[front] > arr[back]) {", + " var temp = arr[front];", + " arr[front] = arr[back];", + " arr[back] = temp;", + " }", + "", + " // Increment and re-run swapping", + " front += 1;", + " back += 1;", + " }", + " iteration_count += 1;", + " }", + "", + " // Print the sorted array", + " console.log(arr);", + "}", + "", + "", + "{{out}}", + "
",
+      " [0, 1, 3, 4, 5, 9]",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8005", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n // Node 5.4.1 tested implementation (ES6)\n function is_array_sorted(arr) {\n var sorted = true;\n for (var i = 0; i < arr.length - 1; i++) {\n if (arr[i] > arr[i + 1]) {\n sorted = false;\n break;\n }\n }\n return sorted;\n }\n\n // Array to sort\n var arr = [4, 9, 0, 3, 1, 5];\n\n var iteration_count = 0;\n var gap = arr.length - 2;\n var decrease_factor = 1.25;\n\n // Until array is not sorted, repeat iterations\n while (!is_array_sorted(arr)) {\n // If not first gap\n if (iteration_count > 0)\n // Calculate gap\n gap = (gap == 1) ? gap : Math.floor(gap / decrease_factor);\n\n // Set front and back elements and increment to a gap\n var front = 0;\n var back = gap;\n while (back <= arr.length - 1) {\n // If elements are not ordered swap them\n if (arr[front] > arr[back]) {\n var temp = arr[front];\n arr[front] = arr[back];\n arr[back] = temp;\n }\n\n // Increment and re-run swapping\n front += 1;\n back += 1;\n }\n iteration_count += 1;\n }\n\n // Print the sorted array\n console.log(arr);\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Counting sort", + "type": "Waypoint", + "description": [ + "

Implement the Counting sort. This is a way of sorting integers when the minimum and maximum value are known.

Pseudocode:

", + "

function countingSort(array, min, max):

", + "

count: array of (max - min + 1) elements

", + "

initialize count with 0

", + "

for each number in array do

", + "

count[number - min] := count[number - min] + 1

", + "

done

", + "

z := 0

", + "

for i from min to max do

", + "

while ( count[i - min] > 0 ) do

", + "

array[z] := i

", + "

z := z+1

", + "

count[i - min] := count[i - min] - 1

", + "

done

", + "

done

The min and max can be computed apart, or be known a priori.

Note: we know that, given an array of integers, its maximum and minimum values can be always found; but if we imagine the worst case for an array of 32 bit integers, we see that in order to hold the counts, we need an array of 232 elements, i.e., we need, to hold a count value up to 232-1, more or less 4 Gbytes. So the counting sort is more practical when the range is (very) limited and minimum and maximum values are known a priori. (Anyway sparse arrays may limit the impact of the memory usage)

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "var countSort = function(arr, min, max) {", + " var i, z = 0, count = [];", + " ", + " for (i = min; i <= max; i++) {", + " count[i] = 0;", + " }", + " ", + " for (i=0; i < arr.length; i++) {", + " count[arr[i]]++;", + " }", + " ", + " for (i = min; i <= max; i++) {", + " while (count[i]-- > 0) {", + " arr[z++] = i;", + " }", + " }", + " ", + "}", + "", + "Testing:", + "", + "// Line breaks are in HTML", + "", + "var i, ages = [];", + "", + "for (i = 0; i < 100; i++) {", + " ages.push(Math.floor(Math.random() * (141)));", + "}", + "", + "countSort(ages, 0, 140);", + "", + "for (i = 0; i < 100; i++) {", + " document.write(ages[i] + \"
\");", + "}
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8006", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var countSort = function(arr, min, max) {\n var i, z = 0, count = [];\n \n for (i = min; i <= max; i++) {\n count[i] = 0;\n }\n \n for (i=0; i < arr.length; i++) {\n count[arr[i]]++;\n }\n \n for (i = min; i <= max; i++) {\n while (count[i]-- > 0) {\n arr[z++] = i;\n }\n }\n \n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Gnome sort", + "type": "Waypoint", + "description": [ + "

Gnome sort is a sorting algorithm which is similar to Insertion sort, except that moving an element to its proper place is accomplished by a series of swaps, as in Bubble Sort.

The pseudocode for the algorithm is:

", + "

function gnomeSort(a[0..size-1])

", + "

i := 1

", + "

j := 2

", + "

while i < size do

", + "

if a[i-1] <= a[i] then

", + "

// for descending sort, use >= for comparison

", + "

i := j

", + "

j := j + 1

", + "

else

", + "

swap a[i-1] and a[i]

", + "

i := i - 1

", + "

if i = 0 then

", + "

i := j

", + "

j := j + 1

", + "

endif

", + "

endif

", + "

done

Task: implement the Gnome sort in your language to sort an array (or list) of numbers.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function gnomeSort(a) {", + " function moveBack(i) {", + " for( ; i > 0 && a[i-1] > a[i]; i--) {", + " var t = a[i];", + " a[i] = a[i-1];", + " a[i-1] = t;", + " }", + " }", + " for (var i = 1; i < a.length; i++) {", + " if (a[i-1] > a[i]) moveBack(i);", + " }", + " return a;", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8007", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function gnomeSort(a) {\n function moveBack(i) {\n for( ; i > 0 && a[i-1] > a[i]; i--) {\n var t = a[i];\n a[i] = a[i-1];\n a[i-1] = t;\n }\n }\n for (var i = 1; i < a.length; i++) {\n if (a[i-1] > a[i]) moveBack(i);\n }\n return a;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Heapsort", + "type": "Waypoint", + "description": [ + "

Heapsort is an in-place sorting algorithm with worst case and average complexity of O(n logn).

The basic idea is to turn the array into a binary heap structure, which has the property that it allows efficient retrieval and removal of the maximal element.

We repeatedly \"remove\" the maximal element from the heap, thus building the sorted list from back to front.

Heapsort requires random access, so can only be used on an array-like data structure.

Pseudocode:

", + "

function heapSort(a, count) is

", + "

input: an unordered array a of length count

(first place a in max-heap order)

", + "

heapify(a, count)

end := count - 1

", + "

while end > 0 do

", + "

(swap the root(maximum value) of the heap with the

", + "

last element of the heap)

", + "

swap(a[end], a[0])

", + "

(decrement the size of the heap so that the previous

", + "

max value will stay in its proper place)

", + "

end := end - 1

", + "

(put the heap back in max-heap order)

", + "

siftDown(a, 0, end)

", + "

function heapify(a,count) is

", + "

(start is assigned the index in a of the last parent node)

", + "

start := (count - 2) / 2

while start ≥ 0 do

", + "

(sift down the node at index start to the proper place

", + "

such that all nodes below the start index are in heap

", + "

order)

", + "

siftDown(a, start, count-1)

", + "

start := start - 1

", + "

(after sifting down the root all nodes/elements are in heap order)

function siftDown(a, start, end) is

", + "

(end represents the limit of how far down the heap to sift)

", + "

root := start

while root * 2 + 1 ≤ end do (While the root has at least one child)

", + "

child := root * 2 + 1 (root*2+1 points to the left child)

", + "

(If the child has a sibling and the child's value is less than its sibling's...)

", + "

if child + 1 ≤ end and a[child] < a[child + 1] then

", + "

child := child + 1 (... then point to the right child instead)

", + "

if a[root] < a[child] then (out of max-heap order)

", + "

swap(a[root], a[child])

", + "

root := child (repeat to continue sifting down the child now)

", + "

else

", + "

return

", + "

Write a function to sort a collection of integers using heapsort.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8008", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Insertion sort", + "type": "Waypoint", + "description": [ + "

An O(n2) sorting algorithm which moves elements one at a time into the correct position.

", + "

The algorithm consists of inserting one element at a time into the previously sorted part of the array, moving higher ranked elements up as necessary.

", + "

To start off, the first (or smallest, or any arbitrary) element of the unsorted array is considered to be the sorted part.

Although insertion sort is an O(n2) algorithm, its simplicity, low overhead, good locality of reference and efficiency make it a good choice in two cases:

", + "

(i) small n,

", + "

(ii) as the final finishing-off algorithm for O(n logn) algorithms such as mergesort and quicksort.

The algorithm is as follows (from wikipedia):

", + "

function insertionSort(array A)

", + "

for i from 1 to length[A]-1 do

", + "

value := A[i]

", + "

j := i-1

", + "

while j >= 0 and A[j] > value do

", + "

A[j+1] := A[j]

", + "

j := j-1

", + "

done

", + "

A[j+1] = value

", + "

done

Writing the algorithm for integers will suffice.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "function insertionSort (a) {", + " for (var i = 0; i < a.length; i++) {", + " var k = a[i];", + " for (var j = i; j > 0 && k < a[j - 1]; j--)", + " a[j] = a[j - 1];", + " a[j] = k;", + " }", + " return a;", + "}", + "", + "var a = [4, 65, 2, -31, 0, 99, 83, 782, 1];", + "insertionSort(a);", + "document.write(a.join(\" \"));", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8009", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nfunction insertionSort (a) {\n for (var i = 0; i < a.length; i++) {\n var k = a[i];\n for (var j = i; j > 0 && k < a[j - 1]; j--)\n a[j] = a[j - 1];\n a[j] = k;\n }\n return a;\n}\n\nvar a = [4, 65, 2, -31, 0, 99, 83, 782, 1];\ninsertionSort(a);\ndocument.write(a.join(\" \"));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Merge sort", + "type": "Waypoint", + "description": [ + "

The merge sort is a recursive sort of order n*log(n).

It is notable for having a worst case and average complexity of O(n*log(n)), and a best case complexity of O(n) (for pre-sorted input).

The basic idea is to split the collection into smaller groups by halving it until the groups only have one element or no elements (which are both entirely sorted groups).

Then merge the groups back together so that their elements are in order.

This is how the algorithm gets its divide and conquer description.

", + "Task:", + "

Write a function to sort a collection of integers using the merge sort.

", + "

The merge sort algorithm comes in two parts:

", + "

a sort function and

", + "

a merge function

The functions in pseudocode look like this:

", + "

function mergesort(m)

", + "

var list left, right, result

", + "

if length(m) ≤ 1

", + "

return m

", + "

else

", + "

var middle = length(m) / 2

", + "

for each x in m up to middle - 1

", + "

add x to left

", + "

for each x in m at and after middle

", + "

add x to right

", + "

left = mergesort(left)

", + "

right = mergesort(right)

", + "

if last(left) ≤ first(right)

", + "

append right to left

", + "

return left

", + "

result = merge(left, right)

", + "

return result

function merge(left,right)

", + "

var list result

", + "

while length(left) > 0 and length(right) > 0

", + "

if first(left) ≤ first(right)

", + "

append first(left) to result

", + "

left = rest(left)

", + "

else

", + "

append first(right) to result

", + "

right = rest(right)

", + "

if length(left) > 0

", + "

append rest(left) to result

", + "

if length(right) > 0

", + "

append rest(right) to result

", + "

return result

", + "See also:", + " the Wikipedia entry: merge sort

Note: better performance can be expected if, rather than recursing until length(m) ≤ 1, an insertion sort is used for length(m) smaller than some threshold larger than 1. However, this complicates the example code, so it is not shown here.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function merge(left, right, arr) {", + " var a = 0;", + "", + " while (left.length && right.length) {", + " arr[a++] = (right[0] < left[0]) ? right.shift() : left.shift();", + " }", + " while (left.length) {", + " arr[a++] = left.shift();", + " }", + " while (right.length) {", + " arr[a++] = right.shift();", + " }", + "}", + "", + "function mergeSort(arr) {", + " var len = arr.length;", + "", + " if (len === 1) { return; }", + "", + " var mid = Math.floor(len / 2),", + " left = arr.slice(0, mid),", + " right = arr.slice(mid);", + "", + " mergeSort(left);", + " mergeSort(right);", + " merge(left, right, arr);", + "}", + "", + "var arr = [1, 5, 2, 7, 3, 9, 4, 6, 8];", + "mergeSort(arr); // arr will now: 1, 2, 3, 4, 5, 6, 7, 8, 9", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc800a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function merge(left, right, arr) {\n var a = 0;\n\n while (left.length && right.length) {\n arr[a++] = (right[0] < left[0]) ? right.shift() : left.shift();\n }\n while (left.length) {\n arr[a++] = left.shift();\n }\n while (right.length) {\n arr[a++] = right.shift();\n }\n}\n\nfunction mergeSort(arr) {\n var len = arr.length;\n\n if (len === 1) { return; }\n\n var mid = Math.floor(len / 2),\n left = arr.slice(0, mid),\n right = arr.slice(mid);\n\n mergeSort(left);\n mergeSort(right);\n merge(left, right, arr);\n}\n\nvar arr = [1, 5, 2, 7, 3, 9, 4, 6, 8];\nmergeSort(arr); // arr will now: 1, 2, 3, 4, 5, 6, 7, 8, 9\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Pancake sort", + "type": "Waypoint", + "description": [ + "Task:", + "

Sort an array of integers (of any convenient size) into ascending order using Pancake sorting.

In short, instead of individual elements being sorted, the only operation allowed is to \"flip\" one end of the list, like so:

", + "

Before:

", + "

6 7 8 9 2 5 3 4 1

", + "

After:

", + "

9 8 7 6 2 5 3 4 1

Only one end of the list can be flipped; this should be the low end, but the high end is okay if it's easier to code or works better, but it must be the same end for the entire solution. (The end flipped can't be arbitrarily changed.)

Show both the initial, unsorted list and the final sorted list. (Intermediate steps during sorting are optional.) Optimizations are optional (but recommended).

For more information on pancake sorting, see the Wikipedia entry.

See also:

", + "Number reversal game", + "Topswops" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Array.prototype.pancake_sort = function () {", + " for (var i = this.length - 1; i >= 1; i--) {", + " // find the index of the largest element not yet sorted", + " var max_idx = 0;", + " var max = this[0];", + " for (var j = 1; j <= i; j++) {", + " if (this[j] > max) {", + " max = this[j];", + " max_idx = j;", + " }", + " }", + "", + " if (max_idx == i) ", + " continue; // element already in place", + "", + " var new_slice;", + "", + " // flip this max element to index 0", + " if (max_idx > 0) {", + " new_slice = this.slice(0, max_idx+1).reverse();", + " for (var j = 0; j <= max_idx; j++) ", + " this[j] = new_slice[j];", + " }", + "", + " // then flip the max element to its place", + " new_slice = this.slice(0, i+1).reverse();", + " for (var j = 0; j <= i; j++) ", + " this[j] = new_slice[j];", + " }", + " return this;", + "}", + "ary = [7,6,5,9,8,4,3,1,2,0]", + "sorted = ary.concat().pancake_sort();", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc800b", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "Array.prototype.pancake_sort = function () {\n for (var i = this.length - 1; i >= 1; i--) {\n // find the index of the largest element not yet sorted\n var max_idx = 0;\n var max = this[0];\n for (var j = 1; j <= i; j++) {\n if (this[j] > max) {\n max = this[j];\n max_idx = j;\n }\n }\n\n if (max_idx == i) \n continue; // element already in place\n\n var new_slice;\n\n // flip this max element to index 0\n if (max_idx > 0) {\n new_slice = this.slice(0, max_idx+1).reverse();\n for (var j = 0; j <= max_idx; j++) \n this[j] = new_slice[j];\n }\n\n // then flip the max element to its place\n new_slice = this.slice(0, i+1).reverse();\n for (var j = 0; j <= i; j++) \n this[j] = new_slice[j];\n }\n return this;\n}\nary = [7,6,5,9,8,4,3,1,2,0]\nsorted = ary.concat().pancake_sort();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Permutation sort", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement a permutation sort, which proceeds by generating the possible permutations

", + "

of the input array/list until discovering the sorted one.

Pseudocode:

", + "

while not InOrder(list) do

", + "

nextPermutation(list)

", + "

done

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc800c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Quicksort", + "type": "Waypoint", + "description": [ + "Task:", + "

Sort an array (or list) elements using the quicksort algorithm.

The elements must have a strict weak order and the index of the array can be of any discrete type.

For languages where this is not possible, sort an array of integers.

", + "

Quicksort, also known as partition-exchange sort, uses these steps.

:# Choose any element of the array to be the pivot.

", + "

:# Divide all other elements (except the pivot) into two partitions.

", + "

:#* All elements less than the pivot must be in the first partition.

", + "

:#* All elements greater than the pivot must be in the second partition.

", + "

:# Use recursion to sort both partitions.

", + "

:# Join the first sorted partition, the pivot, and the second sorted partition.

", + "

The best pivot creates partitions of equal length (or lengths differing by 1).

The worst pivot creates an empty partition (for example, if the pivot is the first or last element of a sorted array).

The run-time of Quicksort ranges from O(n log n) with the best pivots, to O(n2) with the worst pivots, where n is the number of elements in the array.

", + "

This is a simple quicksort algorithm, adapted from Wikipedia.

function quicksort(array)

", + "

less, equal, greater := three empty arrays

", + "

if length(array) > 1

", + "

pivot := select any element of array

", + "

for each x in array

", + "

if x < pivot then add x to less

", + "

if x = pivot then add x to equal

", + "

if x > pivot then add x to greater

", + "

quicksort(less)

", + "

quicksort(greater)

", + "

array := concatenate(less, equal, greater)

A better quicksort algorithm works in place, by swapping elements within the array, to avoid the memory allocation of more arrays.

function quicksort(array)

", + "

if length(array) > 1

", + "

pivot := select any element of array

", + "

left := first index of array

", + "

right := last index of array

", + "

while left ≤ right

", + "

while array[left] < pivot

", + "

left := left + 1

", + "

while array[right] > pivot

", + "

right := right - 1

", + "

if left ≤ right

", + "

swap array[left] with array[right]

", + "

left := left + 1

", + "

right := right - 1

", + "

quicksort(array from first index to right)

", + "

quicksort(array from left to last index)

Quicksort has a reputation as the fastest sort. Optimized variants of quicksort are common features of many languages and libraries. One often contrasts quicksort with merge sort, because both sorts have an average time of O(n log n).

\"On average, mergesort does fewer comparisons than quicksort, so it may be better when complicated comparison routines are used. Mergesort also takes advantage of pre-existing order, so it would be favored for using sort() to merge several sorted arrays. On the other hand, quicksort is often faster for small arrays, and on arrays of a few distinct values, repeated many times.\" — http://perldoc.perl.org/sort.html

Quicksort is at one end of the spectrum of divide-and-conquer algorithms, with merge sort at the opposite end.

Quicksort is a conquer-then-divide algorithm, which does most of the work during the partitioning and the recursive calls. The subsequent reassembly of the sorted partitions involves trivial effort.", + "Merge sort is a divide-then-conquer algorithm. The partioning happens in a trivial way, by splitting the input array in half. Most of the work happens during the recursive calls and the merge phase.", + "

With quicksort, every element in the first partition is less than or equal to every element in the second partition. Therefore, the merge phase of quicksort is so trivial that it needs no mention!

This task has not specified whether to allocate new arrays, or sort in place. This task also has not specified how to choose the pivot element. (Common ways to are to choose the first element, the middle element, or the median of three elements.) Thus there is a variety among the following implementations.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Imperative===", + "", + "function sort(array, less) {", + "", + " function swap(i, j) {", + " var t = array[i];", + " array[i] = array[j];", + " array[j] = t;", + " }", + "", + " function quicksort(left, right) {", + "", + " if (left < right) {", + " var pivot = array[left + Math.floor((right - right) / 2)],", + " left_new = left,", + " right_new = right;", + "", + " do {", + " while (less(array[left_new], pivot)) {", + " left_new += 1;", + " }", + " while (less(pivot, array[right_new])) {", + " right_new -= 1;", + " }", + " if (left_new <= right_new) {", + " swap(left_new, right_new);", + " left_new += 1;", + " right_new -= 1;", + " }", + " } while (left_new <= right_new);", + "", + " quicksort(left, right_new);", + " quicksort(left_new, right);", + "", + " }", + " }", + "", + " quicksort(0, array.length - 1);", + "", + " return array;", + "}", + "", + "Example:var test_array = [10, 3, 11, 15, 19, 1];", + "var sorted_array = sort(test_array, function(a,b) { return a", + "", + "{{Out}}[ 1, 3, 10, 11, 15, 19 ]", + "", + "===Functional===", + "", + "", + "====ES5====", + "", + "Emphasising clarity more than run-time optimisation (for which Array.sort() would be a better option)", + "", + "(function () {", + " 'use strict';", + "", + " // quickSort :: (Ord a) => [a] -> [a] ", + " function quickSort(xs) {", + "", + " if (xs.length) {", + " var h = xs[0],", + " t = xs.slice(1),", + "", + " lessMore = partition(function (x) {", + " return x <= h;", + " }, t),", + " less = lessMore[0],", + " more = lessMore[1];", + "", + " return [].concat.apply(", + " [], [quickSort(less), h, quickSort(more)]", + " );", + "", + " } else return [];", + " }", + "", + "", + " // partition :: Predicate -> List -> (Matches, nonMatches)", + " // partition :: (a -> Bool) -> [a] -> ([a], [a])", + " function partition(p, xs) {", + " return xs.reduce(function (a, x) {", + " return (", + " a[p(x) ? 0 : 1].push(x),", + " a", + " );", + " }, [[], []]);", + " }", + "", + " return quickSort([11.8, 14.1, 21.3, 8.5, 16.7, 5.7])", + "", + "})();", + "", + "{{Out}}", + "", + "
[5.7, 8.5, 11.8, 14.1, 16.7, 21.3]
", + "", + "====ES6====", + "", + "Array.prototype.quick_sort = function () {", + " if (this.length < 2) { return this; }", + "", + " var pivot = this[Math.round(this.length / 2)];", + "", + " return this.filter(x => x < pivot)", + " .quick_sort()", + " .concat(this.filter(x => x == pivot))", + " .concat(this.filter(x => x > pivot).quick_sort());", + "};", + "", + "", + "Or, expressed in terms of a single partition, rather than two consecutive filters:", + "", + "(() => {", + " 'use strict';", + "", + " // QUICKSORT --------------------------------------------------------------", + "", + " // quickSort :: (Ord a) => [a] -> [a]", + " const quickSort = xs =>", + " xs.length > 1 ? (() => {", + " const", + " h = xs[0],", + " [less, more] = partition(x => x <= h, xs.slice(1));", + " return [].concat.apply(", + " [], [quickSort(less), h, quickSort(more)]", + " );", + " })() : xs;", + "", + "", + " // GENERIC ----------------------------------------------------------------", + "", + " // partition :: Predicate -> List -> (Matches, nonMatches)", + " // partition :: (a -> Bool) -> [a] -> ([a], [a])", + " const partition = (p, xs) =>", + " xs.reduce((a, x) =>", + " p(x) ? [a[0].concat(x), a[1]] : [a[0], a[1].concat(x)], [", + " [],", + " []", + " ]);", + "", + " // TEST -------------------------------------------------------------------", + " return quickSort([11.8, 14.1, 21.3, 8.5, 16.7, 5.7]);", + "})();", + "{{Out}}", + "
[5.7, 8.5, 11.8, 14.1, 16.7, 21.3]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc800d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function sort(array, less) {\n\n function swap(i, j) {\n var t = array[i];\n array[i] = array[j];\n array[j] = t;\n }\n\n function quicksort(left, right) {\n\n if (left < right) {\n var pivot = array[left + Math.floor((right - right) / 2)],\n left_new = left,\n right_new = right;\n\n do {\n while (less(array[left_new], pivot)) {\n left_new += 1;\n }\n while (less(pivot, array[right_new])) {\n right_new -= 1;\n }\n if (left_new <= right_new) {\n swap(left_new, right_new);\n left_new += 1;\n right_new -= 1;\n }\n } while (left_new <= right_new);\n\n quicksort(left, right_new);\n quicksort(left_new, right);\n\n }\n }\n\n quicksort(0, array.length - 1);\n\n return array;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Radix sort", + "type": "Waypoint", + "description": [ + "Task:", + "

Sort an integer array with the radix sort algorithm.

The primary purpose is to complete the characterization of sort algorithms task.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc800e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Selection sort", + "type": "Waypoint", + "description": [ + "Task:", + "

Sort an array (or list) of elements using the Selection sort algorithm.

", + "

It works as follows:

First find the smallest element in the array and exchange it with the element in the first position, then find the second smallest element and exchange it with the element in the second position, and continue in this way until the entire array is sorted.

", + "

Its asymptotic complexity is O(n2) making it inefficient on large arrays.

Its primary purpose is for when writing data is very expensive (slow) when compared to reading, eg. writing to flash memory or EEPROM.

No other sorting algorithm has less data movement.

", + "Reference:", + "Wikipedia: Selection sort" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "This algorithm sorts array of numbers.", + "function selectionSort(nums) {", + " var len = nums.length;", + " for(var i = 0; i < len; i++) {", + " var minAt = i;", + " for(var j = i + 1; j < len; j++) {", + " if(nums[j] < nums[minAt])", + " minAt = j;", + " }", + "", + " if(minAt != i) {", + " var temp = nums[i];", + " nums[i] = nums[minAt];", + " nums[minAt] = temp;", + " }", + " }", + " return nums;", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc800f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function selectionSort(nums) {\n var len = nums.length;\n for(var i = 0; i < len; i++) {\n var minAt = i;\n for(var j = i + 1; j < len; j++) {\n if(nums[j] < nums[minAt])\n minAt = j;\n }\n\n if(minAt != i) {\n var temp = nums[i];\n nums[i] = nums[minAt];\n nums[minAt] = temp;\n }\n }\n return nums;\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Shell sort", + "type": "Waypoint", + "description": [ + "Task:", + "

Sort an array of elements using the Shell sort algorithm, a diminishing increment sort.

The Shell sort (also known as Shellsort or Shell's method) is named after its inventor, Donald Shell, who published the algorithm in 1959.

Shell sort is a sequence of interleaved insertion sorts based on an increment sequence.

", + "

The increment size is reduced after each pass until the increment size is 1.

With an increment size of 1, the sort is a basic insertion sort, but by this time the data is guaranteed to be almost sorted, which is insertion sort's \"best case\".

Any sequence will sort the data as long as it ends in 1, but some work better than others.

Empirical studies have shown a geometric increment sequence with a ratio of about 2.2 work well in practice.

", + "

[http://www.cs.princeton.edu/~rs/shell/]

Other good sequences are found at the On-Line Encyclopedia of Integer Sequences.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function shellSort (a) {", + " for (var h = a.length; h > 0; h = parseInt(h / 2)) {", + " for (var i = h; i < a.length; i++) {", + " var k = a[i];", + " for (var j = i; j >= h && k < a[j - h]; j -= h)", + " a[j] = a[j - h];", + " a[j] = k;", + " }", + " }", + " return a;", + "}", + "", + "var a = [];", + "var n = location.href.match(/\\?(\\d+)|$/)[1] || 10;", + "for (var i = 0; i < n; i++)", + " a.push(parseInt(Math.random() * 100));", + "shellSort(a);", + "document.write(a.join(\" \"));", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8010", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function shellSort (a) {\n for (var h = a.length; h > 0; h = parseInt(h / 2)) {\n for (var i = h; i < a.length; i++) {\n var k = a[i];\n for (var j = i; j >= h && k < a[j - h]; j -= h)\n a[j] = a[j - h];\n a[j] = k;\n }\n }\n return a;\n}\n\nvar a = [];\nvar n = location.href.match(/\\?(\\d+)|$/)[1] || 10;\nfor (var i = 0; i < n; i++)\n a.push(parseInt(Math.random() * 100));\nshellSort(a);\ndocument.write(a.join(\" \"));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Sleep sort", + "type": "Waypoint", + "description": [ + "

In general, sleep sort works by starting a separate task for each item to be sorted, where each task sleeps for an interval corresponding to the item's sort key, then emits the item. Items are then collected sequentially in time.

Task: Write a program that implements sleep sort. Have it accept non-negative integers on the command line and print the integers in sorted order. If this is not idomatic in your language or environment, input and output may be done differently. Enhancements for optimization, generalization, practicality, robustness, and so on are not required.

Sleep sort was presented anonymously on 4chan and has been discussed on Hacker News.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Array.prototype.timeoutSort = function (f) {", + "\tthis.forEach(function (n) {", + "\t\tsetTimeout(function () { f(n) }, 5 * n)", + "\t});", + "}", + "", + "Usage and output:", + "[1, 9, 8, 7, 6, 5, 3, 4, 5, 2, 0].timeoutSort(function(n) { document.write(n + 'br'); })", + "
",
+      "0",
+      "1",
+      "2",
+      "3",
+      "4",
+      "5",
+      "6",
+      "7",
+      "8",
+      "9",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8011", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "Array.prototype.timeoutSort = function (f) {\n\tthis.forEach(function (n) {\n\t\tsetTimeout(function () { f(n) }, 5 * n)\n\t});\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Stooge sort", + "type": "Waypoint", + "description": [ + "Task:", + "

Show the Stooge Sort for an array of integers.

", + "

The Stooge Sort algorithm is as follows:

", + "

algorithm stoogesort(array L, i = 0, j = length(L)-1)

", + "

if L[j] < L[i] then

", + "

L[i] L[j]

", + "

if j - i > 1 then

", + "

t := (j - i + 1)/3

", + "

stoogesort(L, i , j-t)

", + "

stoogesort(L, i+t, j )

", + "

stoogesort(L, i , j-t)

", + "

return L

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function stoogeSort (array, i, j) {", + " if (j === undefined) {", + " j = array.length - 1;", + " }", + "", + " if (i === undefined) {", + " i = 0;", + " }", + "", + " if (array[j] < array[i]) {", + " var aux = array[i];", + " array[i] = array[j];", + " array[j] = aux;", + " }", + "", + " if (j - i > 1) {", + " var t = Math.floor((j - i + 1) / 3);", + " stoogeSort(array, i, j-t);", + " stoogeSort(array, i+t, j);", + " stoogeSort(array, i, j-t);", + " }", + "};", + "Example:", + "arr = [9,1,3,10,13,4,2];", + "stoogeSort(arr);", + "console.log(arr);", + "{{out}}", + "
[1, 2, 3, 4, 9, 10, 13]
", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8012", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function stoogeSort (array, i, j) {\n if (j === undefined) {\n j = array.length - 1;\n }\n\n if (i === undefined) {\n i = 0;\n }\n\n if (array[j] < array[i]) {\n var aux = array[i];\n array[i] = array[j];\n array[j] = aux;\n }\n\n if (j - i > 1) {\n var t = Math.floor((j - i + 1) / 3);\n stoogeSort(array, i, j-t);\n stoogeSort(array, i+t, j);\n stoogeSort(array, i, j-t);\n }\n};\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sorting algorithms/Strand sort", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement the Strand sort.

This is a way of sorting numbers by extracting shorter sequences of already sorted numbers from an unsorted list.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8013", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sort stability", + "type": "Waypoint", + "description": [ + "

When sorting records in a table by a particular column or field, a stable sort will always retain the relative order of records that have the same key.

For example, in this table of countries and cities, a stable sort on the second column, the cities, would keep the US Birmingham above the UK Birmingham. (Although an unstable sort might, in this case, place the US Birmingham above the UK Birmingham, a stable sort routine would guarantee it).

", + "
UK  London",
+      "US  New York",
+      "US  Birmingham",
+      "UK  Birmingham
", + "

Similarly, stable sorting on just the first column would generate “UK London” as the first item and “US Birmingham” as the last item (since the order of the elements having the same first word – “UK” or “US” – would be maintained).

Examine the documentation on any in-built sort routines supplied by a language.", + "Indicate if an in-built routine is supplied", + "If supplied, indicate whether or not the in-built routine is stable.", + "

(This Wikipedia table shows the stability of some common sort routines).

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "The ECMA standard does not specify what sorting algorithm to use, so it depends upon the implementation.", + "", + "ary = [[\"UK\", \"London\"], [\"US\", \"New York\"], [\"US\", \"Birmingham\"], [\"UK\", \"Birmingham\"]]", + "print(ary);", + "", + "ary.sort(function(a,b){return (a[1]b[1] ? 1 : 0))});", + "print(ary);", + "", + "/* a stable sort will output [\"US\", \"Birmingham\"] before [\"UK\", \"Birmingham\"] */", + "", + "Stable implementations:", + "{{works with|SpiderMonkey|1.8}}", + "{{works with|Firefox|3}}", + "{{works with|Internet Explorer|6}}", + "{{works with|JScript|5.7}}", + "{{works with|OSSP js}}", + "
UK,London,US,New York,US,Birmingham,UK,Birmingham",
+      "US,Birmingham,UK,Birmingham,UK,London,US,New York
", + "", + "Not stable:", + "{{works with|Rhino|1.7 rel 2}}", + "{{works with|Google Chrome|3.0}}", + "
UK,London,US,New York,US,Birmingham,UK,Birmingham",
+      "UK,Birmingham,US,Birmingham,UK,London,US,New York
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8014", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "ary = [[\"UK\", \"London\"], [\"US\", \"New York\"], [\"US\", \"Birmingham\"], [\"UK\", \"Birmingham\"]]\nprint(ary);\n\nary.sort(function(a,b){return (a[1]b[1] ? 1 : 0))});\nprint(ary);\n\n/* a stable sort will output [\"US\", \"Birmingham\"] before [\"UK\", \"Birmingham\"] */\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sort three variables", + "type": "Waypoint", + "description": [ + "Task: ", + "

Sort (the values of) three variables (X, Y, and Z) that contain any value (numbers and/or literals).

If that isn't possible in your language, then just sort numbers (and note if they can be floating point, integer, or other).

", + "

I.E.: (for the three variables x, y, and z), where:

", + "

x = 'lions, tigers, and'

", + "

y = 'bears, oh my!'

", + "

z = '(from the \"Wizard of OZ\")'

After sorting, the three variables would hold:

", + "

x = '(from the \"Wizard of OZ\")'

", + "

y = 'bears, oh my!'

", + "

z = 'lions, tigers, and'

", + "

For numeric value sorting, use:

I.E.: (for the three variables x, y, and z), where:

", + "

x = 77444

", + "

y = -12

", + "

z = 0

After sorting, the three variables would hold:

", + "

x = -12

", + "

y = 0

", + "

z = 77444

The variables should contain some form of a number, but specify if the algorithm

", + "

used can be for floating point or integers. Note any limitations.

", + "

The values may or may not be unique.

", + "

The method used for sorting can be any algorithm; the goal is to use the most idiomatic in the computer programming language used.

More than one algorithm could be shown if one isn't clearly the better choice.

", + "

One algorithm could be:

", + "

Θ store the three variables x, y, and z

", + "

into an array (or a list) A

Θ sort (the three elements of) the array A

Θ extract the three elements from the array and place them in the

", + "

variables x, y, and z in order of extraction

Show the results of the sort here on this page using at least the values of those shown above.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8015", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sort using a custom comparator", + "type": "Waypoint", + "description": [ + "Task:", + "

Sort an array (or list) of strings in order of descending length, and in ascending lexicographic order for strings of equal length.

Use a sorting facility provided by the language/library, combined with your own callback comparison function.

", + "

Note: Lexicographic order is case-insensitive.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "function lengthSorter(a, b) {", + " var result = b.length - a.length;", + " if (result == 0)", + " result = a.localeCompare(b);", + " return result;", + "}", + "", + "var test = [\"Here\", \"are\", \"some\", \"sample\", \"strings\", \"to\", \"be\", \"sorted\"];", + "test.sort(lengthSorter);", + "alert( test.join(' ') ); // strings sample sorted Here some are be to", + "", + "Or, abstracting a little for simpler composition of compound and derived searches (ASC and DESC, secondary sorts):", + "", + "(function () {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS FOR COMPARISONS", + "", + " // Ordering :: ( LT | EQ | GT ) | ( -1 | 0 | 1 )", + "", + " // compare :: a -> a -> Ordering", + " var compare = function (a, b) {", + " return a < b ? -1 : a > b ? 1 : 0;", + " };", + "", + " // mappendOrdering :: Ordering -> Ordering -> Ordering", + " var mappendOrdering = function (a, b) {", + " return a !== 0 ? a : b;", + " };", + "", + " // on :: (b -> b -> c) -> (a -> b) -> a -> a -> c", + " var on = function (f, g) {", + " return function (a, b) {", + " return f(g(a), g(b));", + " };", + " };", + "", + " // flip :: (a -> b -> c) -> b -> a -> c", + " var flip = function (f) {", + " return function (a, b) {", + " return f.apply(null, [b, a]);", + " };", + " };", + "", + " // arrayCopy :: [a] -> [a]", + " var arrayCopy = function (xs) {", + " return xs.slice(0);", + " };", + "", + " // show :: a -> String", + " var show = function (x) {", + " return JSON.stringify(x, null, 2);", + " };", + "", + " // TEST", + " var xs = ['Shanghai', 'Karachi', 'Beijing', 'Sao Paulo', 'Dhaka', 'Delhi', 'Lagos'];", + "", + " var rs = [{", + " name: 'Shanghai',", + " pop: 24.2", + " }, {", + " name: 'Karachi',", + " pop: 23.5", + " }, {", + " name: 'Beijing',", + " pop: 21.5", + " }, {", + " name: 'Sao Paulo',", + " pop: 24.2", + " }, {", + " name: 'Dhaka',", + " pop: 17.0", + " }, {", + " name: 'Delhi',", + " pop: 16.8", + " }, {", + " name: 'Lagos',", + " pop: 16.1", + " }];", + "", + " // population :: Dictionary -> Num", + " var population = function (x) {", + " return x.pop;", + " };", + "", + " // length :: [a] -> Int", + " var length = function (xs) {", + " return xs.length;", + " };", + "", + " // toLower :: String -> String", + " var toLower = function (s) {", + " return s.toLowerCase();", + " };", + "", + " // lengthThenAZ :: String -> String -> ( -1 | 0 | 1)", + " var lengthThenAZ = function (a, b) {", + " return mappendOrdering(", + " on(compare, length)(a, b),", + " on(compare, toLower)(a, b)", + " );", + " };", + "", + " // descLengthThenAZ :: String -> String -> ( -1 | 0 | 1)", + " var descLengthThenAZ = function (a, b) {", + " return mappendOrdering(", + " on(flip(compare), length)(a, b),", + " on(compare, toLower)(a, b)", + " );", + " };", + "", + " return show({", + " default: arrayCopy(xs)", + " .sort(compare),", + "", + " descendingDefault: arrayCopy(xs)", + " .sort(flip(compare)),", + "", + " byLengthThenAZ: arrayCopy(xs)", + " .sort(lengthThenAZ),", + "", + " byDescendingLengthThenZA: arrayCopy(xs)", + " .sort(flip(lengthThenAZ)),", + "", + " byDescendingLengthThenAZ: arrayCopy(xs)", + " .sort(descLengthThenAZ),", + "", + " byPopulation: arrayCopy(rs)", + " .sort(on(compare, population)),", + "", + " byDescendingPopulation: arrayCopy(rs)", + " .sort(on(flip(compare), population))", + " });", + "})();", + "", + "===ES6===", + "(() => {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS FOR COMPARISONS", + "", + " // Ordering :: ( LT | EQ | GT ) | ( -1 | 0 | 1 )", + " // compare :: a -> a -> Ordering", + " const compare = (a, b) => a < b ? -1 : (a > b ? 1 : 0);", + "", + " // mappendOrdering :: Ordering -> Ordering -> Ordering", + " const mappendOrdering = (a, b) => a !== 0 ? a : b;", + "", + " // on :: (b -> b -> c) -> (a -> b) -> a -> a -> c", + " const on = (f, g) => (a, b) => f(g(a), g(b));", + "", + " // flip :: (a -> b -> c) -> b -> a -> c", + " const flip = f => (a, b) => f.apply(null, [b, a]);", + "", + " // arrayCopy :: [a] -> [a]", + " const arrayCopy = (xs) => xs.slice(0);", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x, null, 2);", + "", + "", + " // TEST", + " const xs = ['Shanghai', 'Karachi', 'Beijing', 'Sao Paulo', 'Dhaka', 'Delhi', 'Lagos'];", + "", + " const rs = [{", + " name: 'Shanghai',", + " pop: 24.2", + " }, {", + " name: 'Karachi',", + " pop: 23.5", + " }, {", + " name: 'Beijing',", + " pop: 21.5", + " }, {", + " name: 'Sao Paulo',", + " pop: 24.2", + " }, {", + " name: 'Dhaka',", + " pop: 17.0", + " }, {", + " name: 'Delhi',", + " pop: 16.8", + " }, {", + " name: 'Lagos',", + " pop: 16.1", + " }]", + "", + " // population :: Dictionary -> Num", + " const population = x => x.pop;", + "", + " // length :: [a] -> Int", + " const length = xs => xs.length;", + "", + " // toLower :: String -> String", + " const toLower = s => s.toLowerCase();", + "", + " // lengthThenAZ :: String -> String -> ( -1 | 0 | 1)", + " const lengthThenAZ = (a, b) =>", + " mappendOrdering(", + " on(compare, length)(a, b),", + " on(compare, toLower)(a, b)", + " );", + "", + " // descLengthThenAZ :: String -> String -> ( -1 | 0 | 1)", + " const descLengthThenAZ = (a, b) =>", + " mappendOrdering(", + " on(flip(compare), length)(a, b),", + " on(compare, toLower)(a, b)", + " );", + "", + " return show({", + " default: arrayCopy(xs)", + " .sort(compare),", + "", + " descendingDefault: arrayCopy(xs)", + " .sort(flip(compare)),", + "", + " byLengthThenAZ: arrayCopy(xs)", + " .sort(lengthThenAZ),", + "", + " byDescendingLengthThenZA: arrayCopy(xs)", + " .sort(flip(lengthThenAZ)),", + "", + " byDescendingLengthThenAZ: arrayCopy(xs)", + " .sort(descLengthThenAZ),", + "", + " byPopulation: arrayCopy(rs)", + " .sort(on(compare, population)),", + "", + " byDescendingPopulation: arrayCopy(rs)", + " .sort(on(flip(compare), population))", + " });", + "})();", + "", + "{{Out}}", + "
{",
+      "  \"default\": [",
+      "    \"Beijing\",",
+      "    \"Delhi\",",
+      "    \"Dhaka\",",
+      "    \"Karachi\",",
+      "    \"Lagos\",",
+      "    \"Sao Paulo\",",
+      "    \"Shanghai\"",
+      "  ],",
+      "  \"descendingDefault\": [",
+      "    \"Shanghai\",",
+      "    \"Sao Paulo\",",
+      "    \"Lagos\",",
+      "    \"Karachi\",",
+      "    \"Dhaka\",",
+      "    \"Delhi\",",
+      "    \"Beijing\"",
+      "  ],",
+      "  \"byLengthThenAZ\": [",
+      "    \"Delhi\",",
+      "    \"Dhaka\",",
+      "    \"Lagos\",",
+      "    \"Beijing\",",
+      "    \"Karachi\",",
+      "    \"Shanghai\",",
+      "    \"Sao Paulo\"",
+      "  ],",
+      "  \"byDescendingLengthThenZA\": [",
+      "    \"Sao Paulo\",",
+      "    \"Shanghai\",",
+      "    \"Karachi\",",
+      "    \"Beijing\",",
+      "    \"Lagos\",",
+      "    \"Dhaka\",",
+      "    \"Delhi\"",
+      "  ],",
+      "  \"byDescendingLengthThenAZ\": [",
+      "    \"Sao Paulo\",",
+      "    \"Shanghai\",",
+      "    \"Beijing\",",
+      "    \"Karachi\",",
+      "    \"Delhi\",",
+      "    \"Dhaka\",",
+      "    \"Lagos\"",
+      "  ],",
+      "  \"byPopulation\": [",
+      "    {",
+      "      \"name\": \"Lagos\",",
+      "      \"pop\": 16.1",
+      "    },",
+      "    {",
+      "      \"name\": \"Delhi\",",
+      "      \"pop\": 16.8",
+      "    },",
+      "    {",
+      "      \"name\": \"Dhaka\",",
+      "      \"pop\": 17",
+      "    },",
+      "    {",
+      "      \"name\": \"Beijing\",",
+      "      \"pop\": 21.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Karachi\",",
+      "      \"pop\": 23.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Shanghai\",",
+      "      \"pop\": 24.2",
+      "    },",
+      "    {",
+      "      \"name\": \"Sao Paulo\",",
+      "      \"pop\": 24.2",
+      "    }",
+      "  ],",
+      "  \"byDescendingPopulation\": [",
+      "    {",
+      "      \"name\": \"Shanghai\",",
+      "      \"pop\": 24.2",
+      "    },",
+      "    {",
+      "      \"name\": \"Sao Paulo\",",
+      "      \"pop\": 24.2",
+      "    },",
+      "    {",
+      "      \"name\": \"Karachi\",",
+      "      \"pop\": 23.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Beijing\",",
+      "      \"pop\": 21.5",
+      "    },",
+      "    {",
+      "      \"name\": \"Dhaka\",",
+      "      \"pop\": 17",
+      "    },",
+      "    {",
+      "      \"name\": \"Delhi\",",
+      "      \"pop\": 16.8",
+      "    },",
+      "    {",
+      "      \"name\": \"Lagos\",",
+      "      \"pop\": 16.1",
+      "    }",
+      "  ]",
+      "}
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8016", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function lengthSorter(a, b) {\n var result = b.length - a.length;\n if (result == 0)\n result = a.localeCompare(b);\n return result;\n}\n\nvar test = [\"Here\", \"are\", \"some\", \"sample\", \"strings\", \"to\", \"be\", \"sorted\"];\ntest.sort(lengthSorter);\nalert( test.join(' ') ); // strings sample sorted Here some are be to\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Soundex", + "type": "Waypoint", + "description": [ + "

Soundex is an algorithm for creating indices for words based on their pronunciation.

", + "Task:", + "

The goal is for homophones to be encoded to the same representation so that they can be matched despite minor differences in spelling (from the WP article).

", + "Caution:", + "

There is a major issue in many of the implementations concerning the separation of two consonants that have the same soundex code! According to the official Rules https://www.archives.gov/research/census/soundex.html. So check for instance if Ashcraft is coded to A-261.

", + "If a vowel (A, E, I, O, U) separates two consonants that have the same soundex code, the consonant to the right of the vowel is coded. Tymczak is coded as T-522 (T, 5 for the M, 2 for the C, Z ignored (see \"Side-by-Side\" rule above), 2 for the K). Since the vowel \"A\" separates the Z and K, the K is coded.", + "If \"H\" or \"W\" separate two consonants that have the same soundex code, the consonant to the right of the vowel is not coded. Example: Ashcraft is coded A-261 (A, 2 for the S, C ignored, 6 for the R, 1 for the F). It is not coded A-226." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "==== Version w/o RegExp ====", + "var soundex = function (s) {", + " var a = s.toLowerCase().split('')", + " f = a.shift(),", + " r = '',", + " codes = {", + " a: '', e: '', i: '', o: '', u: '',", + " b: 1, f: 1, p: 1, v: 1,", + " c: 2, g: 2, j: 2, k: 2, q: 2, s: 2, x: 2, z: 2,", + " d: 3, t: 3,", + " l: 4,", + " m: 5, n: 5,", + " r: 6", + " };", + " ", + " r = f +", + " a", + " .map(function (v, i, a) { return codes[v] })", + " .filter(function (v, i, a) { return ((i === 0) ? v !== codes[f] : v !== a[i - 1]); })", + " .join('');", + " ", + " return (r + '000').slice(0, 4).toUpperCase();", + "};", + "", + "var tests = {", + " \"Soundex\": \"S532\",", + " \"Example\": \"E251\",", + " \"Sownteks\": \"S532\",", + " \"Ekzampul\": \"E251\",", + " \"Euler\": \"E460\",", + " \"Gauss\": \"G200\",", + " \"Hilbert\": \"H416\",", + " \"Knuth\": \"K530\",", + " \"Lloyd\": \"L300\",", + " \"Lukasiewicz\": \"L222\",", + " \"Ellery\": \"E460\",", + " \"Ghosh\": \"G200\",", + " \"Heilbronn\": \"H416\",", + " \"Kant\": \"K530\",", + " \"Ladd\": \"L300\",", + " \"Lissajous\": \"L222\",", + " \"Wheaton\": \"W350\",", + " \"Ashcraft\": \"A226\",", + " \"Burroughs\": \"B622\",", + " \"Burrows\": \"B620\",", + " \"O'Hara\": \"O600\"", + " };", + "", + "for (var i in tests)", + " if (tests.hasOwnProperty(i)) {", + " console.log(", + " i +", + " ' \\t' +", + " tests[i] +", + " '\\t' +", + " soundex(i) +", + " '\\t' +", + " (soundex(i) === tests[i])", + " );", + "}", + "", + "// Soundex S532 S532 true", + "// Example E251 E251 true", + "// Sownteks S532 S532 true", + "// Ekzampul E251 E251 true", + "// Euler E460 E460 true", + "// Gauss G200 G200 true", + "// Hilbert H416 H416 true", + "// Knuth K530 K530 true", + "// Lloyd L300 L300 true", + "// Lukasiewicz L222 L222 true", + "// Ellery E460 E460 true", + "// Ghosh G200 G200 true", + "// Heilbronn H416 H416 true", + "// Kant K530 K530 true", + "// Ladd L300 L300 true", + "// Lissajous L222 L222 true", + "// Wheaton W350 W350 true", + "// Ashcraft A226 A226 true", + "// Burroughs B622 B622 true", + "// Burrows B620 B620 true", + "// O'Hara O600 O600 true", + "", + "", + "==== Extended version w/ RegExp ====", + "", + "Note: This version differs from the one above in the following way. According to U.S. National Archives Website, consecutive consonants which map to the same code are not condensed to a single occurrence of the code if they are separated by vowels, but separating W and H do not thus intervene. Therefore Ashcraft is coded A261 and Burroughs is coded B620 rather than A226 and B622", + "", + "", + "function soundex(t) {", + " t = t.toUpperCase().replace(/[^A-Z]/g, '');", + " return (t[0] || '0') + t.replace(/[HW]/g, '')", + " .replace(/[BFPV]/g, '1')", + " .replace(/[CGJKQSXZ]/g, '2')", + " .replace(/[DT]/g, '3')", + " .replace(/[L]/g, '4')", + " .replace(/[MN]/g, '5')", + " .replace(/[R]/g, '6')", + " .replace(/(.)\\1+/g, '$1')", + " .substr(1)", + " .replace(/[AEOIUHWY]/g, '')", + " .concat('000')", + " .substr(0, 3);", + "}", + "", + "// tests", + "[ [\"Example\", \"E251\"], [\"Sownteks\", \"S532\"], [\"Lloyd\", \"L300\"], [\"12346\", \"0000\"],", + " [\"4-H\", \"H000\"], [\"Ashcraft\", \"A261\"], [\"Ashcroft\", \"A261\"], [\"auerbach\", \"A612\"],", + " [\"bar\", \"B600\"], [\"barre\", \"B600\"], [\"Baragwanath\", \"B625\"], [\"Burroughs\", \"B620\"],", + " [\"Burrows\", \"B620\"], [\"C.I.A.\", \"C000\"], [\"coöp\", \"C100\"], [\"D-day\", \"D000\"],", + " [\"d jay\", \"D200\"], [\"de la Rosa\", \"D462\"], [\"Donnell\", \"D540\"], [\"Dracula\", \"D624\"],", + " [\"Drakula\", \"D624\"], [\"Du Pont\", \"D153\"], [\"Ekzampul\", \"E251\"], [\"example\", \"E251\"],", + " [\"Ellery\", \"E460\"], [\"Euler\", \"E460\"], [\"F.B.I.\", \"F000\"], [\"Gauss\", \"G200\"],", + " [\"Ghosh\", \"G200\"], [\"Gutierrez\", \"G362\"], [\"he\", \"H000\"], [\"Heilbronn\", \"H416\"],", + " [\"Hilbert\", \"H416\"], [\"Jackson\", \"J250\"], [\"Johnny\", \"J500\"], [\"Jonny\", \"J500\"],", + " [\"Kant\", \"K530\"], [\"Knuth\", \"K530\"], [\"Ladd\", \"L300\"], [\"Lloyd\", \"L300\"],", + " [\"Lee\", \"L000\"], [\"Lissajous\", \"L222\"], [\"Lukasiewicz\", \"L222\"], [\"naïve\", \"N100\"],", + " [\"Miller\", \"M460\"], [\"Moses\", \"M220\"], [\"Moskowitz\", \"M232\"], [\"Moskovitz\", \"M213\"],", + " [\"O'Conner\", \"O256\"], [\"O'Connor\", \"O256\"], [\"O'Hara\", \"O600\"], [\"O'Mally\", \"O540\"],", + " [\"Peters\", \"P362\"], [\"Peterson\", \"P362\"], [\"Pfister\", \"P236\"], [\"R2-D2\", \"R300\"],", + " [\"rÄ≈sumÅ∙\", \"R250\"], [\"Robert\", \"R163\"], [\"Rupert\", \"R163\"], [\"Rubin\", \"R150\"],", + " [\"Soundex\", \"S532\"], [\"sownteks\", \"S532\"], [\"Swhgler\", \"S460\"], [\"'til\", \"T400\"],", + " [\"Tymczak\", \"T522\"], [\"Uhrbach\", \"U612\"], [\"Van de Graaff\", \"V532\"],", + " [\"VanDeusen\", \"V532\"], [\"Washington\", \"W252\"], [\"Wheaton\", \"W350\"],", + " [\"Williams\", \"W452\"], [\"Woolcock\", \"W422\"]", + "].forEach(function(v) {", + " var a = v[0], t = v[1], d = soundex(a);", + " if (d !== t) {", + " console.log('soundex(\"' + a + '\") was ' + d + ' should be ' + t);", + " }", + "}); ", + "", + "===ES6===", + "", + "Allowing for both Simple Soundex (first example above) and NARA Soundex (second example above)", + "(Reusing set of tests from second contribution)", + "", + "(() => {", + " 'use strict';", + "", + " // Simple Soundex or NARA Soundex (if blnNara = true)", + "", + " // soundex :: Bool -> String -> String", + " const soundex = (blnNara, name) => {", + "", + " // code :: Char -> Char", + " const code = c => ['AEIOU', 'BFPV', 'CGJKQSXZ', 'DT', 'L', 'MN', 'R', 'HW']", + " .reduce((a, x, i) =>", + " a ? a : (x.indexOf(c) !== -1 ? i.toString() : a), '');", + "", + " // isAlpha :: Char -> Boolean", + " const isAlpha = c => {", + " const d = c.charCodeAt(0);", + " return d > 64 && d < 91;", + " };", + "", + " const s = name.toUpperCase()", + " .split('')", + " .filter(isAlpha);", + "", + " return (s[0] || '0') +", + " s.map(code)", + " .join('')", + " .replace(/7/g, blnNara ? '' : '7')", + " .replace(/(.)\\1+/g, '$1')", + " .substr(1)", + " .replace(/[07]/g, '')", + " .concat('000')", + " .substr(0, 3);", + " };", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " const curry = f => a => b => f(a, b),", + " [simpleSoundex, naraSoundex] = [false, true]", + " .map(bln => curry(soundex)(bln));", + "", + " // TEST", + " return [", + " [\"Example\", \"E251\"],", + " [\"Sownteks\", \"S532\"],", + " [\"Lloyd\", \"L300\"],", + " [\"12346\", \"0000\"],", + " [\"4-H\", \"H000\"],", + " [\"Ashcraft\", \"A261\"],", + " [\"Ashcroft\", \"A261\"],", + " [\"auerbach\", \"A612\"],", + " [\"bar\", \"B600\"],", + " [\"barre\", \"B600\"],", + " [\"Baragwanath\", \"B625\"],", + " [\"Burroughs\", \"B620\"],", + " [\"Burrows\", \"B620\"],", + " [\"C.I.A.\", \"C000\"],", + " [\"coöp\", \"C100\"],", + " [\"D-day\", \"D000\"],", + " [\"d jay\", \"D200\"],", + " [\"de la Rosa\", \"D462\"],", + " [\"Donnell\", \"D540\"],", + " [\"Dracula\", \"D624\"],", + " [\"Drakula\", \"D624\"],", + " [\"Du Pont\", \"D153\"],", + " [\"Ekzampul\", \"E251\"],", + " [\"example\", \"E251\"],", + " [\"Ellery\", \"E460\"],", + " [\"Euler\", \"E460\"],", + " [\"F.B.I.\", \"F000\"],", + " [\"Gauss\", \"G200\"],", + " [\"Ghosh\", \"G200\"],", + " [\"Gutierrez\", \"G362\"],", + " [\"he\", \"H000\"],", + " [\"Heilbronn\", \"H416\"],", + " [\"Hilbert\", \"H416\"],", + " [\"Jackson\", \"J250\"],", + " [\"Johnny\", \"J500\"],", + " [\"Jonny\", \"J500\"],", + " [\"Kant\", \"K530\"],", + " [\"Knuth\", \"K530\"],", + " [\"Ladd\", \"L300\"],", + " [\"Lloyd\", \"L300\"],", + " [\"Lee\", \"L000\"],", + " [\"Lissajous\", \"L222\"],", + " [\"Lukasiewicz\", \"L222\"],", + " [\"naïve\", \"N100\"],", + " [\"Miller\", \"M460\"],", + " [\"Moses\", \"M220\"],", + " [\"Moskowitz\", \"M232\"],", + " [\"Moskovitz\", \"M213\"],", + " [\"O'Conner\", \"O256\"],", + " [\"O'Connor\", \"O256\"],", + " [\"O'Hara\", \"O600\"],", + " [\"O'Mally\", \"O540\"],", + " [\"Peters\", \"P362\"],", + " [\"Peterson\", \"P362\"],", + " [\"Pfister\", \"P236\"],", + " [\"R2-D2\", \"R300\"],", + " [\"rÄ≈sumÅ∙\", \"R250\"],", + " [\"Robert\", \"R163\"],", + " [\"Rupert\", \"R163\"],", + " [\"Rubin\", \"R150\"],", + " [\"Soundex\", \"S532\"],", + " [\"sownteks\", \"S532\"],", + " [\"Swhgler\", \"S460\"],", + " [\"'til\", \"T400\"],", + " [\"Tymczak\", \"T522\"],", + " [\"Uhrbach\", \"U612\"],", + " [\"Van de Graaff\", \"V532\"],", + " [\"VanDeusen\", \"V532\"],", + " [\"Washington\", \"W252\"],", + " [\"Wheaton\", \"W350\"],", + " [\"Williams\", \"W452\"],", + " [\"Woolcock\", \"W422\"]", + " ].reduce((a, [name, naraCode]) => {", + " const naraTest = naraSoundex(name),", + " simpleTest = simpleSoundex(name);", + "", + " const logNara = naraTest !== naraCode ? (", + " `${name} was ${naraTest} should be ${naraCode}`", + " ) : '',", + " logDelta = (naraTest !== simpleTest ? (", + " `${name} -> NARA: ${naraTest} vs Simple: ${simpleTest}`", + " ) : '');", + "", + " return logNara.length || logDelta.length ? (", + " a + [logNara, logDelta].join('\\n')", + " ) : a;", + " }, '');", + "})();", + "", + "{{Out}}", + "
Ashcraft -> NARA: A261 vs Simple: A226",
+      "Ashcroft -> NARA: A261 vs Simple: A226",
+      "Burroughs -> NARA: B620 vs Simple: B622",
+      "Swhgler -> NARA: S460 vs Simple: S246
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8017", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var soundex = function (s) {\n var a = s.toLowerCase().split('')\n f = a.shift(),\n r = '',\n codes = {\n a: '', e: '', i: '', o: '', u: '',\n b: 1, f: 1, p: 1, v: 1,\n c: 2, g: 2, j: 2, k: 2, q: 2, s: 2, x: 2, z: 2,\n d: 3, t: 3,\n l: 4,\n m: 5, n: 5,\n r: 6\n };\n \n r = f +\n a\n .map(function (v, i, a) { return codes[v] })\n .filter(function (v, i, a) { return ((i === 0) ? v !== codes[f] : v !== a[i - 1]); })\n .join('');\n \n return (r + '000').slice(0, 4).toUpperCase();\n};\n\nvar tests = {\n \"Soundex\": \"S532\",\n \"Example\": \"E251\",\n \"Sownteks\": \"S532\",\n \"Ekzampul\": \"E251\",\n \"Euler\": \"E460\",\n \"Gauss\": \"G200\",\n \"Hilbert\": \"H416\",\n \"Knuth\": \"K530\",\n \"Lloyd\": \"L300\",\n \"Lukasiewicz\": \"L222\",\n \"Ellery\": \"E460\",\n \"Ghosh\": \"G200\",\n \"Heilbronn\": \"H416\",\n \"Kant\": \"K530\",\n \"Ladd\": \"L300\",\n \"Lissajous\": \"L222\",\n \"Wheaton\": \"W350\",\n \"Ashcraft\": \"A226\",\n \"Burroughs\": \"B622\",\n \"Burrows\": \"B620\",\n \"O'Hara\": \"O600\"\n };\n\nfor (var i in tests)\n if (tests.hasOwnProperty(i)) {\n console.log(\n i +\n ' \\t' +\n tests[i] +\n '\\t' +\n soundex(i) +\n '\\t' +\n (soundex(i) === tests[i])\n );\n}\n\n// Soundex S532 S532 true\n// Example E251 E251 true\n// Sownteks S532 S532 true\n// Ekzampul E251 E251 true\n// Euler E460 E460 true\n// Gauss G200 G200 true\n// Hilbert H416 H416 true\n// Knuth K530 K530 true\n// Lloyd L300 L300 true\n// Lukasiewicz L222 L222 true\n// Ellery E460 E460 true\n// Ghosh G200 G200 true\n// Heilbronn H416 H416 true\n// Kant K530 K530 true\n// Ladd L300 L300 true\n// Lissajous L222 L222 true\n// Wheaton W350 W350 true\n// Ashcraft A226 A226 true\n// Burroughs B622 B622 true\n// Burrows B620 B620 true\n// O'Hara O600 O600 true\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Spiral matrix", + "type": "Waypoint", + "description": [ + "Task:", + "

Produce a spiral array.

", + "

A spiral array is a square arrangement of the first N2 natural numbers, where the

", + "numbers increase sequentially as you go around the edges of the array spiraling inwards.", + "

For example, given 5, produce this array:

", + "
",
+      " 0  1  2  3  4",
+      "15 16 17 18  5",
+      "14 23 24 19  6",
+      "13 22 21 20  7",
+      "12 11 10  9  8",
+      "
", + "Related tasks:", + " Zig-zag matrix ", + " Identity_matrix", + " Ulam_spiral_(for_primes)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Imperative===", + "", + "spiralArray = function (edge) {", + " var arr = Array(edge),", + " x = 0, y = edge,", + " total = edge * edge--,", + " dx = 1, dy = 0,", + " i = 0, j = 0;", + " while (y) arr[--y] = [];", + " while (i < total) {", + " arr[y][x] = i++;", + " x += dx; y += dy;", + " if (++j == edge) {", + " if (dy < 0) {x++; y++; edge -= 2}", + " j = dx; dx = -dy; dy = j; j = 0;", + " }", + " }", + " return arr;", + "}", + "", + "// T E S T:", + "arr = spiralArray(edge = 5);", + "for (y= 0; y < edge; y++) console.log(arr[y].join(\" \"));", + "", + "{{out}}", + "
",
+      "0 1 2 3 4",
+      "15 16 17 18 5",
+      "14 23 24 19 6",
+      "13 22 21 20 7",
+      "12 11 10 9 8
", + "", + "===Functional===", + "", + "====ES5====", + "", + "Translating one of the Haskell versions:", + "", + "(function (n) {", + "", + " // Spiral: the first row plus a smaller spiral rotated 90 degrees clockwise", + " function spiral(lngRows, lngCols, nStart) {", + " return lngRows ? [range(nStart, (nStart + lngCols) - 1)].concat(", + " transpose(", + " spiral(lngCols, lngRows - 1, nStart + lngCols)", + " ).map(reverse)", + " ) : [", + " []", + " ];", + " }", + "", + " // rows and columns transposed (for 90 degree rotation)", + " function transpose(lst) {", + " return lst.length > 1 ? lst[0].map(function (_, col) {", + " return lst.map(function (row) {", + " return row[col];", + " });", + " }) : lst;", + " }", + "", + " // elements in reverse order (for 90 degree rotation)", + " function reverse(lst) {", + " return lst.length > 1 ? lst.reduceRight(function (acc, x) {", + " return acc.concat(x);", + " }, []) : lst;", + " }", + "", + " // [m..n]", + " function range(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(function (x, i) {", + " return m + i;", + " });", + " }", + "", + " // TESTING", + " ", + " var lstSpiral = spiral(n, n, 0);", + "", + "", + " // OUTPUT FORMATTING - JSON and wikiTable", + " function wikiTable(lstRows, blnHeaderRow, strStyle) {", + " return '{| class=\"wikitable\" ' + (", + " strStyle ? 'style=\"' + strStyle + '\"' : ''", + " ) + lstRows.map(function (lstRow, iRow) {", + " var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');", + "", + " return '\\n|-\\n' + strDelim + ' ' + lstRow.map(function (v) {", + " return typeof v === 'undefined' ? ' ' : v;", + " }).join(' ' + strDelim + strDelim + ' ');", + " }).join('') + '\\n|}';", + " }", + "", + " return [", + " wikiTable(", + "", + " lstSpiral,", + "", + " false,", + " 'text-align:center;width:12em;height:12em;table-layout:fixed;'", + " ),", + " ", + " JSON.stringify(lstSpiral)", + " ].join('\\n\\n');", + "", + "})(5);", + "", + "Output:", + "", + "{| class=\"wikitable\" style=\"text-align:center;width:12em;height:12em;table-layout:fixed;\"", + "|-", + "| 0 || 1 || 2 || 3 || 4", + "|-", + "| 15 || 16 || 17 || 18 || 5", + "|-", + "| 14 || 23 || 24 || 19 || 6", + "|-", + "| 13 || 22 || 21 || 20 || 7", + "|-", + "| 12 || 11 || 10 || 9 || 8", + "|}", + "", + "[[0,1,2,3,4],[15,16,17,18,5],[14,23,24,19,6],[13,22,21,20,7],[12,11,10,9,8]]", + "", + "", + "====ES6====", + "", + "(n => {", + "", + " // spiral :: the first row plus a smaller spiral rotated 90 degrees clockwise", + " // spiral :: Int -> Int -> Int -> [[Int]]", + " function spiral(lngRows, lngCols, nStart) {", + " return lngRows ? [range(nStart, (nStart + lngCols) - 1)]", + " .concat(", + " transpose(", + " spiral(lngCols, lngRows - 1, nStart + lngCols)", + " )", + " .map(reverse)", + " ) : [[]];", + " }", + "", + " // transpose :: [[a]] -> [[a]]", + " function transpose(xs) {", + " return xs[0]", + " .map((_, iCol) => xs", + " .map((row) => row[iCol]));", + " }", + "", + " // reverse :: [a] -> [a]", + " function reverse(xs) {", + " return xs.slice(0)", + " .reverse();", + " }", + "", + " // range(intFrom, intTo, optional intStep)", + " // Int -> Int -> Maybe Int -> [Int]", + " function range(m, n, step) {", + " let d = (step || 1) * (n >= m ? 1 : -1);", + "", + " return Array.from({", + " length: Math.floor((n - m) / d) + 1", + " }, (_, i) => m + (i * d));", + " }", + "", + "", + "", + " // TESTING", + "", + " // replicate :: Int -> String -> String", + " function replicate(n, a) {", + " var v = [a],", + " o = '';", + "", + " if (n < 1) return o;", + " while (n > 1) {", + " if (n & 1) o = o + v;", + " n >>= 1;", + " v = v + v;", + " }", + " return o + v;", + " }", + "", + "", + " return spiral(n, n, 0)", + " .map(", + " xs => xs.map(x => {", + " let s = `${x}`;", + " return replicate(4 - s.length, ' ') + s;", + " })", + " .join('')", + " )", + " .join('\\n');", + "", + "})(5);", + "", + "", + "
 0   1   2   3   4",
+      "15  16  17  18   5",
+      "14  23  24  19   6",
+      "13  22  21  20   7",
+      "12  11  10   9   8
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc801c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "spiralArray = function (edge) {\n var arr = Array(edge),\n x = 0, y = edge,\n total = edge * edge--,\n dx = 1, dy = 0,\n i = 0, j = 0;\n while (y) arr[--y] = [];\n while (i < total) {\n arr[y][x] = i++;\n x += dx; y += dy;\n if (++j == edge) {\n if (dy < 0) {x++; y++; edge -= 2}\n j = dx; dx = -dy; dy = j; j = 0;\n }\n }\n return arr;\n}\n\n// T E S T:\narr = spiralArray(edge = 5);\nfor (y= 0; y < edge; y++) console.log(arr[y].join(\" \"));\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Split a character string based on change of character", + "type": "Waypoint", + "description": [ + "

", + "

Task:", + "

Split a (character) string into comma (plus a blank) delimited

", + "

strings based on a change of character (left to right).

Show the output here (use the 1st example below).

", + "

Blanks should be treated as any other character (except

", + "

they are problematic to display clearly). The same applies

", + "

to commas.

", + "

For instance, the string:

", + "

gHHH5YY++///\\

", + "

should be split and show:

", + "

g, HHH, 5, YY, ++, ///, \\

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // concat :: [[a]] -> [a] | [String] -> String", + " const concat = xs =>", + " xs.length > 0 ? (() => {", + " const unit = typeof xs[0] === 'string' ? '' : [];", + " return unit.concat.apply(unit, xs);", + " })() : [];", + "", + " // group :: Eq a => [a] -> [[a]]", + " const group = xs => groupBy((a, b) => a === b, xs);", + "", + " // groupBy :: (a -> a -> Bool) -> [a] -> [[a]]", + " const groupBy = (f, xs) => {", + " const dct = xs.slice(1)", + " .reduce((a, x) => {", + " const", + " h = a.active.length > 0 ? a.active[0] : undefined,", + " blnGroup = h !== undefined && f(h, x);", + " return {", + " active: blnGroup ? a.active.concat([x]) : [x],", + " sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])", + " };", + " }, {", + " active: xs.length > 0 ? [xs[0]] : [],", + " sofar: []", + " });", + " return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);", + " };", + "", + " // intercalate :: String -> [a] -> String", + " const intercalate = (s, xs) => xs.join(s);", + "", + " // map :: (a -> b) -> [a] -> [b]", + " const map = (f, xs) => xs.map(f);", + "", + " // show :: a -> String", + " const show = (...x) =>", + " JSON.stringify.apply(", + " null, x.length > 1 ? [x[0], null, x[1]] : x", + " );", + "", + " // stringChars :: String -> [Char]", + " const stringChars = s => s.split('');", + "", + "", + " // TEST -------------------------------------------------------------------", + " return show(", + " intercalate(', ',", + " map(concat, group(stringChars('gHHH5YY++///\\\\')))", + " )", + " );", + "", + " // -> \"g, HHH, 5, YY, ++, ///, \\\\\"", + "})();", + "{{Out}}", + "
g, HHH, 5, YY, ++, ///, \\
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc801d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n // GENERIC FUNCTIONS ------------------------------------------------------\n\n // concat :: [[a]] -> [a] | [String] -> String\n const concat = xs =>\n xs.length > 0 ? (() => {\n const unit = typeof xs[0] === 'string' ? '' : [];\n return unit.concat.apply(unit, xs);\n })() : [];\n\n // group :: Eq a => [a] -> [[a]]\n const group = xs => groupBy((a, b) => a === b, xs);\n\n // groupBy :: (a -> a -> Bool) -> [a] -> [[a]]\n const groupBy = (f, xs) => {\n const dct = xs.slice(1)\n .reduce((a, x) => {\n const\n h = a.active.length > 0 ? a.active[0] : undefined,\n blnGroup = h !== undefined && f(h, x);\n return {\n active: blnGroup ? a.active.concat([x]) : [x],\n sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])\n };\n }, {\n active: xs.length > 0 ? [xs[0]] : [],\n sofar: []\n });\n return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);\n };\n\n // intercalate :: String -> [a] -> String\n const intercalate = (s, xs) => xs.join(s);\n\n // map :: (a -> b) -> [a] -> [b]\n const map = (f, xs) => xs.map(f);\n\n // show :: a -> String\n const show = (...x) =>\n JSON.stringify.apply(\n null, x.length > 1 ? [x[0], null, x[1]] : x\n );\n\n // stringChars :: String -> [Char]\n const stringChars = s => s.split('');\n\n\n // TEST -------------------------------------------------------------------\n return show(\n intercalate(', ',\n map(concat, group(stringChars('gHHH5YY++///\\\\')))\n )\n );\n\n // -> \"g, HHH, 5, YY, ++, ///, \\\\\"\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Stable marriage problem", + "type": "Waypoint", + "description": [ + "

Solve the Stable marriage problem using the Gale/Shapley algorithm.

", + "

Problem description

", + "

Given an equal number of men and women to be paired for marriage, each man ranks all the women in order of his preference and each woman ranks all the men in order of her preference.

A stable set of engagements for marriage is one where no man prefers a woman over the one he is engaged to, where that other woman also prefers that man over the one she is engaged to. I.e. with consulting marriages, there would be no reason for the engagements between the people to change.

Gale and Shapley proved that there is a stable set of engagements for any set of preferences and the first link above gives their algorithm for finding a set of stable engagements.

", + "

Task Specifics

", + "

Given ten males:

", + "

abe, bob, col, dan, ed, fred, gav, hal, ian, jon

", + "

And ten females:

", + "

abi, bea, cath, dee, eve, fay, gay, hope, ivy, jan

And a complete list of ranked preferences, where the most liked is to the left:

", + "

abe: abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay

", + "

bob: cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay

", + "

col: hope, eve, abi, dee, bea, fay, ivy, gay, cath, jan

", + "

dan: ivy, fay, dee, gay, hope, eve, jan, bea, cath, abi

", + "

ed: jan, dee, bea, cath, fay, eve, abi, ivy, hope, gay

", + "

fred: bea, abi, dee, gay, eve, ivy, cath, jan, hope, fay

", + "

gav: gay, eve, ivy, bea, cath, abi, dee, hope, jan, fay

", + "

hal: abi, eve, hope, fay, ivy, cath, jan, bea, gay, dee

", + "

ian: hope, cath, dee, gay, bea, abi, fay, ivy, jan, eve

", + "

jon: abi, fay, jan, gay, eve, bea, dee, cath, ivy, hope

abi: bob, fred, jon, gav, ian, abe, dan, ed, col, hal

", + "

bea: bob, abe, col, fred, gav, dan, ian, ed, jon, hal

", + "

cath: fred, bob, ed, gav, hal, col, ian, abe, dan, jon

", + "

dee: fred, jon, col, abe, ian, hal, gav, dan, bob, ed

", + "

eve: jon, hal, fred, dan, abe, gav, col, ed, ian, bob

", + "

fay: bob, abe, ed, ian, jon, dan, fred, gav, col, hal

", + "

gay: jon, gav, hal, fred, bob, abe, col, ed, dan, ian

", + "

hope: gav, jon, bob, abe, ian, dan, hal, ed, col, fred

", + "

ivy: ian, col, hal, gav, fred, bob, abe, ed, jon, dan

", + "

jan: ed, hal, gav, abe, bob, jon, col, ian, fred, dan

Use the Gale Shapley algorithm to find a stable set of engagements", + "Perturb this set of engagements to form an unstable set of engagements then check this new set for stability.

References

", + " The Stable Marriage Problem. (Eloquent description and background information).", + "Gale-Shapley Algorithm Demonstration.", + "Another Gale-Shapley Algorithm Demonstration.", + "Stable Marriage Problem - Numberphile (Video).", + "Stable Marriage Problem (the math bit) (Video).", + "The Stable Marriage Problem and School Choice. (Excellent exposition)" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function Person(name) {", + "", + " var candidateIndex = 0;", + "", + " this.name = name;", + " this.fiance = null;", + " this.candidates = [];", + "", + " this.rank = function(p) {", + " for (i = 0; i < this.candidates.length; i++)", + " if (this.candidates[i] === p) return i;", + " return this.candidates.length + 1;", + " }", + "", + " this.prefers = function(p) {", + " return this.rank(p) < this.rank(this.fiance);", + " }", + "", + " this.nextCandidate = function() {", + " if (candidateIndex >= this.candidates.length) return null;", + " return this.candidates[candidateIndex++];", + " }", + "", + " this.engageTo = function(p) {", + " if (p.fiance) p.fiance.fiance = null;", + " p.fiance = this;", + " if (this.fiance) this.fiance.fiance = null;", + " this.fiance = p;", + " }", + "", + " this.swapWith = function(p) {", + " console.log(\"%s & %s swap partners\", this.name, p.name);", + " var thisFiance = this.fiance;", + " var pFiance = p.fiance;", + " this.engageTo(pFiance);", + " p.engageTo(thisFiance);", + " }", + "}", + "", + "function isStable(guys, gals) {", + " for (var i = 0; i < guys.length; i++)", + " for (var j = 0; j < gals.length; j++)", + " if (guys[i].prefers(gals[j]) && gals[j].prefers(guys[i]))", + " return false;", + " return true;", + "}", + "", + "function engageEveryone(guys) {", + " var done;", + " do {", + " done = true;", + " for (var i = 0; i < guys.length; i++) {", + " var guy = guys[i];", + " if (!guy.fiance) {", + " done = false;", + " var gal = guy.nextCandidate();", + " if (!gal.fiance || gal.prefers(guy))", + " guy.engageTo(gal);", + " }", + " }", + " } while (!done);", + "}", + "", + "function doMarriage() {", + "", + " var abe = new Person(\"Abe\");", + " var bob = new Person(\"Bob\");", + " var col = new Person(\"Col\");", + " var dan = new Person(\"Dan\");", + " var ed = new Person(\"Ed\");", + " var fred = new Person(\"Fred\");", + " var gav = new Person(\"Gav\");", + " var hal = new Person(\"Hal\");", + " var ian = new Person(\"Ian\");", + " var jon = new Person(\"Jon\");", + " var abi = new Person(\"Abi\");", + " var bea = new Person(\"Bea\");", + " var cath = new Person(\"Cath\");", + " var dee = new Person(\"Dee\");", + " var eve = new Person(\"Eve\");", + " var fay = new Person(\"Fay\");", + " var gay = new Person(\"Gay\");", + " var hope = new Person(\"Hope\");", + " var ivy = new Person(\"Ivy\");", + " var jan = new Person(\"Jan\");", + "", + " abe.candidates = [abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay];", + " bob.candidates = [cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay];", + " col.candidates = [hope, eve, abi, dee, bea, fay, ivy, gay, cath, jan];", + " dan.candidates = [ivy, fay, dee, gay, hope, eve, jan, bea, cath, abi];", + " ed.candidates = [jan, dee, bea, cath, fay, eve, abi, ivy, hope, gay];", + " fred.candidates = [bea, abi, dee, gay, eve, ivy, cath, jan, hope, fay];", + " gav.candidates = [gay, eve, ivy, bea, cath, abi, dee, hope, jan, fay];", + " hal.candidates = [abi, eve, hope, fay, ivy, cath, jan, bea, gay, dee];", + " ian.candidates = [hope, cath, dee, gay, bea, abi, fay, ivy, jan, eve];", + " jon.candidates = [abi, fay, jan, gay, eve, bea, dee, cath, ivy, hope];", + " abi.candidates = [bob, fred, jon, gav, ian, abe, dan, ed, col, hal];", + " bea.candidates = [bob, abe, col, fred, gav, dan, ian, ed, jon, hal];", + " cath.candidates = [fred, bob, ed, gav, hal, col, ian, abe, dan, jon];", + " dee.candidates = [fred, jon, col, abe, ian, hal, gav, dan, bob, ed];", + " eve.candidates = [jon, hal, fred, dan, abe, gav, col, ed, ian, bob];", + " fay.candidates = [bob, abe, ed, ian, jon, dan, fred, gav, col, hal];", + " gay.candidates = [jon, gav, hal, fred, bob, abe, col, ed, dan, ian];", + " hope.candidates = [gav, jon, bob, abe, ian, dan, hal, ed, col, fred];", + " ivy.candidates = [ian, col, hal, gav, fred, bob, abe, ed, jon, dan];", + " jan.candidates = [ed, hal, gav, abe, bob, jon, col, ian, fred, dan];", + "", + " var guys = [abe, bob, col, dan, ed, fred, gav, hal, ian, jon];", + " var gals = [abi, bea, cath, dee, eve, fay, gay, hope, ivy, jan];", + "", + " engageEveryone(guys);", + "", + " for (var i = 0; i < guys.length; i++) {", + " console.log(\"%s is engaged to %s\", guys[i].name, guys[i].fiance.name);", + " }", + " console.log(\"Stable = %s\", isStable(guys, gals) ? \"Yes\" : \"No\");", + " jon.swapWith(fred);", + " console.log(\"Stable = %s\", isStable(guys, gals) ? \"Yes\" : \"No\");", + "}", + "", + "doMarriage();", + "", + "", + "{{out}}", + "
Abe is engaged to Ivy",
+      "Bob is engaged to Cath",
+      "Col is engaged to Dee",
+      "Dan is engaged to Fay",
+      "Ed is engaged to Jan",
+      "Fred is engaged to Bea",
+      "Gav is engaged to Gay",
+      "Hal is engaged to Eve",
+      "Ian is engaged to Hope",
+      "Jon is engaged to Abi",
+      "Stable = Yes",
+      "Jon & Fred swap partners",
+      "Stable = No
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc801f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function Person(name) {\n\n var candidateIndex = 0;\n\n this.name = name;\n this.fiance = null;\n this.candidates = [];\n\n this.rank = function(p) {\n for (i = 0; i < this.candidates.length; i++)\n if (this.candidates[i] === p) return i;\n return this.candidates.length + 1;\n }\n\n this.prefers = function(p) {\n return this.rank(p) < this.rank(this.fiance);\n }\n\n this.nextCandidate = function() {\n if (candidateIndex >= this.candidates.length) return null;\n return this.candidates[candidateIndex++];\n }\n\n this.engageTo = function(p) {\n if (p.fiance) p.fiance.fiance = null;\n p.fiance = this;\n if (this.fiance) this.fiance.fiance = null;\n this.fiance = p;\n }\n\n this.swapWith = function(p) {\n console.log(\"%s & %s swap partners\", this.name, p.name);\n var thisFiance = this.fiance;\n var pFiance = p.fiance;\n this.engageTo(pFiance);\n p.engageTo(thisFiance);\n }\n}\n\nfunction isStable(guys, gals) {\n for (var i = 0; i < guys.length; i++)\n for (var j = 0; j < gals.length; j++)\n if (guys[i].prefers(gals[j]) && gals[j].prefers(guys[i]))\n return false;\n return true;\n}\n\nfunction engageEveryone(guys) {\n var done;\n do {\n done = true;\n for (var i = 0; i < guys.length; i++) {\n var guy = guys[i];\n if (!guy.fiance) {\n done = false;\n var gal = guy.nextCandidate();\n if (!gal.fiance || gal.prefers(guy))\n guy.engageTo(gal);\n }\n }\n } while (!done);\n}\n\nfunction doMarriage() {\n\n var abe = new Person(\"Abe\");\n var bob = new Person(\"Bob\");\n var col = new Person(\"Col\");\n var dan = new Person(\"Dan\");\n var ed = new Person(\"Ed\");\n var fred = new Person(\"Fred\");\n var gav = new Person(\"Gav\");\n var hal = new Person(\"Hal\");\n var ian = new Person(\"Ian\");\n var jon = new Person(\"Jon\");\n var abi = new Person(\"Abi\");\n var bea = new Person(\"Bea\");\n var cath = new Person(\"Cath\");\n var dee = new Person(\"Dee\");\n var eve = new Person(\"Eve\");\n var fay = new Person(\"Fay\");\n var gay = new Person(\"Gay\");\n var hope = new Person(\"Hope\");\n var ivy = new Person(\"Ivy\");\n var jan = new Person(\"Jan\");\n\n abe.candidates = [abi, eve, cath, ivy, jan, dee, fay, bea, hope, gay];\n bob.candidates = [cath, hope, abi, dee, eve, fay, bea, jan, ivy, gay];\n col.candidates = [hope, eve, abi, dee, bea, fay, ivy, gay, cath, jan];\n dan.candidates = [ivy, fay, dee, gay, hope, eve, jan, bea, cath, abi];\n ed.candidates = [jan, dee, bea, cath, fay, eve, abi, ivy, hope, gay];\n fred.candidates = [bea, abi, dee, gay, eve, ivy, cath, jan, hope, fay];\n gav.candidates = [gay, eve, ivy, bea, cath, abi, dee, hope, jan, fay];\n hal.candidates = [abi, eve, hope, fay, ivy, cath, jan, bea, gay, dee];\n ian.candidates = [hope, cath, dee, gay, bea, abi, fay, ivy, jan, eve];\n jon.candidates = [abi, fay, jan, gay, eve, bea, dee, cath, ivy, hope];\n abi.candidates = [bob, fred, jon, gav, ian, abe, dan, ed, col, hal];\n bea.candidates = [bob, abe, col, fred, gav, dan, ian, ed, jon, hal];\n cath.candidates = [fred, bob, ed, gav, hal, col, ian, abe, dan, jon];\n dee.candidates = [fred, jon, col, abe, ian, hal, gav, dan, bob, ed];\n eve.candidates = [jon, hal, fred, dan, abe, gav, col, ed, ian, bob];\n fay.candidates = [bob, abe, ed, ian, jon, dan, fred, gav, col, hal];\n gay.candidates = [jon, gav, hal, fred, bob, abe, col, ed, dan, ian];\n hope.candidates = [gav, jon, bob, abe, ian, dan, hal, ed, col, fred];\n ivy.candidates = [ian, col, hal, gav, fred, bob, abe, ed, jon, dan];\n jan.candidates = [ed, hal, gav, abe, bob, jon, col, ian, fred, dan];\n\n var guys = [abe, bob, col, dan, ed, fred, gav, hal, ian, jon];\n var gals = [abi, bea, cath, dee, eve, fay, gay, hope, ivy, jan];\n\n engageEveryone(guys);\n\n for (var i = 0; i < guys.length; i++) {\n console.log(\"%s is engaged to %s\", guys[i].name, guys[i].fiance.name);\n }\n console.log(\"Stable = %s\", isStable(guys, gals) ? \"Yes\" : \"No\");\n jon.swapWith(fred);\n console.log(\"Stable = %s\", isStable(guys, gals) ? \"Yes\" : \"No\");\n}\n\ndoMarriage();\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Stack", + "type": "Waypoint", + "description": [ + "

A stack is a container of elements with last in, first out access policy. Sometimes it also called LIFO.

The stack is accessed through its top.

The basic stack operations are:

push stores a new element onto the stack top;", + " pop returns the last pushed stack element, while removing it from the stack;", + " empty tests if the stack contains no elements.", + "

Sometimes the last pushed stack element is made accessible for immutable access (for read) or mutable access (for write):

top (sometimes called peek to keep with the p theme) returns the topmost element without modifying the stack.", + "

Stacks allow a very simple hardware implementation.

They are common in almost all processors.

In programming, stacks are also very popular for their way (LIFO) of resource management, usually memory.

Nested scopes of language objects are naturally implemented by a stack (sometimes by multiple stacks).

This is a classical way to implement local variables of a re-entrant or recursive subprogram. Stacks are also used to describe a formal computational framework.

See stack machine.

Many algorithms in pattern matching, compiler construction (e.g. recursive descent parsers), and machine learning (e.g. based on tree traversal) have a natural representation in terms of stacks.

", + "Task:", + "

Create a stack supporting the basic operations: push, pop, empty.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "The built-in Array class already has stack primitives.", + "var stack = [];", + "stack.push(1)", + "stack.push(2,3);", + "print(stack.pop()); // 3", + "print(stack.length); // 2, stack empty if 0", + "Here's a constructor that wraps the array:", + "function Stack() {", + " this.data = new Array();", + "", + " this.push = function(element) {this.data.push(element)}", + " this.pop = function() {return this.data.pop()}", + " this.empty = function() {return this.data.length == 0}", + " this.peek = function() {return this.data[this.data.length - 1]}", + "}", + "Here's an example using the revealing module pattern instead of prototypes.", + "", + "function makeStack() {", + " var stack = [];", + "", + " var popStack = function () {", + " return stack.pop();", + " };", + " var pushStack = function () {", + " return stack.push.apply(stack, arguments);", + " };", + " var isEmpty = function () {", + " return stack.length === 0;", + " };", + " var peekStack = function () {", + " return stack[stack.length-1];", + " };", + " ", + " return {", + " pop: popStack,", + " push: pushStack,", + " isEmpty: isEmpty,", + " peek: peekStack,", + " top: peekStack", + " };", + "}", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8020", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var stack = [];\nstack.push(1)\nstack.push(2,3);\nprint(stack.pop()); // 3\nprint(stack.length); // 2, stack empty if 0\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Stair-climbing puzzle", + "type": "Waypoint", + "description": [ + "

From Chung-Chieh Shan (LtU):

Your stair-climbing robot has a very simple low-level API: the \"step\" function takes no argument and attempts to climb one step as a side effect. Unfortunately, sometimes the attempt fails and the robot clumsily falls one step instead. The \"step\" function detects what happens and returns a boolean flag: true on success, false on failure.

Write a function \"step_up\" that climbs one step up [from the initial position] (by repeating \"step\" attempts if necessary). Assume that the robot is not already at the top of the stairs, and neither does it ever reach the bottom of the stairs. How small can you make \"step_up\"? Can you avoid using variables (even immutable ones) and numbers?

Here's a pseudo-code of a simple recursive solution without using variables:

", + "
",
+      "func step_up()",
+      "{",
+      "    if not step() {",
+      "        step_up();",
+      "        step_up();",
+      "    }",
+      "}",
+      "
", + "

Inductive proof that step_up() steps up one step, if it terminates:

", + "Base case (if the step() call returns true): it stepped up one step. QED", + "Inductive case (if the step() call returns false): Assume that recursive calls to step_up() step up one step. It stepped down one step (because step() returned false), but now we step up two steps using two step_up() calls. QED", + "

The second (tail) recursion above can be turned into an iteration, as follows:

", + "
",
+      "func step_up()",
+      "{",
+      "    while not step() {",
+      "        step_up();",
+      "    }",
+      "}",
+      "
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8022", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "State name puzzle", + "type": "Waypoint", + "description": [ + "

Background

This task is inspired by Mark Nelson's DDJ Column \"Wordplay\" and one of the weekly puzzle challenges from Will Shortz on NPR Weekend Edition [http://www.npr.org/templates/story/story.php?storyId=9264290] and originally attributed to David Edelheit.

The challenge was to take the names of two U.S. States, mix them all together, then rearrange the letters to form the names of two different U.S. States (so that all four state names differ from one another).

What states are these?

", + "

The problem was reissued on the Unicon Discussion Web which includes several solutions with analysis. Several techniques may be helpful and you may wish to refer to Gödel numbering, equivalence relations, and equivalence classes. The basic merits of these were discussed in the Unicon Discussion Web.

A second challenge in the form of a set of fictitious new states was also presented.

Task:

", + "

Write a program to solve the challenge using both the original list of states and the fictitious list.

Caveats:

", + "case and spacing aren't significant - just letters (harmonize case)", + "don't expect the names to be in any order - such as being sorted", + "don't rely on names to be unique (eliminate duplicates - meaning if Iowa appears twice you can only use it once)", + "

Comma separated list of state names used in the original puzzle:

", + "
",
+      "    \"Alabama\", \"Alaska\", \"Arizona\", \"Arkansas\",",
+      "    \"California\", \"Colorado\", \"Connecticut\",",
+      "    \"Delaware\",    ",
+      "    \"Florida\", \"Georgia\", \"Hawaii\",",
+      "    \"Idaho\", \"Illinois\", \"Indiana\", \"Iowa\",",
+      "    \"Kansas\", \"Kentucky\", \"Louisiana\",",
+      "    \"Maine\", \"Maryland\", \"Massachusetts\", \"Michigan\",",
+      "    \"Minnesota\", \"Mississippi\", \"Missouri\", \"Montana\",",
+      "    \"Nebraska\", \"Nevada\", \"New Hampshire\", \"New Jersey\",",
+      "    \"New Mexico\", \"New York\", \"North Carolina\", \"North Dakota\",",
+      "    \"Ohio\", \"Oklahoma\", \"Oregon\",",
+      "    \"Pennsylvania\", \"Rhode Island\",",
+      "    \"South Carolina\", \"South Dakota\", \"Tennessee\", \"Texas\",",
+      "    \"Utah\", \"Vermont\", \"Virginia\",",
+      "    \"Washington\", \"West Virginia\", \"Wisconsin\", \"Wyoming\"",
+      "
", + "

Comma separated list of additional fictitious state names to be added to the original (Includes a duplicate):

", + "
",
+      "\"New Kory\", \"Wen Kory\", \"York New\", \"Kory New\", \"New Kory\"",
+      "
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8024", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Stem-and-leaf plot", + "type": "Waypoint", + "description": [ + "

Create a well-formatted stem-and-leaf plot from the following data set, where the leaves are the last digits:

12 127 28 42 39 113 42 18 44 118 44 37 113 124 37 48 127 36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 114 126 53 114 96 25 109 7 31 141 46 13 27 43 117 116 27 7 68 40 31 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 127 31 116 146

", + "

The primary intent of this task is the presentation of information. It is acceptable to hardcode the data set or characteristics of it (such as what the stems are) in the example, insofar as it is impractical to make the example generic to any data set. For example, in a computation-less language like HTML the data set may be entirely prearranged within the example; the interesting characteristics are how the proper visual formatting is arranged.

If possible, the output should not be a bitmap image. Monospaced plain text is acceptable, but do better if you can. It may be a window, i.e. not a file.

", + "

Note: If you wish to try multiple data sets, you might try this generator.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "It turns out that HTML+CSS renders the plot quite attractively.", + "", + "", + "", + "", + "stem and leaf plot", + "", + "", + "", + "", + "", + "
", + "", + "", + "", + "", + "
", + "", + "The output looks like: ", + "", + "[[File:Stemplot.png]]", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8027", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["null\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Stern-Brocot sequence", + "type": "Waypoint", + "description": [ + "

For this task, the Stern-Brocot sequence is to be generated by an algorithm similar to that employed in generating the Fibonacci sequence.

The first and second members of the sequence are both 1:", + "* 1, 1", + "Start by considering the second member of the sequence", + "Sum the considered member of the sequence and its precedent, (1 + 1) = 2, and append it to the end of the sequence:", + "* 1, 1, 2", + "Append the considered member of the sequence to the end of the sequence:", + "* 1, 1, 2, 1", + "Consider the next member of the series, (the third member i.e. 2)", + "GOTO 3 ", + "* ", + "* ─── Expanding another loop we get: ───", + "*", + "Sum the considered member of the sequence and its precedent, (2 + 1) = 3, and append it to the end of the sequence:", + "* 1, 1, 2, 1, 3", + "Append the considered member of the sequence to the end of the sequence:", + "* 1, 1, 2, 1, 3, 2", + "Consider the next member of the series, (the fourth member i.e. 1)The task is to:", + "Create a function/method/subroutine/procedure/... to generate the Stern-Brocot sequence of integers using the method outlined above.", + "Show the first fifteen members of the sequence. (This should be: 1, 1, 2, 1, 3, 2, 3, 1, 4, 3, 5, 2, 5, 3, 4)", + "Show the (1-based) index of where the numbers 1-to-10 first appears in the sequence.", + "Show the (1-based) index of where the number 100 first appears in the sequence.", + "Check that the greatest common divisor of all the two consecutive members of the series up to the 1000th member, is always one.", + "Show your output on this page.", + "Ref:", + "Infinite Fractions - Numberphile (Video).", + "Trees, Teeth, and Time: The mathematics of clock making. ", + "A002487 The On-Line Encyclopedia of Integer Sequences.Related Tasks:", + "Continued fraction/Arithmetic" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8028", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Straddling checkerboard", + "type": "Waypoint", + "description": [ + "

Implement functions to encrypt and decrypt a message using the straddling checkerboard method. The checkerboard should take a 28 character alphabet (A-Z plus a full stop and an escape character) and two different numbers representing the blanks in the first row. The output will be a series of decimal digits.

Numbers should be encrypted by inserting the escape character before each digit, then including the digit unencrypted. This should be reversed for decryption.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "", + "Output:
One night-it was on the twentieth of March, 1888-I was returning.",
+      "34045747525284613427502840425027537379697175891898898898584619028294547488",
+      "ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING.
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8029", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Stream Merge", + "type": "Waypoint", + "description": [ + " 2-stream merge", + "

Read two sorted streams of items from external source (e.g. disk, or network), and write one stream of sorted items to external sink.

", + "

Common algorithm: keep 1 buffered item from each source, select minimal of them, write it, fetch another item from that stream from which the written item was.

N-stream merge", + "

The same as above, but reading from N sources.

", + "

Common algorithm: same as above, but keep buffered items and their source descriptors in a heap.

", + "

Assume streams are very big. You must not suck them whole in the memory, but read them as streams.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc802a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "String interpolation (included)", + "type": "Waypoint", + "description": [ + "

Given a string and defined variables or values, string interpolation is the replacement of defined character sequences in the string by values or variable values.

", + "

For example, given an original string of \"Mary had a X lamb.\", a value of \"big\", and if the language replaces X in its interpolation routine, then the result of its interpolation would be the string \"Mary had a big lamb\".

(Languages usually include an infrequently used character or sequence of characters to indicate what is to be replaced such as \"%\", or \"#\" rather than \"X\").

The task is to: ", + "Use your languages inbuilt string interpolation abilities to interpolate a string missing the text \"little\" which is held in a variable, to produce the output string \"Mary had a little lamb\".", + "If possible, give links to further documentation on your languages string interpolation features.", + "

Note: The task is not to create a string interpolation routine, but to show a language's built-in capability.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "var original = \"Mary had a X lamb\";", + "var little = \"little\";", + "var replaced = original.replace(\"X\", little); //does not change the original string", + "", + "Or,", + "", + "// ECMAScript 6", + "var X = \"little\";", + "var replaced = `Mary had a ${X} lamb`;", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc802f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var original = \"Mary had a X lamb\";\nvar little = \"little\";\nvar replaced = original.replace(\"X\", little); //does not change the original string\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "String matching", + "type": "Waypoint", + "description": [ + "Task:", + "

Given two strings, demonstrate the following three types of string matching:

:# Determining if the first string starts with second string

", + "

:# Determining if the first string contains the second string at any location

", + "

:# Determining if the first string ends with the second string

", + "

Optional requirements:

", + "

:# Print the location of the match for part 2

", + "

:# Handle multiple occurrences of a string for part 2.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "var stringA = \"tacoloco\"", + " , stringB = \"co\"", + " , q1, q2, q2multi, m", + " , q2matches = []", + "", + "// stringA starts with stringB", + "q1 = stringA.substring(0, stringB.length) == stringB", + "", + "// stringA contains stringB", + "q2 = stringA.indexOf(stringB)", + "", + "// multiple matches", + "q2multi = new RegExp(stringB,'g')", + "", + "while(m = q2multi.exec(stringA)){", + "\tq2matches.push(m.index)", + "}", + "", + "// stringA ends with stringB", + "q3 = stringA.substr(-stringB.length) == stringB", + "", + "console.log(\"1: Does '\"+stringA+\"' start with '\"+stringB+\"'? \" + ( q1 ? \"Yes.\" : \"No.\"))", + "console.log(\"2: Is '\"+stringB+\"' contained in '\"+stringA+\"'? \" + (~q2 ? \"Yes, at index \"+q2+\".\" : \"No.\"))", + "if (~q2 && q2matches.length > 1){", + "\tconsole.log(\" In fact, it happens \"+q2matches.length+\" times within '\"+stringA+\"', at index\"+(q2matches.length > 1 ? \"es\" : \"\")+\" \"+q2matches.join(', ')+\".\")", + "}", + "console.log(\"3: Does '\"+stringA+\"' end with '\"+stringB+\"'? \" + ( q3 ? \"Yes.\" : \"No.\"))", + "", + "{{out}}", + "
1: Does 'tacoloco' start with 'co'? No.",
+      "2: Is 'co' contained in 'tacoloco'? Yes, at index 2.",
+      "   In fact, it happens 2 times within 'tacoloco', at indexes 2, 6.",
+      "3: Does 'tacoloco' end with 'co'? Yes.
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8031", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var stringA = \"tacoloco\"\n , stringB = \"co\"\n , q1, q2, q2multi, m\n , q2matches = []\n\n// stringA starts with stringB\nq1 = stringA.substring(0, stringB.length) == stringB\n\n// stringA contains stringB\nq2 = stringA.indexOf(stringB)\n\n// multiple matches\nq2multi = new RegExp(stringB,'g')\n\nwhile(m = q2multi.exec(stringA)){\n\tq2matches.push(m.index)\n}\n\n// stringA ends with stringB\nq3 = stringA.substr(-stringB.length) == stringB\n\nconsole.log(\"1: Does '\"+stringA+\"' start with '\"+stringB+\"'? \" + ( q1 ? \"Yes.\" : \"No.\"))\nconsole.log(\"2: Is '\"+stringB+\"' contained in '\"+stringA+\"'? \" + (~q2 ? \"Yes, at index \"+q2+\".\" : \"No.\"))\nif (~q2 && q2matches.length > 1){\n\tconsole.log(\" In fact, it happens \"+q2matches.length+\" times within '\"+stringA+\"', at index\"+(q2matches.length > 1 ? \"es\" : \"\")+\" \"+q2matches.join(', ')+\".\")\n}\nconsole.log(\"3: Does '\"+stringA+\"' end with '\"+stringB+\"'? \" + ( q3 ? \"Yes.\" : \"No.\"))\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Strip a set of characters from a string", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a function that strips a set of characters from a string.

", + "

The function should take two arguments:

", + "

::# a string to be stripped

", + "

::# a string containing the set of characters to be stripped

", + "

The returned string should contain the first string, stripped of any characters in the second argument:

", + "

print stripchars(\"She was a soul stripper. She took my heart!\",\"aei\")

", + "

Sh ws soul strppr. Sh took my hrt!

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "function stripchars(string, chars) {", + " return string.replace(RegExp('['+chars+']','g'), '');", + "}", + "", + "===ES6===", + "", + "Reversing the order of the arguments, to simplify any currying:", + "", + "(() => {", + " 'use strict';", + "", + " // stripChars :: String -> String -> String", + " const stripChars = (strNeedles, strHayStack) =>", + " strHayStack.replace(RegExp(`[${strNeedles}]`, 'g'), '');", + "", + " // GENERIC FUNCTION", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " const curry = f => a => b => f(a, b);", + "", + " // TEST FUNCTION", + "", + " const noAEI = curry(stripChars)('aeiAEI');", + "", + " // TEST", + " return noAEI('She was a soul stripper. She took my heart!');", + "", + " // 'Sh ws soul strppr. Sh took my hrt!'", + "})();", + "", + "{{Out}}", + "
'Sh ws  soul strppr. Sh took my hrt!'
", + "", + "Alternatively, we could also do this without a regex:", + "", + "(() => {", + " 'use strict';", + "", + " // stripChars :: String -> String -> String", + " const stripChars = (strNeedles, strHayStack) =>", + " strHayStack.split('')", + " .filter(x => !elem(x, strNeedles))", + " .join('');", + "", + " // GENERIC FUNCTIONS", + "", + " // elem :: Eq a => a -> [a] -> Bool", + " const elem = (x, xs) => xs.indexOf(x) !== -1;", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " const curry = f => a => b => f(a, b);", + "", + " // TEST FUNCTION", + "", + " const noAEI = curry(stripChars)('aeiAEI');", + "", + " ", + " // TEST", + " return noAEI('She was a soul stripper. She took my heart!');", + "", + " // 'Sh ws soul strppr. Sh took my hrt!'", + "})();", + "", + "{{Out}}", + "
'Sh ws  soul strppr. Sh took my hrt!'
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8033", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function stripchars(string, chars) {\n return string.replace(RegExp('['+chars+']','g'), '');\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Strip block comments", + "type": "Waypoint", + "description": [ + "

A block comment begins with a beginning delimiter and ends with a ending delimiter, including the delimiters. These delimiters are often multi-character sequences.

", + "Task:", + "

Strip block comments from program text (of a programming language much like classic C).

Your demos should at least handle simple, non-nested and multi-line block comment delimiters.

The block comment delimiters are the two-character sequence:

", + "

::* /* (beginning delimiter)

", + "

::* */ (ending delimiter)

", + "

Sample text for stripping:

", + "
",
+      "  /**",
+      "   * Some comments",
+      "   * longer comments here that we can parse.",
+      "   *",
+      "   * Rahoo ",
+      "   */",
+      "   function subroutine() {",
+      "    a = /* inline comment */ b + c ;",
+      "   }",
+      "   /*/ <-- tricky comments */   /**",
+      "    * Another comment.",
+      "    */",
+      "    function something() {",
+      "    }",
+      "
Extra credit:", + "

Ensure that the stripping code is not hard-coded to the particular delimiters described above, but instead allows the caller to specify them. (If your language supports them, optional parameters may be useful for this.)

", + "Related task:", + " Strip comments from a string" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8034", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Strip comments from a string", + "type": "Waypoint", + "description": [ + "

The task is to remove text that follow any of a set of comment markers, (in these examples either a hash or a semicolon) from a string or input line.

", + "

Whitespace debacle: There is some confusion about whether to remove any whitespace from the input line.

As of 2 September 2011, at least 8 languages (C, C++, Java, Perl, Python, Ruby, sed, UNIX Shell) were incorrect, out of 36 total languages, because they did not trim whitespace by 29 March 2011 rules. Some other languages might be incorrect for the same reason.

Please discuss this issue at .

From 29 March 2011, this task required that: \"The comment marker and any whitespace at the beginning or ends of the resultant line should be removed. A line without comments should be trimmed of any leading or trailing whitespace before being produced as a result.\" The task had 28 languages, which did not all meet this new requirement.", + "From 28 March 2011, this task required that: \"Whitespace before the comment marker should be removed.\"", + "From 30 October 2010, this task did not specify whether or not to remove whitespace.", + "

The following examples will be truncated to either \"apples, pears \" or \"apples, pears\".

(This example has flipped between \"apples, pears \" and \"apples, pears\" in the past.)

",
+      "apples, pears # and bananas",
+      "apples, pears ; and bananas",
+      "
", + "Related task:", + " Strip block comments" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "function stripComments(s) {", + " var re1 = /^\\s+|\\s+$/g; // Strip leading and trailing spaces", + " var re2 = /\\s*[#;].+$/g; // Strip everything after # or ; to the end of the line, including preceding spaces", + " return s.replace(re1,'').replace(re2,'');", + "}", + "", + "", + "var s1 = 'apples, pears # and bananas';", + "var s2 = 'apples, pears ; and bananas';", + "", + "alert(stripComments(s1) + '\\n' + stripComments(s2));", + "", + "", + "A more efficient version that caches the regular expressions in a closure:", + "", + "var stripComments = (function () {", + " var re1 = /^\\s+|\\s+$/g;", + " var re2 = /\\s*[#;].+$/g;", + " return function (s) {", + " return s.replace(re1,'').replace(re2,'');", + " };", + "}());", + "", + "A difference with the two versions is that in the first, all declarations are processed before code is executed so the function declaration can be after the code that calls it. However in the second example, the expression creating the function must be executed before the function is available, so it must be before the code that calls it.", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8035", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function stripComments(s) {\n var re1 = /^\\s+|\\s+$/g; // Strip leading and trailing spaces\n var re2 = /\\s*[#;].+$/g; // Strip everything after # or ; to the end of the line, including preceding spaces\n return s.replace(re1,'').replace(re2,'');\n}\n\n\nvar s1 = 'apples, pears # and bananas';\nvar s2 = 'apples, pears ; and bananas';\n\nalert(stripComments(s1) + '\\n' + stripComments(s2));\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Strip control codes and extended characters from a string", + "type": "Waypoint", + "description": [ + "

The task is to strip control codes and extended characters from a string. The solution should demonstrate how to achieve each of the following results:

a string with control codes stripped (but extended characters not stripped)", + "a string with control codes and extended characters stripped

In ASCII, the control codes have decimal codes 0 through to 31 and 127. On an ASCII based system, if the control codes are stripped, the resultant string would have all of its characters within the range of 32 to 126 decimal on the ASCII table.

On a non-ASCII based system, we consider characters that do not have a corresponding glyph on the ASCII table (within the ASCII range of 32 to 126 decimal) to be an extended character for the purpose of this task.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES 5===", + "", + "(function (strTest) {", + "", + " // s -> s", + " function strip(s) {", + " return s.split('').filter(function (x) {", + " var n = x.charCodeAt(0);", + " ", + " return 31 < n && 127 > n;", + " }).join('');", + " }", + "", + " return strip(strTest);", + "", + "})(\"\\ba\\x00b\\n\\rc\\fd\\xc3\");", + "", + "{{Out}}", + "", + "\"abcd\"", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8036", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function (strTest) {\n\n // s -> s\n function strip(s) {\n return s.split('').filter(function (x) {\n var n = x.charCodeAt(0);\n \n return 31 < n && 127 > n;\n }).join('');\n }\n\n return strip(strTest);\n\n})(\"\\ba\\x00b\\n\\rc\\fd\\xc3\");\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Subleq", + "type": "Waypoint", + "description": [ + "

Subleq is an example of a One-Instruction Set Computer (OISC).

It is named after its only instruction, which is SUbtract and Branch if Less than or EQual to zero.

", + "Task

Your task is to create an interpreter which emulates such a machine.

", + "

The machine's memory consists of an array of signed integers. Any reasonable word size is fine, but the memory must be able to hold negative as well as positive numbers.

Execution begins with the instruction pointer aimed at the first word, which is address 0. It proceeds as follows:

Let A, B, and C be the value stored in the three consecutive words in memory starting at the instruction pointer.", + "Advance the instruction pointer 3 words to point at the address after the one containing C. ", + "If A is -1, then a character is read from standard input and its code point stored in the address given by B. C is unused.", + "If B is -1, then the number contained in the address given by A is interpreted as a code point and the corresponding character output. C is again unused.", + "Otherwise, both A and B are treated as the addresses of memory locations. The number contained in the address given by A is subtracted from the number at the address given by B (and the result stored back in address B). If the result is zero or negative, the value C becomes the new instruction pointer.", + "If the instruction pointer becomes negative, execution halts.", + "Other negative addresses besides -1 may be treated as equivalent to -1, or generate an error, as you see fit.

Your solution should accept a program to execute on the machine, separately from the input fed to the program itself. This program should be in raw subleq \"machine code\" - whitespace-separated decimal numbers, with no symbolic names or other assembly-level extensions, to be loaded into memory starting at address 0. Show the output of your solution when fed this \"Hello, world!\" program. (Note that the example assumes ASCII or a superset of it, such as any of the Latin-N character sets or Unicode. You may translate it into another character set if your implementation is on a non-ASCiI-compatible environment.)

15 17 -1 17 -1 -1 16 1 -1 16 3 -1 15 15 0 0 -1 72 101 108 108 111 44 32 119 111 114 108 100 33 10 0

Which corresponds to something like this in a hypothetical assembler language:

start:",
+      "    zero, message, -1",
+      "    message, -1, -1",
+      "    neg1, start+1, -1",
+      "    neg1, start+3, -1",
+      "    zero, zero, start",
+      "zero: 0",
+      "neg1: -1",
+      "message: \"Hello, world!\\n\\0\"
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8038", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Substring", + "type": "Waypoint", + "description": [ + "

In this task display a substring:

starting from n characters in and of m length;", + "starting from n characters in, up to the end of the string;", + "whole string minus last character;", + "starting from a known character within the string and of m length;", + "starting from a known substring within the string and of m length.", + "

If the program uses UTF-8 or UTF-16, it must work on any valid Unicode code point,

", + "

whether in the Basic Multilingual Plane or above it.

The program must reference logical characters (code points), not 8-bit code units for UTF-8 or 16-bit code units for UTF-16.

Programs for other encodings (such as 8-bit ASCII, or EUC-JP) are not required to handle all Unicode characters.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "The String object has two similar methods: substr and substring.", + "*substr(start, [len]) returns a substring beginning at a specified location and having a specified length.", + "*substring(start, [end]) returns a string containing the substring from start up to, ''but not including'', end.", + "", + "var str = \"abcdefgh\";", + "", + "var n = 2;", + "var m = 3;", + "", + "// * starting from n characters in and of m length;", + "str.substr(n, m); // => \"cde\"", + "", + "// * starting from n characters in, up to the end of the string;", + "str.substr(n); // => \"cdefgh\"", + "str.substring(n); // => \"cdefgh\"", + "", + "// * whole string minus last character;", + "str.substring(0, str.length - 1); // => \"abcdefg\"", + "", + "// * starting from a known character within the string and of m length;", + "str.substr(str.indexOf('b'), m); // => \"bcd\"", + "", + "// * starting from a known substring within the string and of m length. ", + "str.substr(str.indexOf('bc'), m); // => \"bcd\"", + "", + "", + "Or, in terms of some familiar functional primitives, translating broadly from Haskell:", + "", + "(function () {", + " 'use strict';", + "", + " // take :: Int -> Text -> Text", + " function take(n, s) {", + " return s.substr(0, n);", + " }", + "", + " // drop :: Int -> Text -> Text", + " function drop(n, s) {", + " return s.substr(n);", + " }", + "", + "", + " // init :: Text -> Text", + " function init(s) {", + " var n = s.length;", + " return (n > 0 ? s.substr(0, n - 1) : undefined);", + " }", + " ", + " // breakOn :: Text -> Text -> (Text, Text)", + " function breakOn(strPattern, s) {", + " var i = s.indexOf(strPattern);", + " return i === -1 ? [strPattern, ''] : [s.substr(0, i), s.substr(i)];", + " }", + " ", + "", + " var str = '一二三四五六七八九十';", + "", + "", + " return JSON.stringify({", + " ", + " 'from n in, of m length': (function (n, m) {", + " return take(m, drop(n, str));", + " })(4, 3),", + " ", + " ", + " 'from n in, up to end' :(function (n) {", + " return drop(n, str);", + " })(3),", + " ", + " ", + " 'all but last' : init(str),", + " ", + " ", + " 'from matching char, of m length' : (function (pattern, s, n) {", + " return take(n, breakOn(pattern, s)[1]);", + " })('五', str, 3),", + " ", + " ", + " 'from matching string, of m length':(function (pattern, s, n) {", + " return take(n, breakOn(pattern, s)[1]);", + " })('六七', str, 4)", + " ", + " }, null, 2);", + "", + "})();", + "", + "{{Out}}", + "", + "{", + " \"from n in, of m length\": \"五六七\",", + " \"from n in, up to end\": \"四五六七八九十\",", + " \"all but last\": \"一二三四五六七八九\",", + " \"from matching char, of m length\": \"五六七\",", + " \"from matching string, of m length\": \"六七八九\"", + "}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8039", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var str = \"abcdefgh\";\n\nvar n = 2;\nvar m = 3;\n\n// * starting from n characters in and of m length;\nstr.substr(n, m); // => \"cde\"\n\n// * starting from n characters in, up to the end of the string;\nstr.substr(n); // => \"cdefgh\"\nstr.substring(n); // => \"cdefgh\"\n\n// * whole string minus last character;\nstr.substring(0, str.length - 1); // => \"abcdefg\"\n\n// * starting from a known character within the string and of m length;\nstr.substr(str.indexOf('b'), m); // => \"bcd\"\n\n// * starting from a known substring within the string and of m length. \nstr.substr(str.indexOf('bc'), m); // => \"bcd\"\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Substring/Top and tail", + "type": "Waypoint", + "description": [ + "

The task is to demonstrate how to remove the first and last characters from a string.

The solution should demonstrate how to obtain the following results:

String with first character removed", + "String with last character removed", + "String with both the first and last characters removed", + "

If the program uses UTF-8 or UTF-16, it must work on any valid Unicode code point, whether in the Basic Multilingual Plane or above it.

The program must reference logical characters (code points), not 8-bit code units for UTF-8 or 16-bit code units for UTF-16.

Programs for other encodings (such as 8-bit ASCII, or EUC-JP) are not required to handle all Unicode characters.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "alert(\"knight\".slice(1)); // strip first character", + "alert(\"socks\".slice(0, -1)); // strip last character", + "alert(\"brooms\".slice(1, -1)); // strip both first and last characters", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc803a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "alert(\"knight\".slice(1)); // strip first character\nalert(\"socks\".slice(0, -1)); // strip last character\nalert(\"brooms\".slice(1, -1)); // strip both first and last characters\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sudoku", + "type": "Waypoint", + "description": [ + "Task:", + "

Solve a partially filled-in normal 9x9 Sudoku grid and display the result in a human-readable format.

", + "

Algorithmics of Sudoku may help implement this.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "====ES6====", + "", + "//-------------------------------------------[ Dancing Links and Algorithm X ]--", + "/**", + " * The doubly-doubly circularly linked data object.", + " * Data object X", + " */", + "class DoX {", + " /**", + " * @param {string} V", + " * @param {!DoX=} H", + " */", + " constructor(V, H) {", + " this.V = V;", + " this.L = this;", + " this.R = this;", + " this.U = this;", + " this.D = this;", + " this.S = 1;", + " this.H = H || this;", + " H && (H.S += 1);", + " }", + "}", + "", + "/**", + " * Helper function to help build a horizontal doubly linked list.", + " * @param {!DoX} e An existing node in the list.", + " * @param {!DoX} n A new node to add to the right of the existing node.", + " * @return {!DoX}", + " */", + "const addRight = (e, n) => {", + " n.R = e.R;", + " n.L = e;", + " e.R.L = n;", + " return e.R = n;", + "};", + "", + "/**", + " * Helper function to help build a vertical doubly linked list.", + " * @param {!DoX} e An existing node in the list.", + " * @param {!DoX} n A new node to add below the existing node.", + " */", + "const addBelow = (e, n) => {", + " n.D = e.D;", + " n.U = e;", + " e.D.U = n;", + " return e.D = n;", + "};", + "", + "/**", + " * Verbatim copy of DK's search algorithm. The meat of the DLX algorithm.", + " * @param {!DoX} h The root node.", + " * @param {!Array} s The solution array.", + " */", + "const search = function(h, s) {", + " if (h.R == h) {", + " printSol(s);", + " } else {", + " let c = chooseColumn(h);", + " cover(c);", + " for (let r = c.D; r != c; r = r.D) {", + " s.push(r);", + " for (let j = r.R; r !=j; j = j.R) {", + " cover(j.H);", + " }", + " search(h, s);", + " r = s.pop();", + " for (let j = r.R; j != r; j = j.R) {", + " uncover(j.H);", + " }", + " }", + " uncover(c);", + " }", + "};", + "", + "/**", + " * Verbatim copy of DK's algorithm for choosing the next column object.", + " * @param {!DoX} h", + " * @return {!DoX}", + " */", + "const chooseColumn = h => {", + " let s = Number.POSITIVE_INFINITY;", + " let c = h;", + " for(let j = h.R; j != h; j = j.R) {", + " if (j.S < s) {", + " c = j;", + " s = j.S;", + " }", + " }", + " return c;", + "};", + "", + "", + "/**", + " * Verbatim copy of DK's cover algorithm", + " * @param {!DoX} c", + " */", + "const cover = c => {", + " c.L.R = c.R;", + " c.R.L = c.L;", + " for (let i = c.D; i != c; i = i.D) {", + " for (let j = i.R; j != i; j = j.R) {", + " j.U.D = j.D;", + " j.D.U = j.U;", + " j.H.S = j.H.S - 1;", + " }", + " }", + "};", + "", + "/**", + " * Verbatim copy of DK's cover algorithm", + " * @param {!DoX} c", + " */", + "const uncover = c => {", + " for (let i = c.U; i != c; i = i.U) {", + " for (let j = i.L; i != j; j = j.L) {", + " j.H.S = j.H.S + 1;", + " j.U.D = j;", + " j.D.U = j;", + " }", + " }", + " c.L.R = c;", + " c.R.L = c;", + "};", + "", + "//-----------------------------------------------------------[ Print Helpers ]--", + "/**", + " * Given the standard string format of a grid, print a formatted view of it.", + " * @param {!string|!Array} a", + " */", + "const printGrid = function(a) {", + "", + " const getChar = c => {", + " let r = Number(c);", + " if (isNaN(r)) { return c }", + "", + " let o = 48;", + " if (r > 9 && r < 36) { o = 55 }", + " if (r >= 36) { o = 61 }", + " return String.fromCharCode(r + o)", + " };", + "", + " a = 'string' == typeof a ? a.split('') : a;", + "", + " let U = Math.sqrt(a.length);", + " let N = Math.sqrt(U);", + " let line = new Array(N).fill('+').reduce((p, c) => {", + " p.push(... Array.from(new Array(1 + N*2).fill('-')));", + " p.push(c);", + " return p;", + " }, ['\\n+']).join('') + '\\n';", + "", + " a = a.reduce(function(p, c, i) {", + " let d = i && !(i % U), G = i && !(i % N);", + " i = !(i % (U * N));", + " d && !i && (p += '|\\n| ');", + " d && i && (p += '|');", + " i && (p = '' + p + line + '| ');", + " return '' + p + (G && !d ? '| ' : '') + getChar(c) + ' ';", + " }, '') + '|' + line;", + " console.log(a);", + "", + "};", + "", + "/**", + " * Given a search solution, print the resultant grid.", + " * @param {!Array} a An array of data objects", + " */", + "const printSol = a => {", + " printGrid(a.reduce((p, c) => {", + " let [i, v] = c.V.split(':');", + " p[i * 1] = v;", + " return p;", + " }, new Array(a.length).fill('.')));", + "};", + "", + "//----------------------------------------------[ Grid to Exact cover Matrix ]--", + "/**", + " * Helper to get some meta about the grid.", + " * @param {!string} s The standard string representation of a grid.", + " * @return {!Array}", + " */", + "const gridMeta = s => {", + " const g = s.split('');", + " const cellCount = g.length;", + " const tokenCount = Math.sqrt(cellCount);", + " const N = Math.sqrt(tokenCount);", + " const g2D = g.map(e => isNaN(e * 1) ?", + " new Array(tokenCount).fill(1).map((_, i) => i + 1) :", + " [e * 1]);", + " return [cellCount, N, tokenCount, g2D];", + "};", + "", + "/**", + " * Given a cell grid index, return the row, column and box indexes.", + " * @param {!number} n The n-value of the grid. 3 for a 9x9 sudoku.", + " * @return {!function(!number): !Array}", + " */", + "const indexesN = n => i => {", + " let c = Math.floor(i / (n * n));", + " i %= n * n;", + " return [c, i, Math.floor(c / n) * n + Math.floor(i / n)];", + "};", + "", + "/**", + " * Given a puzzle string, reduce it to an exact-cover matrix and use", + " * Donald Knuth's DLX algorithm to solve it.", + " * @param puzString", + " */", + "const reduceGrid = puzString => {", + "", + " printGrid(puzString);", + " const [", + " numCells, // The total number of cells in a grid (81 for a 9x9 grid)", + " N, // the 'n' value of the grid. (3 for a 9x9 grid)", + " U, // The total number of unique tokens to be placed.", + " g2D // A 2D array representation of the grid, with each element", + " // being an array of candidates for a cell. Known cells are", + " // single element arrays.", + " ] = gridMeta(puzString);", + "", + " const getIndex = indexesN(N);", + "", + " /**", + " * The DLX Header row.", + " * Its length is 4 times the grid's size. This is to be able to encode", + " * each of the 4 Sudoku constrains, onto each of the cells of the grid.", + " * The array is initialised with unlinked DoX nodes, but in the next step", + " * those nodes are all linked.", + " * @type {!Array.}", + " */", + " const headRow = new Array(4 * numCells)", + " .fill('')", + " .map((_, i) => new DoX(`H${i}`));", + "", + " /**", + " * The header row root object. This is circularly linked to be to the left", + " * of the first header object in the header row array.", + " * It is used as the entry point into the DLX algorithm.", + " * @type {!DoX}", + " */", + " let H = new DoX('ROOT');", + " headRow.reduce((p, c) => addRight(p, c), H);", + "", + " /**", + " * Transposed the sudoku puzzle into a exact cover matrix, so it can be passed", + " * to the DLX algorithm to solve.", + " */", + " for (let i = 0; i < numCells; i++) {", + " const [ri, ci, bi] = getIndex(i);", + " g2D[i].forEach(num => {", + " let id = `${i}:${num}`;", + " let candIdx = num - 1;", + "", + " // The 4 columns that we will populate.", + " const A = headRow[i];", + " const B = headRow[numCells + candIdx + (ri * U)];", + " const C = headRow[(numCells * 2) + candIdx + (ci * U)];", + " const D = headRow[(numCells * 3) + candIdx + (bi * U)];", + "", + " // The Row-Column Constraint", + " let rcc = addBelow(A.U, new DoX(id, A));", + "", + " // The Row-Number Constraint", + " let rnc = addBelow(B.U, addRight(rcc, new DoX(id, B)));", + "", + " // The Column-Number Constraint", + " let cnc = addBelow(C.U, addRight(rnc, new DoX(id, C)));", + "", + " // The Block-Number Constraint", + " addBelow(D.U, addRight(cnc, new DoX(id, D)));", + " });", + " }", + " search(H, []);", + "};", + "", + "", + "[", + " '819..5.....2...75..371.4.6.4..59.1..7..3.8..2..3.62..7.5.7.921..64...9.....2..438',", + " '53..247....2...8..1..7.39.2..8.72.49.2.98..7.79.....8.....3.5.696..1.3...5.69..1.',", + " '..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3..',", + " '394..267....3..4..5..69..2..45...9..6.......7..7...58..1..67..8..9..8....264..735',", + " '97.3...6..6.75.........8.5.......67.....3.....539..2..7...25.....2.1...8.4...73..',", + " '4......6.5...8.9..3....1....2.7....1.9.....4.8....3.5....2....7..6.5...8.1......6',", + " '85...24..72......9..4.........1.7..23.5...9...4...........8..7..17..........36.4.',", + " '..1..5.7.92.6.......8...6...9..2.4.1.........3.4.8..9...7...3.......7.69.1.8..7..',", + " '.9...4..7.....79..8........4.58.....3.......2.....97.6........4..35.....2..6...8.',", + " '12.3....435....1....4........54..2..6...7.........8.9...31..5.......9.7.....6...8',", + " '9..2..5...4..6..3...3.....6...9..2......5..8...7..4..37.....1...5..2..4...1..6..9',", + " '1....7.9..3..2...8..96..5....53..9...1..8...26....4...3......1..4......7..7...3..',", + " '12.4..3..3...1..5...6...1..7...9.....4.6.3.....3..2...5...8.7....7.....5.......98',", + " '..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9',", + " '.......39.....1..5..3.5.8....8.9...6.7...2...1..4.......9.8..5..2....6..4..7.....',", + " '....839..1......3...4....7..42.3....6.......4....7..1..2........8...92.....25...6',", + " '..3......4...8..36..8...1...4..6..73...9..........2..5..4.7..686........7..6..5..'", + "].forEach(reduceGrid);", + "", + "// Or of you want to create all the grids of a particular n-size.", + "// I run out of stack space at n = 9", + "let n = 2;", + "let s = new Array(Math.pow(n, 4)).fill('.').join('');", + "reduceGrid(s);", + "", + "", + "
+-------+-------+-------+",
+      "| . . 3 | . . . | . . . |",
+      "| 4 . . | . 8 . | . 3 6 |",
+      "| . . 8 | . . . | 1 . . |",
+      "+-------+-------+-------+",
+      "| . 4 . | . 6 . | . 7 3 |",
+      "| . . . | 9 . . | . . . |",
+      "| . . . | . . 2 | . . 5 |",
+      "+-------+-------+-------+",
+      "| . . 4 | . 7 . | . 6 8 |",
+      "| 6 . . | . . . | . . . |",
+      "| 7 . . | 6 . . | 5 . . |",
+      "+-------+-------+-------+",
+      "",
+      "+-------+-------+-------+",
+      "| 1 2 3 | 4 5 6 | 7 8 9 |",
+      "| 4 5 7 | 1 8 9 | 2 3 6 |",
+      "| 9 6 8 | 3 2 7 | 1 5 4 |",
+      "+-------+-------+-------+",
+      "| 2 4 9 | 5 6 1 | 8 7 3 |",
+      "| 5 7 6 | 9 3 8 | 4 1 2 |",
+      "| 8 3 1 | 7 4 2 | 6 9 5 |",
+      "+-------+-------+-------+",
+      "| 3 1 4 | 2 7 5 | 9 6 8 |",
+      "| 6 9 5 | 8 1 4 | 3 2 7 |",
+      "| 7 8 2 | 6 9 3 | 5 4 1 |",
+      "+-------+-------+-------+",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc803c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "//-------------------------------------------[ Dancing Links and Algorithm X ]--\n/**\n * The doubly-doubly circularly linked data object.\n * Data object X\n */\nclass DoX {\n /**\n * @param {string} V\n * @param {!DoX=} H\n */\n constructor(V, H) {\n this.V = V;\n this.L = this;\n this.R = this;\n this.U = this;\n this.D = this;\n this.S = 1;\n this.H = H || this;\n H && (H.S += 1);\n }\n}\n\n/**\n * Helper function to help build a horizontal doubly linked list.\n * @param {!DoX} e An existing node in the list.\n * @param {!DoX} n A new node to add to the right of the existing node.\n * @return {!DoX}\n */\nconst addRight = (e, n) => {\n n.R = e.R;\n n.L = e;\n e.R.L = n;\n return e.R = n;\n};\n\n/**\n * Helper function to help build a vertical doubly linked list.\n * @param {!DoX} e An existing node in the list.\n * @param {!DoX} n A new node to add below the existing node.\n */\nconst addBelow = (e, n) => {\n n.D = e.D;\n n.U = e;\n e.D.U = n;\n return e.D = n;\n};\n\n/**\n * Verbatim copy of DK's search algorithm. The meat of the DLX algorithm.\n * @param {!DoX} h The root node.\n * @param {!Array} s The solution array.\n */\nconst search = function(h, s) {\n if (h.R == h) {\n printSol(s);\n } else {\n let c = chooseColumn(h);\n cover(c);\n for (let r = c.D; r != c; r = r.D) {\n s.push(r);\n for (let j = r.R; r !=j; j = j.R) {\n cover(j.H);\n }\n search(h, s);\n r = s.pop();\n for (let j = r.R; j != r; j = j.R) {\n uncover(j.H);\n }\n }\n uncover(c);\n }\n};\n\n/**\n * Verbatim copy of DK's algorithm for choosing the next column object.\n * @param {!DoX} h\n * @return {!DoX}\n */\nconst chooseColumn = h => {\n let s = Number.POSITIVE_INFINITY;\n let c = h;\n for(let j = h.R; j != h; j = j.R) {\n if (j.S < s) {\n c = j;\n s = j.S;\n }\n }\n return c;\n};\n\n\n/**\n * Verbatim copy of DK's cover algorithm\n * @param {!DoX} c\n */\nconst cover = c => {\n c.L.R = c.R;\n c.R.L = c.L;\n for (let i = c.D; i != c; i = i.D) {\n for (let j = i.R; j != i; j = j.R) {\n j.U.D = j.D;\n j.D.U = j.U;\n j.H.S = j.H.S - 1;\n }\n }\n};\n\n/**\n * Verbatim copy of DK's cover algorithm\n * @param {!DoX} c\n */\nconst uncover = c => {\n for (let i = c.U; i != c; i = i.U) {\n for (let j = i.L; i != j; j = j.L) {\n j.H.S = j.H.S + 1;\n j.U.D = j;\n j.D.U = j;\n }\n }\n c.L.R = c;\n c.R.L = c;\n};\n\n//-----------------------------------------------------------[ Print Helpers ]--\n/**\n * Given the standard string format of a grid, print a formatted view of it.\n * @param {!string|!Array} a\n */\nconst printGrid = function(a) {\n\n const getChar = c => {\n let r = Number(c);\n if (isNaN(r)) { return c }\n\n let o = 48;\n if (r > 9 && r < 36) { o = 55 }\n if (r >= 36) { o = 61 }\n return String.fromCharCode(r + o)\n };\n\n a = 'string' == typeof a ? a.split('') : a;\n\n let U = Math.sqrt(a.length);\n let N = Math.sqrt(U);\n let line = new Array(N).fill('+').reduce((p, c) => {\n p.push(... Array.from(new Array(1 + N*2).fill('-')));\n p.push(c);\n return p;\n }, ['\\n+']).join('') + '\\n';\n\n a = a.reduce(function(p, c, i) {\n let d = i && !(i % U), G = i && !(i % N);\n i = !(i % (U * N));\n d && !i && (p += '|\\n| ');\n d && i && (p += '|');\n i && (p = '' + p + line + '| ');\n return '' + p + (G && !d ? '| ' : '') + getChar(c) + ' ';\n }, '') + '|' + line;\n console.log(a);\n\n};\n\n/**\n * Given a search solution, print the resultant grid.\n * @param {!Array} a An array of data objects\n */\nconst printSol = a => {\n printGrid(a.reduce((p, c) => {\n let [i, v] = c.V.split(':');\n p[i * 1] = v;\n return p;\n }, new Array(a.length).fill('.')));\n};\n\n//----------------------------------------------[ Grid to Exact cover Matrix ]--\n/**\n * Helper to get some meta about the grid.\n * @param {!string} s The standard string representation of a grid.\n * @return {!Array}\n */\nconst gridMeta = s => {\n const g = s.split('');\n const cellCount = g.length;\n const tokenCount = Math.sqrt(cellCount);\n const N = Math.sqrt(tokenCount);\n const g2D = g.map(e => isNaN(e * 1) ?\n new Array(tokenCount).fill(1).map((_, i) => i + 1) :\n [e * 1]);\n return [cellCount, N, tokenCount, g2D];\n};\n\n/**\n * Given a cell grid index, return the row, column and box indexes.\n * @param {!number} n The n-value of the grid. 3 for a 9x9 sudoku.\n * @return {!function(!number): !Array}\n */\nconst indexesN = n => i => {\n let c = Math.floor(i / (n * n));\n i %= n * n;\n return [c, i, Math.floor(c / n) * n + Math.floor(i / n)];\n};\n\n/**\n * Given a puzzle string, reduce it to an exact-cover matrix and use\n * Donald Knuth's DLX algorithm to solve it.\n * @param puzString\n */\nconst reduceGrid = puzString => {\n\n printGrid(puzString);\n const [\n numCells, // The total number of cells in a grid (81 for a 9x9 grid)\n N, // the 'n' value of the grid. (3 for a 9x9 grid)\n U, // The total number of unique tokens to be placed.\n g2D // A 2D array representation of the grid, with each element\n // being an array of candidates for a cell. Known cells are\n // single element arrays.\n ] = gridMeta(puzString);\n\n const getIndex = indexesN(N);\n\n /**\n * The DLX Header row.\n * Its length is 4 times the grid's size. This is to be able to encode\n * each of the 4 Sudoku constrains, onto each of the cells of the grid.\n * The array is initialised with unlinked DoX nodes, but in the next step\n * those nodes are all linked.\n * @type {!Array.}\n */\n const headRow = new Array(4 * numCells)\n .fill('')\n .map((_, i) => new DoX(`H${i}`));\n\n /**\n * The header row root object. This is circularly linked to be to the left\n * of the first header object in the header row array.\n * It is used as the entry point into the DLX algorithm.\n * @type {!DoX}\n */\n let H = new DoX('ROOT');\n headRow.reduce((p, c) => addRight(p, c), H);\n\n /**\n * Transposed the sudoku puzzle into a exact cover matrix, so it can be passed\n * to the DLX algorithm to solve.\n */\n for (let i = 0; i < numCells; i++) {\n const [ri, ci, bi] = getIndex(i);\n g2D[i].forEach(num => {\n let id = `${i}:${num}`;\n let candIdx = num - 1;\n\n // The 4 columns that we will populate.\n const A = headRow[i];\n const B = headRow[numCells + candIdx + (ri * U)];\n const C = headRow[(numCells * 2) + candIdx + (ci * U)];\n const D = headRow[(numCells * 3) + candIdx + (bi * U)];\n\n // The Row-Column Constraint\n let rcc = addBelow(A.U, new DoX(id, A));\n\n // The Row-Number Constraint\n let rnc = addBelow(B.U, addRight(rcc, new DoX(id, B)));\n\n // The Column-Number Constraint\n let cnc = addBelow(C.U, addRight(rnc, new DoX(id, C)));\n\n // The Block-Number Constraint\n addBelow(D.U, addRight(cnc, new DoX(id, D)));\n });\n }\n search(H, []);\n};\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sum and product of an array", + "type": "Waypoint", + "description": [ + "

Compute the sum and product of an array of integers.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "var array = [1, 2, 3, 4, 5],", + " sum = 0,", + " prod = 1,", + " i;", + "for (i = 0; i < array.length; i += 1) {", + " sum += array[i];", + " prod *= array[i];", + "}", + "alert(sum + ' ' + prod);", + "", + "", + "{{Works with|Javascript|1.8}}", + "Where supported, the reduce method can also be used:", + "var array = [1, 2, 3, 4, 5],", + " sum = array.reduce(function (a, b) {", + " return a + b;", + " }, 0),", + " prod = array.reduce(function (a, b) {", + " return a * b;", + " }, 1);", + "alert(sum + ' ' + prod);", + "", + "===ES6===", + "(() => {", + " 'use strict';", + "", + " // sum :: (Num a) => [a] -> a", + " const sum = xs => xs.reduce((a, x) => a + x, 0);", + "", + " // product :: (Num a) => [a] -> a", + " const product = xs => xs.reduce((a, x) => a * x, 1);", + "", + "", + " // TEST", + " // show :: a -> String", + " const show = x => JSON.stringify(x, null, 2);", + "", + " return show(", + " [sum, product]", + " .map(f => f([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))", + " );", + "})();", + "", + "{{Out}}", + "
[",
+      "  55,",
+      "  3628800",
+      "]
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc803d", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var array = [1, 2, 3, 4, 5],\n sum = 0,\n prod = 1,\n i;\nfor (i = 0; i < array.length; i += 1) {\n sum += array[i];\n prod *= array[i];\n}\nalert(sum + ' ' + prod);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sum and Product Puzzle", + "type": "Waypoint", + "description": [ + "

Solve the \"Impossible Puzzle\":

{{quote|

", + "

X and Y are two different whole numbers greater than 1. Their sum is no greater than 100, and Y is greater than X. S and P are two mathematicians (and consequently perfect logicians); S knows the sum X+Y and P knows the product X*Y. Both S and P know all the information in this paragraph.

The following conversation occurs:

S says \"P does not know X and Y.\"", + "P says \"Now I know X and Y.\"", + "S says \"Now I also know X and Y!\"", + "

What are X and Y?

", + "

}}

", + "

It can be hard to wrap one's head around what the three lines of dialog between S (the \"sum guy\") and P (the \"product guy\") convey about the values of X and Y.

", + "

So for your convenience, here's a break-down:

{|

", + "

|-

", + "

!

", + "

! Quote

", + "

! Implied fact

", + "

|-

", + "

! 1)

", + "

| S says \"P does not know X and Y.\"

", + "

| For every possible sum decomposition of the number X+Y, the product has in turn more than one product decomposition.

", + "

|-

", + "

! 2)

", + "

| P says \"Now I know X and Y.\"

", + "

| The number X*Y has only one product decomposition for which fact 1 is true.

", + "

|-

", + "

! 3)

", + "

| S says \"Now I also know X and Y.\"

", + "

| The number X+Y has only one sum decomposition for which fact 2 is true.

", + "

|}

Terminology:

", + "\"sum decomposition\" of a number = Any pair of positive integers (A, B) so that A+B equals the number. Here, with the additional constraint 2 ≤ A < B.", + "\"product decomposition\" of a number = Any pair of positive integers (A, B) so that A*B equals the number. Here, with the additional constraint 2 ≤ A < B.

Your program can solve the puzzle by considering all possible pairs (X, Y) in the range 2 ≤ X < Y ≤ 98, and then successively eliminating candidates based on the three facts. It turns out only one solution remains!

", + "

See the Python example for an implementation that uses this approach with a few optimizations.

", + " Wikipedia: Sum and Product Puzzle
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "{{Trans|Haskell}}", + "(function () {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " var concatMap = function concatMap(f, xs) {", + " return [].concat.apply([], xs.map(f));", + " },", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " curry = function curry(f) {", + " return function (a) {", + " return function (b) {", + " return f(a, b);", + " };", + " };", + " },", + "", + " // intersectBy :: (a - > a - > Bool) - > [a] - > [a] - > [a]", + " intersectBy = function intersectBy(eq, xs, ys) {", + " return xs.length && ys.length ? xs.filter(function (x) {", + " return ys.some(curry(eq)(x));", + " }) : [];", + " },", + "", + " // range :: Int -> Int -> Maybe Int -> [Int]", + " range = function range(m, n, step) {", + " var d = (step || 1) * (n >= m ? 1 : -1);", + " return Array.from({", + " length: Math.floor((n - m) / d) + 1", + " }, function (_, i) {", + " return m + i * d;", + " });", + " };", + "", + " // PROBLEM FUNCTIONS", + "", + " // add, mul :: (Int, Int) -> Int", + " var add = function add(xy) {", + " return xy[0] + xy[1];", + " },", + " mul = function mul(xy) {", + " return xy[0] * xy[1];", + " };", + "", + " // sumEq, mulEq :: (Int, Int) -> [(Int, Int)]", + " var sumEq = function sumEq(p) {", + " var addP = add(p);", + " return s1.filter(function (q) {", + " return add(q) === addP;", + " });", + " },", + " mulEq = function mulEq(p) {", + " var mulP = mul(p);", + " return s1.filter(function (q) {", + " return mul(q) === mulP;", + " });", + " };", + "", + " // pairEQ :: ((a, a) -> (a, a)) -> Bool", + " var pairEQ = function pairEQ(a, b) {", + " return a[0] === b[0] && a[1] === b[1];", + " };", + "", + " // MAIN", + "", + " // xs :: [Int]", + " var xs = range(1, 100);", + "", + " // s1 s2, s3, s4 :: [(Int, Int)]", + " var s1 = concatMap(function (x) {", + " return concatMap(function (y) {", + " return 1 < x && x < y && x + y < 100 ? [", + " [x, y]", + " ] : [];", + " }, xs);", + " }, xs),", + "", + " s2 = s1.filter(function (p) {", + " return sumEq(p).every(function (q) {", + " return mulEq(q).length > 1;", + " });", + " }),", + "", + " s3 = s2.filter(function (p) {", + " return intersectBy(pairEQ, mulEq(p), s2).length === 1;", + " }),", + "", + " s4 = s3.filter(function (p) {", + " return intersectBy(pairEQ, sumEq(p), s3).length === 1;", + " });", + "", + " return s4;", + "})();", + "", + "", + "{{Out}}", + "[[4, 13]]", + "(Finished in 0.69s)", + "", + "", + "===ES6===", + "", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " let concatMap = (f, xs) => [].concat.apply([], xs.map(f)),", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " curry = f => a => b => f(a, b),", + "", + " // intersectBy :: (a - > a - > Bool) - > [a] - > [a] - > [a]", + " intersectBy = (eq, xs, ys) => (xs.length && ys.length) ?", + " xs.filter(x => ys.some(curry(eq)(x))) : [],", + "", + " // range :: Int -> Int -> Maybe Int -> [Int]", + " range = (m, n, step) => {", + " let d = (step || 1) * (n >= m ? 1 : -1);", + " return Array.from({", + " length: Math.floor((n - m) / d) + 1", + " }, (_, i) => m + (i * d));", + " };", + "", + " // PROBLEM FUNCTIONS", + "", + " // add, mul :: (Int, Int) -> Int", + " let add = xy => xy[0] + xy[1],", + " mul = xy => xy[0] * xy[1];", + "", + " // sumEq, mulEq :: (Int, Int) -> [(Int, Int)]", + " let sumEq = p => {", + " let addP = add(p);", + " return s1.filter(q => add(q) === addP);", + " },", + " mulEq = p => {", + " let mulP = mul(p)", + " return s1.filter(q => mul(q) === mulP);", + " };", + "", + " // pairEQ :: ((a, a) -> (a, a)) -> Bool", + " let pairEQ = (a, b) => (a[0] === b[0]) && (a[1] === b[1]);", + "", + "", + " // MAIN", + "", + " // xs :: [Int]", + " let xs = range(1, 100);", + "", + " // s1 s2, s3, s4 :: [(Int, Int)]", + " let s1 = concatMap(x =>", + " concatMap(y =>", + " ((1 < x) && (x < y) && (x + y) < 100) ? [", + " [x, y]", + " ] : [],", + " xs), xs),", + " s2 = s1.filter(", + " p => sumEq(p)", + " .every(", + " q => mulEq(q)", + " .length > 1", + " )", + " ),", + " s3 = s2.filter(", + " p => intersectBy(", + " pairEQ, mulEq(p), s2", + " )", + " .length === 1", + " );", + "", + " return s3.filter(", + " p => intersectBy(", + " pairEQ, sumEq(p), s3", + " )", + " .length === 1", + " );", + "", + "})();", + "", + "{{Out}}", + "[[4, 13]]", + "(Finished in 0.77s)", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc803e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function () {\n 'use strict';\n\n // GENERIC FUNCTIONS\n\n // concatMap :: (a -> [b]) -> [a] -> [b]\n var concatMap = function concatMap(f, xs) {\n return [].concat.apply([], xs.map(f));\n },\n\n // curry :: ((a, b) -> c) -> a -> b -> c\n curry = function curry(f) {\n return function (a) {\n return function (b) {\n return f(a, b);\n };\n };\n },\n\n // intersectBy :: (a - > a - > Bool) - > [a] - > [a] - > [a]\n intersectBy = function intersectBy(eq, xs, ys) {\n return xs.length && ys.length ? xs.filter(function (x) {\n return ys.some(curry(eq)(x));\n }) : [];\n },\n\n // range :: Int -> Int -> Maybe Int -> [Int]\n range = function range(m, n, step) {\n var d = (step || 1) * (n >= m ? 1 : -1);\n return Array.from({\n length: Math.floor((n - m) / d) + 1\n }, function (_, i) {\n return m + i * d;\n });\n };\n\n // PROBLEM FUNCTIONS\n\n // add, mul :: (Int, Int) -> Int\n var add = function add(xy) {\n return xy[0] + xy[1];\n },\n mul = function mul(xy) {\n return xy[0] * xy[1];\n };\n\n // sumEq, mulEq :: (Int, Int) -> [(Int, Int)]\n var sumEq = function sumEq(p) {\n var addP = add(p);\n return s1.filter(function (q) {\n return add(q) === addP;\n });\n },\n mulEq = function mulEq(p) {\n var mulP = mul(p);\n return s1.filter(function (q) {\n return mul(q) === mulP;\n });\n };\n\n // pairEQ :: ((a, a) -> (a, a)) -> Bool\n var pairEQ = function pairEQ(a, b) {\n return a[0] === b[0] && a[1] === b[1];\n };\n\n // MAIN\n\n // xs :: [Int]\n var xs = range(1, 100);\n\n // s1 s2, s3, s4 :: [(Int, Int)]\n var s1 = concatMap(function (x) {\n return concatMap(function (y) {\n return 1 < x && x < y && x + y < 100 ? [\n [x, y]\n ] : [];\n }, xs);\n }, xs),\n\n s2 = s1.filter(function (p) {\n return sumEq(p).every(function (q) {\n return mulEq(q).length > 1;\n });\n }),\n\n s3 = s2.filter(function (p) {\n return intersectBy(pairEQ, mulEq(p), s2).length === 1;\n }),\n\n s4 = s3.filter(function (p) {\n return intersectBy(pairEQ, sumEq(p), s3).length === 1;\n });\n\n return s4;\n})();\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sum digits of an integer", + "type": "Waypoint", + "description": [ + "Task:", + "

Take a Natural Number in a given base and return the sum of its digits:

", + "

* 110 sums to 1

", + "

* 123410 sums to 10

", + "

* fe16 sums to 29

", + "

* f0e16 sums to 29

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===Imperative===", + "", + "function sumDigits(n) {", + "\tn += ''", + "\tfor (var s=0, i=0, e=n.length; i')", + "", + "{{out}}", + "
",
+      "1 sum to 1",
+      "12345 sum to 15",
+      "254 sum to 11",
+      "fe sum to 29",
+      "f0e sum to 29",
+      "999ABCXYZ sum to 162",
+      "
", + "", + "===Functional (ES 5)===", + "", + "(function () {", + " 'use strict';", + "", + " // digitsSummed :: (Int | String) -> Int", + " function digitsSummed(number) {", + " ", + " // 10 digits + 26 alphabetics", + " // give us glyphs for up to base 36", + " var intMaxBase = 36;", + " ", + " return number", + " .toString()", + " .split('')", + " .reduce(function (a, digit) { ", + " return a + parseInt(digit, intMaxBase);", + " }, 0);", + " }", + "", + " // TEST", + "", + " return [1, 12345, 0xfe, 'fe', 'f0e', '999ABCXYZ']", + " .map(function (x) {", + " return x + ' -> ' + digitsSummed(x);", + " })", + " .join('\\n');", + "", + "})();", + "", + "", + "", + "
1 -> 1",
+      "12345 -> 15",
+      "254 -> 11",
+      "fe -> 29",
+      "f0e -> 29",
+      "999ABCXYZ -> 162
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc803f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function sumDigits(n) {\n\tn += ''\n\tfor (var s=0, i=0, e=n.length; i')\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sum multiples of 3 and 5", + "type": "Waypoint", + "description": [ + "Task:", + "

The objective is to write a function that finds the sum of all positive multiples of 3 or 5 below n.

Show output for n = 1000.

", + "

Extra credit: do this efficiently for n = 1e20 or higher.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "", + "JavaScript is better equipped for flexibility than for scale. The value of Number.MAX_SAFE_INTEGER is 9007199254740991, or 2^53 - 1 – resulting from an IEEE 754 double-precision floating point representation of numeric values).", + "", + "As ''Number.MAX_SAFE_INTEGER < 1E20'' evaluates to ''true'', the most obvious JS attack on a solution for 1E20 might involve some string processing … ", + "", + "At more modest scales, however, we can generalise a little to allow for an arbitrary list of integer factors, and write a simple generate, filter and sum approach:", + "", + "(function (lstFactors, intExponent) {", + "", + " // [n] -> n -> n", + " function sumMultiplesBelow(lstIntegers, limit) {", + " return range(1, limit - 1).filter(function (x) {", + " return isMultiple(lstIntegers, x);", + " }).reduce(function (a, n) {", + " return a + n;", + " }, 0)", + " }", + "", + " // [n] -> n -> bool", + " function isMultiple(lst, n) {", + " var i = lng;", + " while (i--)", + " if (n % (lst[i]) === 0) return true;", + " return false;", + " }", + "", + " // [m..n]", + " function range(m, n) {", + " var a = Array(n - m + 1),", + " i = n + 1;", + " while (i--) a[i - 1] = i;", + " return a;", + " }", + "", + "", + " /* TESTING */", + "", + " // [[a]] -> bool -> s -> s", + " function wikiTable(lstRows, blnHeaderRow, strStyle) {", + " return '{| class=\"wikitable\" ' + (", + " strStyle ? 'style=\"' + strStyle + '\"' : ''", + " ) + lstRows.map(function (lstRow, iRow) {", + " var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');", + "", + " return '\\n|-\\n' + strDelim + ' ' + lstRow.map(function (v) {", + " return typeof v === 'undefined' ? ' ' : v;", + " }).join(' ' + strDelim + strDelim + ' ');", + " }).join('') + '\\n|}';", + " }", + "", + " var lng = lstFactors.length,", + " lstSorted = lstFactors.slice(0).sort();", + "", + " var lstTable = [['Below', 'Sum']].concat(", + " range(1, intExponent).map(function (x) {", + " var pwr = Math.pow(10, x);", + "", + " return ['10^' + x, sumMultiplesBelow(lstSorted, pwr)];", + " })", + " );", + "", + " return 'For ' + JSON.stringify(lstFactors) + ':\\n\\n' +", + " wikiTable(lstTable, true) + '\\n\\n' +", + " JSON.stringify(lstTable);", + "", + "})([3, 5], 8);", + "", + "", + "For [3,5]:", + "", + "{| class=\"wikitable\" ", + "|-", + "! Below !! Sum", + "|-", + "| 10^1 || 23", + "|-", + "| 10^2 || 2318", + "|-", + "| 10^3 || 233168", + "|-", + "| 10^4 || 23331668", + "|-", + "| 10^5 || 2333316668", + "|-", + "| 10^6 || 233333166668", + "|-", + "| 10^7 || 23333331666668", + "|-", + "| 10^8 || 2333333316666668", + "|}", + "", + " [[\"Below\",\"Sum\"],[\"10^1\",23],[\"10^2\",2318],[\"10^3\",233168],", + " [\"10^4\",23331668],[\"10^5\",2333316668],[\"10^6\",233333166668],", + " [\"10^7\",23333331666668],[\"10^8\",2333333316666668]]", + "====With wheel increments====", + "function sm35(n){", + "\tvar s=0, inc=[3,2,1,3,1,2,3]", + "\tfor (var j=6, i=0; i", + "====With triangular numbers====", + "function sm35(n){", + "\treturn tri(n,3) + tri(n,5) - tri(n,15)", + "\tfunction tri(n, f) {", + "\t\tn = Math.floor((n-1) / f)", + "\t\treturn f * n * (n+1) / 2", + "\t}", + "}", + "'''This:'''", + "for (var i=1, n=10; i<9; n*=10, i+=1) {", + "\tdocument.write(10, '', i, ' ', sm35(n), '
')", + "}
", + "{{out}}", + " 101 23", + " 102 2318", + " 103 233168", + " 104 23331668", + " 105 2333316668", + " 106 233333166668", + " 107 23333331666668", + " 108 2333333316666668", + "", + "", + "===ES6===", + "", + "(() => {", + "", + " // Area under straight line", + " // between first multiple and last.", + "", + " // sumMults :: Int -> Int -> Int", + " const sumMults = (n, factor) => {", + " const n1 = quot(n - 1, factor);", + " return quot(factor * n1 * (n1 + 1), 2);", + " };", + "", + " // sum35 :: Int -> Int", + " const sum35 = n => sumMults(n, 3) + sumMults(n, 5) - sumMults(n, 15);", + "", + "", + " // GENERIC ----------------------------------------------------------------", + "", + " // enumFromTo :: Int -> Int -> [Int]", + " const enumFromTo = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // Integral a => a -> a -> a", + " const quot = (n, m) => Math.floor(n / m);", + "", + " // TEST -------------------------------------------------------------------", + "", + " // Sums for 10^1 thru 10^8", + " return enumFromTo(1, 8)", + " .map(n => Math.pow(10, n))", + " .reduce((a, x) => (", + " a[x.toString()] = sum35(x),", + " a", + " ), {});", + "})();", + "{{Out}}", + "{\"10\":23, \"100\":2318, \"1000\":233168, \"10000\":23331668,", + "\"100000\":2333316668, \"1000000\":233333166668, \"10000000\":23333331666668,", + "\"100000000\":2333333316666668}", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8040", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [" Number.MAX_SAFE_INTEGER\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sum of a series", + "type": "Waypoint", + "description": [ + "

Compute the nth term of a series, i.e. the sum of the n first terms of the corresponding sequence.

Informally this value, or its limit when n tends to infinity, is also called the sum of the series, thus the title of this task.

For this task, use:

", + "

::::: $S_n = \\sum_{k=1}^n \\frac{1}{k^2}$

", + "

: and compute $S_{1000}$

", + "

This approximates the zeta function for S=2, whose exact value

::::: $\\zeta(2) = {\\pi^2\\over 6}$

is the solution of the Basel problem.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "function sum(a,b,fn) {", + " var s = 0;", + " for ( ; a <= b; a++) s += fn(a);", + " return s;", + "}", + " ", + " sum(1,1000, function(x) { return 1/(x*x) } ) // 1.64393456668156", + "", + "or, in a functional idiom:", + "", + "(function () {", + "", + " function sum(fn, lstRange) {", + " return lstRange.reduce(", + " function (lngSum, x) {", + " return lngSum + fn(x);", + " }, 0", + " );", + " }", + "", + " function range(m, n) {", + " return Array.apply(null, Array(n - m + 1)).map(function (x, i) {", + " return m + i;", + " });", + " }", + "", + "", + " return sum(", + " function (x) {", + " return 1 / (x * x);", + " },", + " range(1, 1000)", + " );", + "", + "})();", + "", + "{{Out}}", + "", + "1.6439345666815615", + "", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // seriesSum :: Num a => (a -> a) -> [a] -> a", + " const seriesSum = (f, xs) =>", + " xs.reduce((a, x) => a + f(x), 0);", + "", + "", + " // GENERIC ------------------------------------------", + "", + " // range :: Int -> Int -> [Int]", + " const range = (m, n) =>", + " Array.from({", + " length: Math.floor(n - m) + 1", + " }, (_, i) => m + i);", + "", + " // TEST ----------------------------------------------", + "", + " return seriesSum(x => 1 / (x * x), range(1, 1000));", + "})();", + "", + "{{Out}}", + "1.6439345666815615", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8041", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function sum(a,b,fn) {\n var s = 0;\n for ( ; a <= b; a++) s += fn(a);\n return s;\n}\n \n sum(1,1000, function(x) { return 1/(x*x) } ) // 1.64393456668156\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sum of squares", + "type": "Waypoint", + "description": [ + "Task:", + "

Write a program to find the sum of squares of a numeric vector.

The program should work on a zero-length vector (with an answer of 0).

", + "Related task:", + " Mean" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "function sumsq(array) {", + " var sum = 0;", + " var i, iLen;", + "", + " for (i = 0, iLen = array.length; i < iLen; i++) {", + " sum += array[i] * array[i];", + " }", + " return sum;", + "}", + "", + "alert(sumsq([1,2,3,4,5])); // 55", + "", + "An alternative using a while loop and Math.pow", + "", + "function sumsq(array) {", + " var sum = 0, ", + " i = array.length;", + "", + " while (i--) sum += Math.pow(array[i], 2);", + "", + " return sum;", + "}", + "", + "alert(sumsq([1,2,3,4,5])); // 55", + "", + "", + "{{libheader|Functional}}Functional.reduce(\"x+y*y\", 0, [1,2,3,4,5])", + "", + "map (JS 1.6) and reduce (JS 1.8)", + "", + "[3,1,4,1,5,9].map(function (n) { return Math.pow(n,2); }).reduce(function (sum,n) { return sum+n; });", + "", + "===ES6===", + "", + "Two ways of composing a sumOfSquares function", + "(() => {", + " 'use strict';", + "", + " // squared :: Num a => a -> a", + " const squared = x => Math.pow(x, 2);", + "", + " // sum :: (Num a) => [a] -> a", + " const sum = xs => xs.reduce((a, x) => a + x, 0);", + "", + " // sumOfSquares :: Num a => [a] -> a", + " const sumOfSquares = xs => sum(xs.map(squared));", + "", + " // sumOfSquares2 :: Num a => [a] -> a", + " const sumOfSquares2 = xs =>", + " xs.reduce((a, x) => a + squared(x), 0);", + "", + " return [sumOfSquares, sumOfSquares2]", + " .map(f => f([3, 1, 4, 1, 5, 9]))", + " .join('\\n');", + "})();", + "", + "{{Out}}", + "
133",
+      "133
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8042", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function sumsq(array) {\n var sum = 0;\n var i, iLen;\n\n for (i = 0, iLen = array.length; i < iLen; i++) {\n sum += array[i] * array[i];\n }\n return sum;\n}\n\nalert(sumsq([1,2,3,4,5])); // 55\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sum to 100", + "type": "Waypoint", + "description": [ + "Task:", + "

Find solutions to the sum to one hundred puzzle.

", + "

Add (insert) the mathematical

", + "

operators + or (plus

", + "

or minus) before any of the digits in the

", + "decimal numeric string 123456789 such that the", + "

resulting mathematical expression adds up to a

", + "particular sum (in this iconic case, 100).", + "

Example:

", + "

123 + 4 - 5 + 67 - 89 = 100

Show all output here.

", + "

* Show all solutions that sum to 100

", + "

* Show the sum that has the maximum number of solutions (from zero to infinity*)

", + "

* Show the lowest positive sum that can't be expressed (has no solutions), using the rules for this task

", + "

* Show the ten highest numbers that can be expressed using the rules for this task (extra credit)

", + "

An example of a sum that can't be expressed (within the rules of this task) is: 5074

", + "which, of course, is not the lowest positive sum that can't be expressed.", + "

* (where infinity would be a relatively small 123,456,789)

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "{{Trans|Haskell}}", + "(function () {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS ----------------------------------------------------", + "", + " // permutationsWithRepetition :: Int -> [a] -> [[a]]", + " var permutationsWithRepetition = function (n, as) {", + " return as.length > 0 ?", + " foldl1(curry(cartesianProduct)(as), replicate(n, as)) : [];", + " };", + "", + " // cartesianProduct :: [a] -> [b] -> [[a, b]]", + " var cartesianProduct = function (xs, ys) {", + " return [].concat.apply([], xs.map(function (x) {", + " return [].concat.apply([], ys.map(function (y) {", + " return [", + " [x].concat(y)", + " ];", + " }));", + " }));", + " };", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " var curry = function (f) {", + " return function (a) {", + " return function (b) {", + " return f(a, b);", + " };", + " };", + " };", + "", + " // flip :: (a -> b -> c) -> b -> a -> c", + " var flip = function (f) {", + " return function (a, b) {", + " return f.apply(null, [b, a]);", + " };", + " };", + "", + " // foldl1 :: (a -> a -> a) -> [a] -> a", + " var foldl1 = function (f, xs) {", + " return xs.length > 0 ? xs.slice(1)", + " .reduce(f, xs[0]) : [];", + " };", + "", + " // replicate :: Int -> a -> [a]", + " var replicate = function (n, a) {", + " var v = [a],", + " o = [];", + " if (n < 1) return o;", + " while (n > 1) {", + " if (n & 1) o = o.concat(v);", + " n >>= 1;", + " v = v.concat(v);", + " }", + " return o.concat(v);", + " };", + "", + " // group :: Eq a => [a] -> [[a]]", + " var group = function (xs) {", + " return groupBy(function (a, b) {", + " return a === b;", + " }, xs);", + " };", + "", + " // groupBy :: (a -> a -> Bool) -> [a] -> [[a]]", + " var groupBy = function (f, xs) {", + " var dct = xs.slice(1)", + " .reduce(function (a, x) {", + " var h = a.active.length > 0 ? a.active[0] : undefined,", + " blnGroup = h !== undefined && f(h, x);", + "", + " return {", + " active: blnGroup ? a.active.concat(x) : [x],", + " sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])", + " };", + " }, {", + " active: xs.length > 0 ? [xs[0]] : [],", + " sofar: []", + " });", + " return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);", + " };", + "", + " // compare :: a -> a -> Ordering", + " var compare = function (a, b) {", + " return a < b ? -1 : a > b ? 1 : 0;", + " };", + "", + " // on :: (b -> b -> c) -> (a -> b) -> a -> a -> c", + " var on = function (f, g) {", + " return function (a, b) {", + " return f(g(a), g(b));", + " };", + " };", + "", + " // nub :: [a] -> [a]", + " var nub = function (xs) {", + " return nubBy(function (a, b) {", + " return a === b;", + " }, xs);", + " };", + "", + " // nubBy :: (a -> a -> Bool) -> [a] -> [a]", + " var nubBy = function (p, xs) {", + " var x = xs.length ? xs[0] : undefined;", + "", + " return x !== undefined ? [x].concat(nubBy(p, xs.slice(1)", + " .filter(function (y) {", + " return !p(x, y);", + " }))) : [];", + " };", + "", + " // find :: (a -> Bool) -> [a] -> Maybe a", + " var find = function (f, xs) {", + " for (var i = 0, lng = xs.length; i < lng; i++) {", + " if (f(xs[i], i)) return xs[i];", + " }", + " return undefined;", + " };", + "", + " // Int -> [a] -> [a]", + " var take = function (n, xs) {", + " return xs.slice(0, n);", + " };", + "", + " // unlines :: [String] -> String", + " var unlines = function (xs) {", + " return xs.join('\\n');", + " };", + "", + " // show :: a -> String", + " var show = function (x) {", + " return JSON.stringify(x);", + " }; //, null, 2);", + "", + " // head :: [a] -> a", + " var head = function (xs) {", + " return xs.length ? xs[0] : undefined;", + " };", + "", + " // tail :: [a] -> [a]", + " var tail = function (xs) {", + " return xs.length ? xs.slice(1) : undefined;", + " };", + "", + " // length :: [a] -> Int", + " var length = function (xs) {", + " return xs.length;", + " };", + "", + " // SIGNED DIGIT SEQUENCES (mapped to sums and to strings)", + "", + " // data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )", + " // asSum :: [Sign] -> Int", + " var asSum = function (xs) {", + " var dct = xs.reduceRight(function (a, sign, i) {", + " var d = i + 1; // zero-based index to [1-9] positions", + " if (sign !== 0) {", + " // Sum increased, digits cleared", + " return {", + " digits: [],", + " n: a.n + sign * parseInt([d].concat(a.digits)", + " .join(''), 10)", + " };", + " } else return { // Digits extended, sum unchanged", + " digits: [d].concat(a.digits),", + " n: a.n", + " };", + " }, {", + " digits: [],", + " n: 0", + " });", + " return dct.n + (", + " dct.digits.length > 0 ? parseInt(dct.digits.join(''), 10) : 0", + " );", + " };", + "", + " // data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )", + " // asString :: [Sign] -> String", + " var asString = function (xs) {", + " var ns = xs.reduce(function (a, sign, i) {", + " var d = (i + 1)", + " .toString();", + " return sign === 0 ? a + d : a + (sign > 0 ? ' +' : ' -') + d;", + " }, '');", + "", + " return ns[0] === '+' ? tail(ns) : ns;", + " };", + "", + " // SUM T0 100 ------------------------------------------------------------", + "", + " // universe :: [[Sign]]", + " var universe = permutationsWithRepetition(9, [0, 1, -1])", + " .filter(function (x) {", + " return x[0] !== 1;", + " });", + "", + " // allNonNegativeSums :: [Int]", + " var allNonNegativeSums = universe.map(asSum)", + " .filter(function (x) {", + " return x >= 0;", + " })", + " .sort();", + "", + " // uniqueNonNegativeSums :: [Int]", + " var uniqueNonNegativeSums = nub(allNonNegativeSums);", + "", + " return [\"Sums to 100:\\n\", unlines(universe.filter(function (x) {", + " return asSum(x) === 100;", + " })", + " .map(asString)),", + "", + " \"\\n\\n10 commonest sums (sum, followed by number of routes to it):\\n\",", + " show(take(10, group(allNonNegativeSums)", + " .sort(on(flip(compare), length))", + " .map(function (xs) {", + " return [xs[0], xs.length];", + " }))),", + "", + " \"\\n\\nFirst positive integer not expressible as a sum of this kind:\\n\",", + " show(find(function (x, i) {", + " return x !== i;", + " }, uniqueNonNegativeSums.sort(compare)) - 1), // zero-based index", + "", + " \"\\n10 largest sums:\\n\",", + " show(take(10, uniqueNonNegativeSums.sort(flip(compare))))", + " ].join('\\n') + '\\n';", + "})();", + "", + "{{Out}}", + "(Run in Atom editor, through Script package)", + "
Sums to 100:",
+      "",
+      "123 +45 -67 +8 -9",
+      "123 +4 -5 +67 -89",
+      "123 -45 -67 +89",
+      "123 -4 -5 -6 -7 +8 -9",
+      "12 +3 +4 +5 -6 -7 +89",
+      "12 +3 -4 +5 +67 +8 +9",
+      "12 -3 -4 +5 -6 +7 +89",
+      "1 +23 -4 +56 +7 +8 +9",
+      "1 +23 -4 +5 +6 +78 -9",
+      "1 +2 +34 -5 +67 -8 +9",
+      "1 +2 +3 -4 +5 +6 +78 +9",
+      " -1 +2 -3 +4 +5 +6 +78 +9",
+      "",
+      "",
+      "10 commonest sums (sum, followed by number of routes to it):",
+      "",
+      "[[9,46],[27,44],[1,43],[15,43],[21,43],[45,42],[3,41],[5,40],[17,39],[7,39]]",
+      "",
+      "",
+      "First positive integer not expressible as a sum of this kind:",
+      "",
+      "211",
+      "",
+      "10 largest sums:",
+      "",
+      "[123456789,23456790,23456788,12345687,12345669,3456801,3456792,3456790,3456788,3456786]",
+      "",
+      "[Finished in 0.381s]
", + "", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " 'use strict';", + "", + " // GENERIC FUNCTIONS ----------------------------------------------------", + "", + " // permutationsWithRepetition :: Int -> [a] -> [[a]]", + " const permutationsWithRepetition = (n, as) =>", + " as.length > 0 ? (", + " foldl1(curry(cartesianProduct)(as), replicate(n, as))", + " ) : [];", + "", + " // cartesianProduct :: [a] -> [b] -> [[a, b]]", + " const cartesianProduct = (xs, ys) =>", + " [].concat.apply([], xs.map(x =>", + " [].concat.apply([], ys.map(y => [[x].concat(y)]))));", + "", + " // curry :: ((a, b) -> c) -> a -> b -> c", + " const curry = f => a => b => f(a, b);", + "", + " // flip :: (a -> b -> c) -> b -> a -> c", + " const flip = f => (a, b) => f.apply(null, [b, a]);", + "", + " // foldl1 :: (a -> a -> a) -> [a] -> a", + " const foldl1 = (f, xs) =>", + " xs.length > 0 ? xs.slice(1)", + " .reduce(f, xs[0]) : [];", + "", + " // replicate :: Int -> a -> [a]", + " const replicate = (n, a) => {", + " let v = [a],", + " o = [];", + " if (n < 1) return o;", + " while (n > 1) {", + " if (n & 1) o = o.concat(v);", + " n >>= 1;", + " v = v.concat(v);", + " }", + " return o.concat(v);", + " };", + "", + " // group :: Eq a => [a] -> [[a]]", + " const group = xs => groupBy((a, b) => a === b, xs);", + "", + " // groupBy :: (a -> a -> Bool) -> [a] -> [[a]]", + " const groupBy = (f, xs) => {", + " const dct = xs.slice(1)", + " .reduce((a, x) => {", + " const", + " h = a.active.length > 0 ? a.active[0] : undefined,", + " blnGroup = h !== undefined && f(h, x);", + "", + " return {", + " active: blnGroup ? a.active.concat(x) : [x],", + " sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])", + " };", + " }, {", + " active: xs.length > 0 ? [xs[0]] : [],", + " sofar: []", + " });", + " return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);", + " };", + "", + " // compare :: a -> a -> Ordering", + " const compare = (a, b) => a < b ? -1 : (a > b ? 1 : 0);", + "", + " // on :: (b -> b -> c) -> (a -> b) -> a -> a -> c", + " const on = (f, g) => (a, b) => f(g(a), g(b));", + "", + " // nub :: [a] -> [a]", + " const nub = xs => nubBy((a, b) => a === b, xs);", + "", + " // nubBy :: (a -> a -> Bool) -> [a] -> [a]", + " const nubBy = (p, xs) => {", + " const x = xs.length ? xs[0] : undefined;", + "", + " return x !== undefined ? [x].concat(", + " nubBy(p, xs.slice(1)", + " .filter(y => !p(x, y)))", + " ) : [];", + " };", + "", + " // find :: (a -> Bool) -> [a] -> Maybe a", + " const find = (f, xs) => {", + " for (var i = 0, lng = xs.length; i < lng; i++) {", + " if (f(xs[i], i)) return xs[i];", + " }", + " return undefined;", + " }", + "", + " // Int -> [a] -> [a]", + " const take = (n, xs) => xs.slice(0, n);", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x); //, null, 2);", + "", + " // head :: [a] -> a", + " const head = xs => xs.length ? xs[0] : undefined;", + "", + " // tail :: [a] -> [a]", + " const tail = xs => xs.length ? xs.slice(1) : undefined;", + "", + " // length :: [a] -> Int", + " const length = xs => xs.length;", + "", + "", + " // SIGNED DIGIT SEQUENCES (mapped to sums and to strings)", + "", + " // data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )", + " // asSum :: [Sign] -> Int", + " const asSum = xs => {", + " const dct = xs.reduceRight((a, sign, i) => {", + " const d = i + 1; // zero-based index to [1-9] positions", + " if (sign !== 0) { // Sum increased, digits cleared", + " return {", + " digits: [],", + " n: a.n + (sign * parseInt([d].concat(a.digits)", + " .join(''), 10))", + " };", + " } else return { // Digits extended, sum unchanged", + " digits: [d].concat(a.digits),", + " n: a.n", + " };", + " }, {", + " digits: [],", + " n: 0", + " });", + " return dct.n + (dct.digits.length > 0 ? (", + " parseInt(dct.digits.join(''), 10)", + " ) : 0);", + " };", + "", + " // data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )", + " // asString :: [Sign] -> String", + " const asString = xs => {", + " const ns = xs.reduce((a, sign, i) => {", + " const d = (i + 1)", + " .toString();", + " return (sign === 0 ? (", + " a + d", + " ) : (a + (sign > 0 ? ' +' : ' -') + d));", + " }, '');", + "", + " return ns[0] === '+' ? tail(ns) : ns;", + " };", + "", + "", + " // SUM T0 100 ------------------------------------------------------------", + "", + " // universe :: [[Sign]]", + " const universe = permutationsWithRepetition(9, [0, 1, -1])", + " .filter(x => x[0] !== 1);", + "", + " // allNonNegativeSums :: [Int]", + " const allNonNegativeSums = universe.map(asSum)", + " .filter(x => x >= 0)", + " .sort();", + "", + " // uniqueNonNegativeSums :: [Int]", + " const uniqueNonNegativeSums = nub(allNonNegativeSums);", + "", + "", + " return [", + " \"Sums to 100:\\n\",", + " unlines(universe.filter(x => asSum(x) === 100)", + " .map(asString)),", + "", + " \"\\n\\n10 commonest sums (sum, followed by number of routes to it):\\n\",", + " show(take(10, group(allNonNegativeSums)", + " .sort(on(flip(compare), length))", + " .map(xs => [xs[0], xs.length]))),", + "", + " \"\\n\\nFirst positive integer not expressible as a sum of this kind:\\n\",", + " show(find(", + " (x, i) => x !== i,", + " uniqueNonNegativeSums.sort(compare)", + " ) - 1), // i is the the zero-based Array index.", + "", + " \"\\n10 largest sums:\\n\",", + " show(take(10, uniqueNonNegativeSums.sort(flip(compare))))", + " ].join('\\n') + '\\n';", + "})();", + "", + "{{Out}}", + "(Run in Atom editor, through Script package)", + "
Sums to 100:",
+      "",
+      "123 +45 -67 +8 -9",
+      "123 +4 -5 +67 -89",
+      "123 -45 -67 +89",
+      "123 -4 -5 -6 -7 +8 -9",
+      "12 +3 +4 +5 -6 -7 +89",
+      "12 +3 -4 +5 +67 +8 +9",
+      "12 -3 -4 +5 -6 +7 +89",
+      "1 +23 -4 +56 +7 +8 +9",
+      "1 +23 -4 +5 +6 +78 -9",
+      "1 +2 +34 -5 +67 -8 +9",
+      "1 +2 +3 -4 +5 +6 +78 +9",
+      " -1 +2 -3 +4 +5 +6 +78 +9",
+      "",
+      "",
+      "10 commonest sums (sum, followed by number of routes to it):",
+      "",
+      "[[9,46],[27,44],[1,43],[15,43],[21,43],[45,42],[3,41],[5,40],[17,39],[7,39]]",
+      "",
+      "",
+      "First positive integer not expressible as a sum of this kind:",
+      "",
+      "211",
+      "",
+      "10 largest sums:",
+      "",
+      "[123456789,23456790,23456788,12345687,12345669,3456801,3456792,3456790,3456788,3456786]",
+      "",
+      "[Finished in 0.382s]
", + "", + "===ES3 (JScript)===", + "{{Works with|Microsoft Windows Script Host}}", + "{{Trans|AWK}}", + "SumTo100();", + "", + "function SumTo100()", + "{ ", + " var ", + " ADD = 0, ", + " SUB = 1, ", + " JOIN = 2;", + " ", + " var ", + " nexpr = 13122; ", + "", + " function out(something) ", + " { ", + " WScript.Echo(something); ", + " }", + "", + " function evaluate(code)", + " {", + " var ", + " value = 0, ", + " number = 0, ", + " power = 1;", + "", + " for ( var k = 9; k >= 1; k-- )", + " {", + " number = power*k + number;", + " switch( code % 3 )", + " {", + " case ADD: value = value + number; number = 0; power = 1; break;", + " case SUB: value = value - number; number = 0; power = 1; break;", + " case JOIN: power = power * 10 ; break;", + " }", + " code = Math.floor(code/3);", + " }", + " return value; ", + " }", + "", + " function print(code)", + " {", + " var ", + " s = \"\";", + " var ", + " a = 19683,", + " b = 6561; ", + " ", + " for ( var k = 1; k <= 9; k++ )", + " {", + " switch( Math.floor( (code % a) / b ) ){", + " case ADD: if ( k > 1 ) s = s + '+'; break;", + " case SUB: s = s + '-'; break;", + " }", + " a = b;", + " b = Math.floor(b/3);", + " s = s + String.fromCharCode(0x30+k);", + " } ", + " out(evaluate(code) + \" = \" + s);", + " }", + " ", + " function comment(commentString)", + " {", + " out(\"\");", + " out(commentString);", + " out(\"\"); ", + " }", + " ", + " comment(\"Show all solutions that sum to 100\");", + " for ( var i = 0; i < nexpr; i++) ", + " if ( evaluate(i) == 100 ) ", + " print(i); ", + " ", + " comment(\"Show the sum that has the maximum number of solutions\"); ", + " var stat = {};", + " for ( var i = 0; i < nexpr; i++ )", + " {", + " var sum = evaluate(i);", + " if (stat[sum])", + " stat[sum]++;", + " else", + " stat[sum] = 1;", + " }", + " ", + " var best = 0;", + " var nbest = -1;", + " for ( var i = 0; i < nexpr; i++ )", + " {", + " var sum = evaluate(i);", + " if ( sum > 0 )", + " if ( stat[sum] > nbest )", + " {", + " best = i; ", + " nbest = stat[sum];", + " }", + " }", + " out(\"\" + evaluate(best) + \" has \" + nbest + \" solutions\");", + " ", + " comment(\"Show the lowest positive number that can't be expressed\");", + " for ( var i = 0; i <= 123456789; i++ )", + " {", + " for ( var j = 0; j < nexpr; j++) ", + " if ( i == evaluate(j) ) break; ", + " if ( i != evaluate(j) ) break;", + " }", + " out(i);", + " ", + " comment(\"Show the ten highest numbers that can be expressed\");", + " var limit = 123456789 + 1;", + " for ( i = 1; i <= 10; i++ ) ", + " {", + " var best = 0;", + " for ( var j = 0; j < nexpr; j++)", + " {", + " var test = evaluate(j);", + " if ( test < limit && test > best ) ", + " best = test;", + " }", + " for ( var j = 0; j < nexpr; j++)", + " if ( evaluate(j) == best ) print(j);", + " limit = best;", + " }", + " ", + "}", + "", + "{{Out}}", + "
Show all solutions that sum to 100",
+      "",
+      "100 = 1+2+3-4+5+6+78+9",
+      "100 = 1+2+34-5+67-8+9",
+      "100 = 1+23-4+5+6+78-9",
+      "100 = 1+23-4+56+7+8+9",
+      "100 = 12+3+4+5-6-7+89",
+      "100 = 12+3-4+5+67+8+9",
+      "100 = 12-3-4+5-6+7+89",
+      "100 = 123+4-5+67-89",
+      "100 = 123+45-67+8-9",
+      "100 = 123-4-5-6-7+8-9",
+      "100 = 123-45-67+89",
+      "100 = -1+2-3+4+5+6+78+9",
+      "",
+      "Show the sum that has the maximum number of solutions",
+      "",
+      "9 has 46 solutions",
+      "",
+      "Show the lowest positive number that can't be expressed",
+      "",
+      "211",
+      "",
+      "Show the ten highest numbers that can be expressed",
+      "",
+      "123456789 = 123456789",
+      "23456790 = 1+23456789",
+      "23456788 = -1+23456789",
+      "12345687 = 12345678+9",
+      "12345669 = 12345678-9",
+      "3456801 = 12+3456789",
+      "3456792 = 1+2+3456789",
+      "3456790 = -1+2+3456789",
+      "3456788 = 1-2+3456789",
+      "3456786 = -1-2+3456789
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8043", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function () {\n 'use strict';\n\n // GENERIC FUNCTIONS ----------------------------------------------------\n\n // permutationsWithRepetition :: Int -> [a] -> [[a]]\n var permutationsWithRepetition = function (n, as) {\n return as.length > 0 ?\n foldl1(curry(cartesianProduct)(as), replicate(n, as)) : [];\n };\n\n // cartesianProduct :: [a] -> [b] -> [[a, b]]\n var cartesianProduct = function (xs, ys) {\n return [].concat.apply([], xs.map(function (x) {\n return [].concat.apply([], ys.map(function (y) {\n return [\n [x].concat(y)\n ];\n }));\n }));\n };\n\n // curry :: ((a, b) -> c) -> a -> b -> c\n var curry = function (f) {\n return function (a) {\n return function (b) {\n return f(a, b);\n };\n };\n };\n\n // flip :: (a -> b -> c) -> b -> a -> c\n var flip = function (f) {\n return function (a, b) {\n return f.apply(null, [b, a]);\n };\n };\n\n // foldl1 :: (a -> a -> a) -> [a] -> a\n var foldl1 = function (f, xs) {\n return xs.length > 0 ? xs.slice(1)\n .reduce(f, xs[0]) : [];\n };\n\n // replicate :: Int -> a -> [a]\n var replicate = function (n, a) {\n var v = [a],\n o = [];\n if (n < 1) return o;\n while (n > 1) {\n if (n & 1) o = o.concat(v);\n n >>= 1;\n v = v.concat(v);\n }\n return o.concat(v);\n };\n\n // group :: Eq a => [a] -> [[a]]\n var group = function (xs) {\n return groupBy(function (a, b) {\n return a === b;\n }, xs);\n };\n\n // groupBy :: (a -> a -> Bool) -> [a] -> [[a]]\n var groupBy = function (f, xs) {\n var dct = xs.slice(1)\n .reduce(function (a, x) {\n var h = a.active.length > 0 ? a.active[0] : undefined,\n blnGroup = h !== undefined && f(h, x);\n\n return {\n active: blnGroup ? a.active.concat(x) : [x],\n sofar: blnGroup ? a.sofar : a.sofar.concat([a.active])\n };\n }, {\n active: xs.length > 0 ? [xs[0]] : [],\n sofar: []\n });\n return dct.sofar.concat(dct.active.length > 0 ? [dct.active] : []);\n };\n\n // compare :: a -> a -> Ordering\n var compare = function (a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n };\n\n // on :: (b -> b -> c) -> (a -> b) -> a -> a -> c\n var on = function (f, g) {\n return function (a, b) {\n return f(g(a), g(b));\n };\n };\n\n // nub :: [a] -> [a]\n var nub = function (xs) {\n return nubBy(function (a, b) {\n return a === b;\n }, xs);\n };\n\n // nubBy :: (a -> a -> Bool) -> [a] -> [a]\n var nubBy = function (p, xs) {\n var x = xs.length ? xs[0] : undefined;\n\n return x !== undefined ? [x].concat(nubBy(p, xs.slice(1)\n .filter(function (y) {\n return !p(x, y);\n }))) : [];\n };\n\n // find :: (a -> Bool) -> [a] -> Maybe a\n var find = function (f, xs) {\n for (var i = 0, lng = xs.length; i < lng; i++) {\n if (f(xs[i], i)) return xs[i];\n }\n return undefined;\n };\n\n // Int -> [a] -> [a]\n var take = function (n, xs) {\n return xs.slice(0, n);\n };\n\n // unlines :: [String] -> String\n var unlines = function (xs) {\n return xs.join('\\n');\n };\n\n // show :: a -> String\n var show = function (x) {\n return JSON.stringify(x);\n }; //, null, 2);\n\n // head :: [a] -> a\n var head = function (xs) {\n return xs.length ? xs[0] : undefined;\n };\n\n // tail :: [a] -> [a]\n var tail = function (xs) {\n return xs.length ? xs.slice(1) : undefined;\n };\n\n // length :: [a] -> Int\n var length = function (xs) {\n return xs.length;\n };\n\n // SIGNED DIGIT SEQUENCES (mapped to sums and to strings)\n\n // data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )\n // asSum :: [Sign] -> Int\n var asSum = function (xs) {\n var dct = xs.reduceRight(function (a, sign, i) {\n var d = i + 1; // zero-based index to [1-9] positions\n if (sign !== 0) {\n // Sum increased, digits cleared\n return {\n digits: [],\n n: a.n + sign * parseInt([d].concat(a.digits)\n .join(''), 10)\n };\n } else return { // Digits extended, sum unchanged\n digits: [d].concat(a.digits),\n n: a.n\n };\n }, {\n digits: [],\n n: 0\n });\n return dct.n + (\n dct.digits.length > 0 ? parseInt(dct.digits.join(''), 10) : 0\n );\n };\n\n // data Sign :: [ 0 | 1 | -1 ] = ( Unsigned | Plus | Minus )\n // asString :: [Sign] -> String\n var asString = function (xs) {\n var ns = xs.reduce(function (a, sign, i) {\n var d = (i + 1)\n .toString();\n return sign === 0 ? a + d : a + (sign > 0 ? ' +' : ' -') + d;\n }, '');\n\n return ns[0] === '+' ? tail(ns) : ns;\n };\n\n // SUM T0 100 ------------------------------------------------------------\n\n // universe :: [[Sign]]\n var universe = permutationsWithRepetition(9, [0, 1, -1])\n .filter(function (x) {\n return x[0] !== 1;\n });\n\n // allNonNegativeSums :: [Int]\n var allNonNegativeSums = universe.map(asSum)\n .filter(function (x) {\n return x >= 0;\n })\n .sort();\n\n // uniqueNonNegativeSums :: [Int]\n var uniqueNonNegativeSums = nub(allNonNegativeSums);\n\n return [\"Sums to 100:\\n\", unlines(universe.filter(function (x) {\n return asSum(x) === 100;\n })\n .map(asString)),\n\n \"\\n\\n10 commonest sums (sum, followed by number of routes to it):\\n\",\n show(take(10, group(allNonNegativeSums)\n .sort(on(flip(compare), length))\n .map(function (xs) {\n return [xs[0], xs.length];\n }))),\n\n \"\\n\\nFirst positive integer not expressible as a sum of this kind:\\n\",\n show(find(function (x, i) {\n return x !== i;\n }, uniqueNonNegativeSums.sort(compare)) - 1), // zero-based index\n\n \"\\n10 largest sums:\\n\",\n show(take(10, uniqueNonNegativeSums.sort(flip(compare))))\n ].join('\\n') + '\\n';\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Superellipse", + "type": "Waypoint", + "description": [ + "

A superellipse is a geometric figure defined as the set of all points (x, y) with

", + "

:: $\\left|\\frac{x}{a}\\right|^n\\! + \\left|\\frac{y}{b}\\right|^n\\! = 1,$

", + "

where n, a, and b are positive numbers.

", + "Task", + "

Draw a superellipse with n = 2.5, and a = b = 200

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "var n = 2.5, a = 200, b = 200, ctx;", + "", + "function point( x, y ) {", + " ctx.fillRect( x, y, 1, 1);", + "}", + "", + "function start() {", + " var can = document.createElement('canvas');", + " can.width = can.height = 600;", + " ctx = can.getContext( \"2d\" );", + " ctx.rect( 0, 0, can.width, can.height );", + " ctx.fillStyle = \"#000000\"; ctx.fill();", + " document.body.appendChild( can );", + "", + " ctx.fillStyle = \"#ffffff\";", + " for( var t = 0; t < 1000; t += .1 ) {", + " x = Math.pow( Math.abs( Math.cos( t ) ), 2 / n ) * a * Math.sign( Math.cos( t ) );", + " y = Math.pow( Math.abs( Math.sin( t ) ), 2 / n ) * b * Math.sign( Math.sin( t ) );", + "", + " point( x + ( can.width >> 1 ), y + ( can.height >> 1 ) );", + " }", + "}", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8044", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nvar n = 2.5, a = 200, b = 200, ctx;\n\nfunction point( x, y ) {\n ctx.fillRect( x, y, 1, 1);\n}\n\nfunction start() {\n var can = document.createElement('canvas');\n can.width = can.height = 600;\n ctx = can.getContext( \"2d\" );\n ctx.rect( 0, 0, can.width, can.height );\n ctx.fillStyle = \"#000000\"; ctx.fill();\n document.body.appendChild( can );\n\n ctx.fillStyle = \"#ffffff\";\n for( var t = 0; t < 1000; t += .1 ) {\n x = Math.pow( Math.abs( Math.cos( t ) ), 2 / n ) * a * Math.sign( Math.cos( t ) );\n y = Math.pow( Math.abs( Math.sin( t ) ), 2 / n ) * b * Math.sign( Math.sin( t ) );\n\n point( x + ( can.width >> 1 ), y + ( can.height >> 1 ) );\n }\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Sutherland-Hodgman polygon clipping", + "type": "Waypoint", + "description": [ + "

The Sutherland-Hodgman clipping algorithm finds the polygon that is the intersection between an arbitrary polygon (the “subject polygon”) and a convex polygon (the “clip polygon”).

It is used in computer graphics (especially 2D graphics) to reduce the complexity of a scene being displayed by eliminating parts of a polygon that do not need to be displayed.

", + "Task:", + "

Take the closed polygon defined by the points:

", + "

$[(50, 150), (200, 50), (350, 150), (350, 300), (250, 300), (200, 250), (150, 350), (100, 250), (100, 200)]$

", + "

and clip it by the rectangle defined by the points:

", + "

$[(100, 100), (300, 100), (300, 300), (100, 300)]$

Print the sequence of points that define the resulting clipped polygon.

", + "Extra credit:", + "

Display all three polygons on a graphical surface, using a different color for each polygon and filling the resulting polygon.

(When displaying you may use either a north-west or a south-west origin, whichever is more convenient for your display mechanism.)

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "'''Solution:'''", + "", + "", + " ", + "\t", + " ", + " \t", + " ", + "", + "", + "", + "You can see it running [http://jsfiddle.net/elisherer/y6RDB/ here]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8045", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\n\n \n\t\n \n \t\n \n\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Symmetric difference", + "type": "Waypoint", + "description": [ + "Task", + "

Given two sets A and B, compute $(A \\setminus B) \\cup (B \\setminus A).$

That is, enumerate the items that are in A or B but not both. This set is called the symmetric difference of A and B.

In other words: $(A \\cup B) \\setminus (A \\cap B)$ (the set of items that are in at least one of A or B minus the set of items that are in both A and B).

Optionally, give the individual differences ($A \\setminus B$ and $B \\setminus A$) as well.

", + "Test cases", + "

A = {John, Bob, Mary, Serena}

", + "

B = {Jim, Mary, John, Bob}

", + "Notes", + "If your code uses lists of items to represent sets then ensure duplicate items in lists are correctly handled. For example two lists representing sets of a = [\"John\", \"Serena\", \"Bob\", \"Mary\", \"Serena\"] and b = [\"Jim\", \"Mary\", \"John\", \"Jim\", \"Bob\"] should produce the result of just two strings: [\"Serena\", \"Jim\"], in any order.", + "In the mathematical notation above A \\ B gives the set of items in A that are not in B; A ∪ B gives the set of items in both A and B, (their union); and A ∩ B gives the set of items that are in both A and B (their intersection)." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "====Iterative====", + "", + "{{works with|JavaScript|1.6}}", + "{{works with|Firefox|1.5}}", + "{{works with|SpiderMonkey}} for the print() function.", + "", + "Uses the Array function unique() defined [[Create a Sequence of unique elements#JavaScript|here]].", + "// in A but not in B", + "function relative_complement(A, B) {", + " return A.filter(function(elem) {return B.indexOf(elem) == -1});", + "}", + "", + "// in A or in B but not in both", + "function symmetric_difference(A,B) {", + " return relative_complement(A,B).concat(relative_complement(B,A));", + "}", + "", + "var a = [\"John\", \"Serena\", \"Bob\", \"Mary\", \"Serena\"].unique(); ", + "var b = [\"Jim\", \"Mary\", \"John\", \"Jim\", \"Bob\"].unique();", + "", + "print(a);", + "print(b);", + "print(symmetric_difference(a,b));", + "outputs", + "
Bob,John,Mary,Serena",
+      "Bob,Jim,John,Mary",
+      "Serena,Jim
", + "", + "'''Clear JavaScript'''", + "", + "function Difference(A,B)", + "{", + " var a = A.length, b = B.length, c = 0, C = [];", + " for (var i = 0; i < a; i++)", + " { var j = 0, k = 0;", + " while (j < b && B[j] !== A[i]) j++;", + " while (k < c && C[k] !== A[i]) k++;", + " if (j == b && k == c) C[c++] = A[i];", + " }", + " return C;", + "}", + "", + "function SymmetricDifference(A,B)", + "{ ", + " var D1 = Difference(A,B), D2 = Difference(B,A),", + " a = D1.length, b = D2.length;", + " for (var i = 0; i < b; i++) D1[a++] = D2[i];", + " return D1;", + "}", + "", + "", + "/* Example", + " A = ['John', 'Serena', 'Bob', 'Mary', 'Serena'];", + " B = ['Jim', 'Mary', 'John', 'Jim', 'Bob'];", + " ", + " Difference(A,B); // 'Serena'", + " Difference(B,A); // 'Jim'", + " SymmetricDifference(A,B); // 'Serena','Jim'", + "*/", + "", + "===ES6===", + "====Functional====", + "By composition of generic functions;", + "(() => {", + " 'use strict';", + "", + " const symmetricDifference = (xs, ys) =>", + " union(difference(xs, ys), difference(ys, xs));", + "", + "", + " // GENERIC FUNCTIONS ------------------------------------------------------", + "", + " // First instance of x (if any) removed from xs", + " // delete_ :: Eq a => a -> [a] -> [a]", + " const delete_ = (x, xs) => {", + " const i = xs.indexOf(x);", + " return i !== -1 ? (xs.slice(0, i)", + " .concat(xs.slice(i, -1))) : xs;", + " };", + "", + " // (\\\\) :: (Eq a) => [a] -> [a] -> [a]", + " const difference = (xs, ys) =>", + " ys.reduce((a, x) => filter(z => z !== x, a), xs);", + "", + " // filter :: (a -> Bool) -> [a] -> [a]", + " const filter = (f, xs) => xs.filter(f);", + "", + " // flip :: (a -> b -> c) -> b -> a -> c", + " const flip = f => (a, b) => f.apply(null, [b, a]);", + "", + " // foldl :: (b -> a -> b) -> b -> [a] -> b", + " const foldl = (f, a, xs) => xs.reduce(f, a);", + "", + " // nub :: [a] -> [a]", + " const nub = xs => {", + " const mht = unconsMay(xs);", + " return mht.nothing ? xs : (", + " ([h, t]) => [h].concat(nub(t.filter(s => s !== h)))", + " )(mht.just);", + " };", + "", + " // show :: a -> String", + " const show = x => JSON.stringify(x, null, 2);", + "", + " // unconsMay :: [a] -> Maybe (a, [a])", + " const unconsMay = xs => xs.length > 0 ? {", + " just: [xs[0], xs.slice(1)],", + " nothing: false", + " } : {", + " nothing: true", + " };", + "", + " // union :: [a] -> [a] -> [a]", + " const union = (xs, ys) => {", + " const sx = nub(xs);", + " return sx.concat(foldl(flip(delete_), nub(ys), sx));", + " };", + "", + " // TEST -------------------------------------------------------------------", + " const", + " a = [\"John\", \"Serena\", \"Bob\", \"Mary\", \"Serena\"],", + " b = [\"Jim\", \"Mary\", \"John\", \"Jim\", \"Bob\"];", + "", + " return show(", + " symmetricDifference(a, b)", + " );", + "})();", + "{{Out}}", + "[\"Serena\", \"Jim\"]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8046", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// in A but not in B\nfunction relative_complement(A, B) {\n return A.filter(function(elem) {return B.indexOf(elem) == -1});\n}\n\n// in A or in B but not in both\nfunction symmetric_difference(A,B) {\n return relative_complement(A,B).concat(relative_complement(B,A));\n}\n\nvar a = [\"John\", \"Serena\", \"Bob\", \"Mary\", \"Serena\"].unique(); \nvar b = [\"Jim\", \"Mary\", \"John\", \"Jim\", \"Bob\"].unique();\n\nprint(a);\nprint(b);\nprint(symmetric_difference(a,b));\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Synchronous concurrency", + "type": "Waypoint", + "description": [ + "

The goal of this task is to create two concurrent activities (\"Threads\" or \"Tasks\", not processes.) that share data synchronously. Your language may provide syntax or libraries to perform concurrency. Different languages provide different implementations of concurrency, often with different names. Some languages use the term threads, others use the term tasks, while others use co-processes. This task should not be implemented using fork, spawn, or the Linux/UNIX/Win32 pipe command, as communication should be between threads, not processes.

One of the concurrent units will read from a file named \"input.txt\" and send the contents of that file, one line at a time, to the other concurrent unit, which will print the line it receives to standard output. The printing unit must count the number of lines it prints. After the concurrent unit reading the file sends its last line to the printing unit, the reading unit will request the number of lines printed by the printing unit. The reading unit will then print the number of lines printed by the printing unit.

This task requires two-way communication between the concurrent units. All concurrent units must cleanly terminate at the end of the program.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8047", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Temperature conversion", + "type": "Waypoint", + "description": [ + "

There are quite a number of temperature scales. For this task we will concentrate on four of the perhaps best-known ones:

", + "

Kelvin, Celsius, Fahrenheit, and Rankine.

The Celsius and Kelvin scales have the same magnitude, but different null points.

0 degrees Celsius corresponds to 273.15 kelvin.

", + "

0 kelvin is absolute zero.

The Fahrenheit and Rankine scales also have the same magnitude, but different null points.

0 degrees Fahrenheit corresponds to 459.67 degrees Rankine.

", + "

0 degrees Rankine is absolute zero.

The Celsius/Kelvin and Fahrenheit/Rankine scales have a ratio of 5 : 9.

", + "Task", + "

Write code that accepts a value of kelvin, converts it to values of the three other scales, and prints the result.

", + "Example:", + "
",
+      "K  21.00C  -252.15F  -421.87R  37.80",
+      "
" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES5===", + "var k2c = k => k - 273.15", + "var k2r = k => k * 1.8", + "var k2f = k => k2r(k) - 459.67", + "", + "Number.prototype.toMaxDecimal = function (d) {", + "\treturn +this.toFixed(d) + ''", + "}", + "", + "function kCnv(k) {", + "\tdocument.write( k,'K° = ', k2c(k).toMaxDecimal(2),'C° = ', k2r(k).toMaxDecimal(2),'R° = ', k2f(k).toMaxDecimal(2),'F°
' ) ", + "}", + " ", + "kCnv(21)", + "kCnv(295)
", + "{{out}}", + "
",
+      "21K° = -252.15C° = 37.8R° = -421.87F°",
+      "295K° = 21.85C° = 531R° = 71.33F°",
+      "
", + "", + "===ES6===", + "", + "Deriving '''kelvinTranslations()''' from a more general '''heatBabel()''' function.", + "", + "(() => {", + " 'use strict';", + "", + " let kelvinTranslations = k => ['K', 'C', 'F', 'R']", + " .map(x => [x, heatBabel(k, 'K', x)]);", + "", + " // heatBabel :: Num -> ScaleName -> ScaleName -> Num", + " let heatBabel = (n, strFromScale, strToScale) => {", + " let ratio = 9 / 5,", + " cels = 273.15,", + " fahr = 459.67,", + " id = x => x,", + " readK = {", + " k: id,", + " c: x => cels + x,", + " f: x => (fahr + x) * ratio,", + " r: x => x / ratio", + " },", + " writeK = {", + " k: id,", + " c: x => x - cels,", + " f: x => (x * ratio) - fahr,", + " r: x => ratio * x", + " };", + "", + " return writeK[strToScale.charAt(0).toLowerCase()](", + " readK[strFromScale.charAt(0).toLowerCase()](n)", + " ).toFixed(2);", + " };", + "", + "", + " // TEST", + " return kelvinTranslations(21)", + " .map(([s, n]) => s + (' ' + n)", + " .slice(-10))", + " .join('\\n');", + "", + "})();", + "", + "", + "{{Out}}", + "", + "
K     21.00",
+      "C   -252.15",
+      "F   -421.87",
+      "R     37.80
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc804c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var k2c = k => k - 273.15\nvar k2r = k => k * 1.8\nvar k2f = k => k2r(k) - 459.67\n\nNumber.prototype.toMaxDecimal = function (d) {\n\treturn +this.toFixed(d) + ''\n}\n\nfunction kCnv(k) {\n\tdocument.write( k,'K° = ', k2c(k).toMaxDecimal(2),'C° = ', k2r(k).toMaxDecimal(2),'R° = ', k2f(k).toMaxDecimal(2),'F°
' ) \n}\n \nkCnv(21)\nkCnv(295)\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Ternary logic", + "type": "Waypoint", + "description": [ + "

In logic, a three-valued logic (also trivalent, ternary, or trinary logic, sometimes abbreviated 3VL) is any of several many-valued logic systems in which there are three truth values indicating true, false and some indeterminate third value.

This is contrasted with the more commonly known bivalent logics (such as classical sentential or boolean logic) which provide only for true and false.

Conceptual form and basic ideas were initially created by Łukasiewicz, Lewis and Sulski.

These were then re-formulated by Grigore Moisil in an axiomatic algebraic form, and also extended to n-valued logics in 1945.

", + "

{|

", + "

|+Example Ternary Logic Operators in Truth Tables:

", + "

|-

", + "

|

", + "

{| class=wikitable

", + "

|+not a

", + "

|-

", + "

! colspan=2 | ¬

", + "

|-

", + "

| True || False

", + "

|-

", + "

| Maybe || Maybe

", + "

|-

", + "

| False || True

", + "

|}

", + "

||

", + "

{| class=wikitable

", + "

|+a and b

", + "

|-

", + "

! ∧

", + "

| True || Maybe || False

", + "

|-

", + "

| True || True || Maybe || False

", + "

|-

", + "

| Maybe || Maybe || Maybe || False

", + "

|-

", + "

| False || False || False || False

", + "

|}

", + "

||

", + "

{| class=wikitable

", + "

|-

", + "

|+a or b

", + "

|-

", + "

! ∨

", + "

| True || Maybe || False

", + "

|-

", + "

| True || True || True || True

", + "

|-

", + "

| Maybe || True || Maybe || Maybe

", + "

|-

", + "

| False || True || Maybe || False

", + "

|}

", + "

|-

", + "

||

", + "

{| class=wikitable

", + "

|-

", + "

|+if a then b

", + "

|-

", + "

! ⊃

", + "

| True || Maybe || False

", + "

|-

", + "

| True || True || Maybe || False

", + "

|-

", + "

| Maybe || True || Maybe || Maybe

", + "

|-

", + "

| False || True || True || True

", + "

|}

", + "

||

", + "

{| class=wikitable

", + "

|-

", + "

|+a is equivalent to b

", + "

|-

", + "

! ≡

", + "

| True || Maybe || False

", + "

|-

", + "

| True || True || Maybe || False

", + "

|-

", + "

| Maybe || Maybe || Maybe || Maybe

", + "

|-

", + "

| False || False || Maybe || True

", + "

|}

", + "

|}

", + "Task:", + "Define a new type that emulates ternary logic by storing data trits.", + "Given all the binary logic operators of the original programming language, reimplement these operators for the new Ternary logic type trit.", + "Generate a sampling of results using trit variables.", + "Kudos for actually thinking up a test case algorithm where ternary logic is intrinsically useful, optimises the test case algorithm and is preferable to binary logic.", + "

Note: Setun (Сетунь) was a balanced ternary computer developed in 1958 at Moscow State University. The device was built under the lead of Sergei Sobolev and Nikolay Brusentsov. It was the only modern ternary computer, using three-valued ternary logic

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Let's use the trit already available in JavaScript:", + "true, false (both boolean) and undefined…", + "var L3 = new Object();", + "", + "L3.not = function(a) {", + " if (typeof a == \"boolean\") return !a;", + " if (a == undefined) return undefined;", + " throw(\"Invalid Ternary Expression.\");", + "}", + "", + "L3.and = function(a, b) {", + " if (typeof a == \"boolean\" && typeof b == \"boolean\") return a && b;", + " if ((a == true && b == undefined) || (a == undefined && b == true)) return undefined;", + " if ((a == false && b == undefined) || (a == undefined && b == false)) return false;", + " if (a == undefined && b == undefined) return undefined;", + " throw(\"Invalid Ternary Expression.\");", + "}", + "", + "L3.or = function(a, b) {", + " if (typeof a == \"boolean\" && typeof b == \"boolean\") return a || b;", + " if ((a == true && b == undefined) || (a == undefined && b == true)) return true;", + " if ((a == false && b == undefined) || (a == undefined && b == false)) return undefined;", + " if (a == undefined && b == undefined) return undefined;", + " throw(\"Invalid Ternary Expression.\");", + "}", + "", + "// A -> B is equivalent to -A or B", + "L3.ifThen = function(a, b) {", + " return L3.or(L3.not(a), b);", + "}", + "", + "// A <=> B is equivalent to (A -> B) and (B -> A)", + "L3.iff = function(a, b) {", + " return L3.and(L3.ifThen(a, b), L3.ifThen(b, a));", + "}", + "", + "… and try these:", + "", + "L3.not(true) // false", + "L3.not(var a) // undefined", + "", + "L3.and(true, a) // undefined", + "", + "L3.or(a, 2 == 3) // false", + "", + "L3.ifThen(true, a) // undefined", + "", + "L3.iff(a, 2 == 2) // undefined ", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8059", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "var L3 = new Object();\n\nL3.not = function(a) {\n if (typeof a == \"boolean\") return !a;\n if (a == undefined) return undefined;\n throw(\"Invalid Ternary Expression.\");\n}\n\nL3.and = function(a, b) {\n if (typeof a == \"boolean\" && typeof b == \"boolean\") return a && b;\n if ((a == true && b == undefined) || (a == undefined && b == true)) return undefined;\n if ((a == false && b == undefined) || (a == undefined && b == false)) return false;\n if (a == undefined && b == undefined) return undefined;\n throw(\"Invalid Ternary Expression.\");\n}\n\nL3.or = function(a, b) {\n if (typeof a == \"boolean\" && typeof b == \"boolean\") return a || b;\n if ((a == true && b == undefined) || (a == undefined && b == true)) return true;\n if ((a == false && b == undefined) || (a == undefined && b == false)) return undefined;\n if (a == undefined && b == undefined) return undefined;\n throw(\"Invalid Ternary Expression.\");\n}\n\n// A -> B is equivalent to -A or B\nL3.ifThen = function(a, b) {\n return L3.or(L3.not(a), b);\n}\n\n// A <=> B is equivalent to (A -> B) and (B -> A)\nL3.iff = function(a, b) {\n return L3.and(L3.ifThen(a, b), L3.ifThen(b, a));\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "The Twelve Days of Christmas", + "type": "Waypoint", + "description": [ + "

Write a program that outputs the lyrics of the Christmas carol The Twelve Days of Christmas.

", + "

The lyrics can be found here.

", + "

(You must reproduce the words in the correct order, but case, format, and punctuation are left to your discretion.)

Cf:", + "Comma quibbling" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "var days = [", + " 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', 'ninth',", + " 'tenth', 'eleventh', 'twelfth',", + "];", + "", + "var gifts = [", + " \"A partridge in a pear tree\",", + " \"Two turtle doves\",", + " \"Three french hens\",", + " \"Four calling birds\",", + " \"Five golden rings\",", + " \"Six geese a-laying\",", + " \"Seven swans a-swimming\",", + " \"Eight maids a-milking\",", + " \"Nine ladies dancing\",", + " \"Ten lords a-leaping\",", + " \"Eleven pipers piping\",", + " \"Twelve drummers drumming\"", + "];", + "", + "var lines, verses = [], song;", + "", + "for ( var i = 0; i < 12; i++ ) {", + "", + " lines = [];", + " lines[0] = \"On the \" + days[i] + \" day of Christmas, my true love gave to me\";", + " ", + " var j = i + 1;", + " var k = 0;", + " while ( j-- > 0 )", + " lines[++k] = gifts[j];", + "", + " ", + " verses[i] = lines.join('\\n');", + " ", + " if ( i == 0 )", + " gifts[0] = \"And a partridge in a pear tree\";", + " ", + "}", + "", + "song = verses.join('\\n\\n');", + "document.write(song);", + "", + "", + "", + "Alternatively, in a functional style of JavaScript, we can define the ancient song \"strPrepn the lstOrdinal[i] strUnit of strHoliday\" as an expression, and return that expression in a human-legible and machine-parseable JSON string translation, for further analysis and processing :-)", + "", + "JSON.stringify(", + " (function (", + " strPrepn,", + " strHoliday,", + " strUnit,", + " strRole,", + " strProcess,", + " strRecipient", + " ) {", + " var lstOrdinal =", + " 'first second third fourth fifth sixth\\", + " seventh eighth ninth tenth eleventh twelfth'", + " .split(/\\s+/),", + " lngUnits = lstOrdinal.length,", + "", + " lstGoods =", + " 'A partridge in a pear tree.\\", + " Two turtle doves\\", + " Three french hens\\", + " Four calling birds\\", + " Five golden rings\\", + " Six geese a-laying\\", + " Seven swans a-swimming\\", + " Eight maids a-milking\\", + " Nine ladies dancing\\", + " Ten lords a-leaping\\", + " Eleven pipers piping\\", + " Twelve drummers drumming'", + " .split(/\\s{2,}/),", + "", + " lstReversed = (function () {", + " var lst = lstGoods.slice(0);", + " return (lst.reverse(), lst);", + " })(),", + "", + " strProvenance = [strRole, strProcess, strRecipient + ':'].join(' '),", + "", + " strPenultimate = lstReversed[lngUnits - 2] + ' and',", + " strFinal = lstGoods[0];", + "", + " return lstOrdinal.reduce(", + " function (sofar, day, i) {", + " return sofar.concat(", + " [", + " [", + " [ // abstraction of line 1", + " strPrepn,", + " 'the',", + " lstOrdinal[i],", + " strUnit,", + " 'of',", + " strHoliday", + " ].join(' '),", + " strProvenance", + " ].concat( // reversed descent through memory", + " (i > 1 ? [lstGoods[i]] : []).concat(", + " lstReversed.slice(", + " lngUnits - i,", + " lngUnits - 2", + " )", + " ).concat( // penultimate line ends with 'and'", + " [", + " strPenultimate,", + " strFinal", + " ].slice(i ? 0 : 1)", + " )", + " )", + " ]", + " );", + " }, []", + " );", + " })(", + " 'On', 'Christmas', 'day', 'my true love', 'gave to', 'me'", + " ), null, 2", + ");", + "", + "Note that the Google Closure compiler's translation of this would be half the size, but rather less legible.", + "(It does make interesting suggestions though – the semi-colon segmentation of the verses below is a trick that might be worth remembering).", + "", + "JSON.stringify(function (h, k, l, f, m, n) {", + " var c =", + " \"first second third fourth fifth sixth seventh eighth ninth tenth eleventh twelfth\"", + " .split(\" \"),", + " d = c.length,", + " e =", + " \"A partridge in a pear tree.;Two turtle doves;Three french hens;Four calling birds;Five golden rings;Six geese a-laying;Seven swans a-swimming;Eight maids a-milking;Nine ladies dancing;Ten lords a-leaping;Eleven pipers piping;Twelve drummers drumming\"", + " .split(\";\"),", + " g = function () {", + " var b = e.slice(0);", + " return b.reverse(), b;", + " }(),", + " p = [f, m, n + \":\"].join(\" \"),", + " q = g[d - 2] + \" and\",", + " r = e[0];", + " ", + " return c.reduce(function (b, f, a) {", + " return b.concat([[[h, \"the\", c[a], l, \"of\", k].join(\" \"), p].concat((1 <", + " a ? [e[a]] : []).concat(g.slice(d - a, d - 2)).concat([q, r].slice(a ?", + " 0 : 1)))]);", + " }, []);", + "}(\"On\", \"Christmas\", \"day\", \"my true love\", \"gave to\", \"me\"), null, 2);", + "", + "Formatted JSON output (the expanded and Closure-compiled versions above both yield the same output).", + "", + "[", + " [", + " \"On the first day of Christmas\",", + " \"my true love gave to me:\",", + " \"A partridge in a pear tree.\"", + " ],", + " [", + " \"On the second day of Christmas\",", + " \"my true love gave to me:\",", + " \"Two turtle doves and\",", + " \"A partridge in a pear tree.\"", + " ],", + " [", + " \"On the third day of Christmas\",", + " \"my true love gave to me:\",", + " \"Three french hens\",", + " \"Two turtle doves and\",", + " \"A partridge in a pear tree.\"", + " ],", + " [", + " \"On the fourth day of Christmas\",", + " \"my true love gave to me:\",", + " \"Four calling birds\",", + " \"Three french hens\",", + " \"Two turtle doves and\",", + " \"A partridge in a pear tree.\"", + " ],", + " [", + " \"On the fifth day of Christmas\",", + " \"my true love gave to me:\",", + " \"Five golden rings\",", + " \"Four calling birds\",", + " \"Three french hens\",", + " \"Two turtle doves and\",", + " \"A partridge in a pear tree.\"", + " ]", + "", + "//... etc.", + "", + "]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84252665b21eecc8061", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nvar days = [\n 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', 'ninth',\n 'tenth', 'eleventh', 'twelfth',\n];\n\nvar gifts = [\n \"A partridge in a pear tree\",\n \"Two turtle doves\",\n \"Three french hens\",\n \"Four calling birds\",\n \"Five golden rings\",\n \"Six geese a-laying\",\n \"Seven swans a-swimming\",\n \"Eight maids a-milking\",\n \"Nine ladies dancing\",\n \"Ten lords a-leaping\",\n \"Eleven pipers piping\",\n \"Twelve drummers drumming\"\n];\n\nvar lines, verses = [], song;\n\nfor ( var i = 0; i < 12; i++ ) {\n\n lines = [];\n lines[0] = \"On the \" + days[i] + \" day of Christmas, my true love gave to me\";\n \n var j = i + 1;\n var k = 0;\n while ( j-- > 0 )\n lines[++k] = gifts[j];\n\n \n verses[i] = lines.join('\\n');\n \n if ( i == 0 )\n gifts[0] = \"And a partridge in a pear tree\";\n \n}\n\nsong = verses.join('\\n\\n');\ndocument.write(song);\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Thue-Morse", + "type": "Waypoint", + "description": [ + "Task:", + "

Create a Thue-Morse sequence.

", + "See also", + " YouTube entry: The Fairest Sharing Sequence Ever " + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "===ES6===", + "(() => {", + " 'use strict';", + "", + " // THUE MORSE", + "", + " // thueMorse :: Int -> String", + " let thueMorse = nCycles => range(1, Math.abs(nCycles))", + " .reduce(a => a.concat(a.map(x => 1 - x)), [0])", + " .join('');", + "", + "", + " // GENERIC FUNCTION", + "", + " // range :: Int -> Int -> [Int]", + " let range = (m, n) => Array.from({", + " length: Math.floor((n - m)) + 1", + " }, (_, i) => m + i);", + "", + "", + " // TEST", + "", + " return thueMorse(6);", + "", + " // 0110100110010110100101100110100110010110011010010110100110010110", + "", + "})();", + "", + "", + "{{Out}}", + "
0110100110010110100101100110100110010110011010010110100110010110
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc8063", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(() => {\n 'use strict';\n\n // THUE MORSE\n\n // thueMorse :: Int -> String\n let thueMorse = nCycles => range(1, Math.abs(nCycles))\n .reduce(a => a.concat(a.map(x => 1 - x)), [0])\n .join('');\n\n\n // GENERIC FUNCTION\n\n // range :: Int -> Int -> [Int]\n let range = (m, n) => Array.from({\n length: Math.floor((n - m)) + 1\n }, (_, i) => m + i);\n\n\n // TEST\n\n return thueMorse(6);\n\n // 0110100110010110100101100110100110010110011010010110100110010110\n\n})();\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Trabb Pardo–Knuth algorithm", + "type": "Waypoint", + "description": [ + "

The TPK algorithm is an early example of a programming chrestomathy.

", + "

It was used in Donald Knuth and Luis Trabb Pardo's Stanford tech report The Early Development of Programming Languages.

", + "

The report traces the early history of work in developing computer languages in the 1940s and 1950s, giving several translations of the algorithm.

From the wikipedia entry:

ask for 11 numbers to be read into a sequence S

", + "

reverse sequence S

", + "

for each item in sequence S

", + "

result := call a function to do an operation

", + "

if result overflows

", + "

alert user

", + "

else

", + "

print result

The task is to implement the algorithm:

", + "Use the function: $f(x) = |x|^{0.5} + 5x^3$", + "The overflow condition is an answer of greater than 400.", + "The 'user alert' should not stop processing of other items of the sequence.", + "Print a prompt before accepting eleven, textual, numeric inputs.", + "You may optionally print the item as well as its associated result, but the results must be in reverse order of input.", + "The sequence S may be 'implied' and so not shown explicitly.", + "Print and show the program in action from a typical run here. (If the output is graphical rather than text then either add a screendump or describe textually what is displayed)." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "", + "=== Spidermonkey ===", + "#!/usr/bin/env js", + "", + "function main() {", + " var nums = getNumbers(11);", + " nums.reverse();", + " for (var i in nums) {", + " pardoKnuth(nums[i], fn, 400);", + " }", + "}", + "", + "function pardoKnuth(n, f, max) {", + " var res = f(n);", + " putstr('f(' + String(n) + ')');", + " if (res > max) {", + " print(' is too large');", + " } else {", + " print(' = ' + String(res));", + " } ", + "}", + "", + "function fn(x) {", + " return Math.pow(Math.abs(x), 0.5) + 5 * Math.pow(x, 3);", + "}", + "", + "function getNumbers(n) {", + " var nums = [];", + " print('Enter', n, 'numbers.');", + " for (var i = 1; i <= n; i++) {", + " putstr(' ' + i + ': ');", + " var num = readline();", + " nums.push(Number(num)); ", + " }", + " return nums;", + "}", + "", + "main();", + "", + "", + "Results:", + " Enter 11 numbers.", + " 1: 1", + " 2: 2", + " 3: 3", + " 4: 4", + " 5: 5", + " 6: 6", + " 7: 7", + " 8: 8", + " 9: 9", + " 10: 10", + " 11: 11", + " f(11) is too large", + " f(10) is too large", + " f(9) is too large", + " f(8) is too large", + " f(7) is too large", + " f(6) is too large", + " f(5) is too large", + " f(4) = 322", + " f(3) = 136.73205080756887", + " f(2) = 41.41421356237309", + " f(1) = 6", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc806e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "#!/usr/bin/env js\n\nfunction main() {\n var nums = getNumbers(11);\n nums.reverse();\n for (var i in nums) {\n pardoKnuth(nums[i], fn, 400);\n }\n}\n\nfunction pardoKnuth(n, f, max) {\n var res = f(n);\n putstr('f(' + String(n) + ')');\n if (res > max) {\n print(' is too large');\n } else {\n print(' = ' + String(res));\n } \n}\n\nfunction fn(x) {\n return Math.pow(Math.abs(x), 0.5) + 5 * Math.pow(x, 3);\n}\n\nfunction getNumbers(n) {\n var nums = [];\n print('Enter', n, 'numbers.');\n for (var i = 1; i <= n; i++) {\n putstr(' ' + i + ': ');\n var num = readline();\n nums.push(Number(num)); \n }\n return nums;\n}\n\nmain();\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Tree traversal", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement a binary tree where each node carries an integer, and implement:

", + "

::* pre-order,

", + "

::* in-order,

", + "

::* post-order, and

", + "

::* level-order traversal.

", + "

Use those traversals to output the following tree:

", + "

1

", + "

/ \\

", + "

/ \\

", + "

/ \\

", + "

2 3

", + "

/ \\ /

", + "

4 5 6

", + "

/ / \\

", + "

7 8 9

The correct output should look like this:

", + "

preorder: 1 2 4 7 5 3 6 8 9

", + "

inorder: 7 4 2 5 1 8 6 9 3

", + "

postorder: 7 4 5 2 8 9 6 3 1

", + "

level-order: 1 2 3 4 5 6 7 8 9

", + "See also:", + " Wikipedia article: Tree traversal." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "====Iteration====", + "inspired by [[#Ruby|Ruby]]", + "function BinaryTree(value, left, right) {", + " this.value = value;", + " this.left = left;", + " this.right = right;", + "}", + "BinaryTree.prototype.preorder = function(f) {this.walk(f,['this','left','right'])}", + "BinaryTree.prototype.inorder = function(f) {this.walk(f,['left','this','right'])}", + "BinaryTree.prototype.postorder = function(f) {this.walk(f,['left','right','this'])}", + "BinaryTree.prototype.walk = function(func, order) {", + " for (var i in order) ", + " switch (order[i]) {", + " case \"this\": func(this.value); break;", + " case \"left\": if (this.left) this.left.walk(func, order); break;", + " case \"right\": if (this.right) this.right.walk(func, order); break;", + " }", + "}", + "BinaryTree.prototype.levelorder = function(func) {", + " var queue = [this];", + " while (queue.length != 0) {", + " var node = queue.shift();", + " func(node.value);", + " if (node.left) queue.push(node.left);", + " if (node.right) queue.push(node.right);", + " }", + "}", + "", + "// convenience function for creating a binary tree", + "function createBinaryTreeFromArray(ary) {", + " var left = null, right = null;", + " if (ary[1]) left = createBinaryTreeFromArray(ary[1]);", + " if (ary[2]) right = createBinaryTreeFromArray(ary[2]);", + " return new BinaryTree(ary[0], left, right);", + "}", + "", + "var tree = createBinaryTreeFromArray([1, [2, [4, [7]], [5]], [3, [6, [8],[9]]]]);", + "", + "print(\"*** preorder ***\"); tree.preorder(print); ", + "print(\"*** inorder ***\"); tree.inorder(print); ", + "print(\"*** postorder ***\"); tree.postorder(print);", + "print(\"*** levelorder ***\"); tree.levelorder(print);", + "", + "====Functional composition====", + "{{Trans|Haskell}}", + "(for binary trees consisting of nested lists)", + "", + "(function () {", + "", + " function preorder(n) {", + " return [n[v]].concat(", + " n[l] ? preorder(n[l]) : []", + " ).concat(", + " n[r] ? preorder(n[r]) : []", + " );", + " }", + "", + " function inorder(n) {", + " return (", + " n[l] ? inorder(n[l]) : []", + " ).concat(", + " n[v]", + " ).concat(", + " n[r] ? inorder(n[r]) : []", + " );", + " }", + "", + " function postorder(n) {", + " return (", + " n[l] ? postorder(n[l]) : []", + " ).concat(", + " n[r] ? postorder(n[r]) : []", + " ).concat(", + " n[v]", + " );", + " }", + "", + " function levelorder(n) {", + " return (function loop(x) {", + " return x.length ? (", + " x[0] ? (", + " [x[0][v]].concat(", + " loop(", + " x.slice(1).concat(", + " [x[0][l], x[0][r]]", + " )", + " )", + " )", + " ) : loop(x.slice(1))", + " ) : [];", + " })([n]);", + " }", + "", + " var v = 0,", + " l = 1,", + " r = 2,", + "", + " tree = [1,", + " [2,", + " [4,", + " [7]", + " ],", + " [5]", + " ],", + " [3,", + " [6,", + " [8],", + " [9]", + " ]", + " ]", + " ],", + "", + " lstTest = [[\"Traversal\", \"Nodes visited\"]].concat(", + " [preorder, inorder, postorder, levelorder].map(", + " function (f) {", + " return [f.name, f(tree)];", + " }", + " )", + " );", + "", + " // [[a]] -> bool -> s -> s", + " function wikiTable(lstRows, blnHeaderRow, strStyle) {", + " return '{| class=\"wikitable\" ' + (", + " strStyle ? 'style=\"' + strStyle + '\"' : ''", + " ) + lstRows.map(function (lstRow, iRow) {", + " var strDelim = ((blnHeaderRow && !iRow) ? '!' : '|');", + "", + " return '\\n|-\\n' + strDelim + ' ' + lstRow.map(function (v) {", + " return typeof v === 'undefined' ? ' ' : v;", + " }).join(' ' + strDelim + strDelim + ' ');", + " }).join('') + '\\n|}';", + " }", + "", + " return wikiTable(lstTest, true) + '\\n\\n' + JSON.stringify(lstTest);", + "", + "})();", + "", + "Output:", + "", + "{| class=\"wikitable\" ", + "|-", + "! Traversal !! Nodes visited", + "|-", + "| preorder || 1,2,4,7,5,3,6,8,9", + "|-", + "| inorder || 7,4,2,5,1,8,6,9,3", + "|-", + "| postorder || 7,4,5,2,8,9,6,3,1", + "|-", + "| levelorder || 1,2,3,4,5,6,7,8,9", + "|}", + "", + "[[\"Traversal\",\"Nodes visited\"],", + "[\"preorder\",[1,2,4,7,5,3,6,8,9]],[\"inorder\",[7,4,2,5,1,8,6,9,3]],", + "[\"postorder\",[7,4,5,2,8,9,6,3,1]],[\"levelorder\",[1,2,3,4,5,6,7,8,9]]]", + "", + "", + "or, again functionally, but:", + "", + "# for a tree of nested dictionaries (rather than a simple nested list),", + "# defining a single '''traverse()''' function", + "# checking that the tree is indeed binary, and returning ''undefined'' for the ''in-order'' traversal if any node in the tree has more than two children. (The other 3 traversals are still defined for rose trees).", + "", + "", + "(function () {", + " 'use strict';", + "", + " // 'preorder' | 'inorder' | 'postorder' | 'level-order'", + "", + " // traverse :: String -> Tree {value: a, nest: [Tree]} -> [a]", + " function traverse(strOrderName, dctTree) {", + " var strName = strOrderName.toLowerCase();", + "", + " if (strName.startsWith('level')) {", + "", + " // LEVEL-ORDER", + " return levelOrder([dctTree]);", + "", + " } else if (strName.startsWith('in')) {", + " var lstNest = dctTree.nest;", + "", + " if ((lstNest ? lstNest.length : 0) < 3) {", + " var left = lstNest[0] || [],", + " right = lstNest[1] || [],", + "", + " lstLeft = left.nest ? (", + " traverse(strName, left)", + " ) : (left.value || []),", + " lstRight = right.nest ? (", + " traverse(strName, right)", + " ) : (right.value || []);", + "", + " return (lstLeft !== undefined && lstRight !== undefined) ?", + "", + " // IN-ORDER", + " (lstLeft instanceof Array ? lstLeft : [lstLeft])", + " .concat(dctTree.value)", + " .concat(lstRight) : undefined;", + "", + " } else { // in-order only defined here for binary trees", + " return undefined;", + " }", + "", + " } else {", + " var lstTraversed = concatMap(function (x) {", + " return traverse(strName, x);", + " }, (dctTree.nest || []));", + "", + " return (", + " strName.startsWith('pre') ? (", + "", + " // PRE-ORDER", + " [dctTree.value].concat(lstTraversed)", + "", + " ) : strName.startsWith('post') ? (", + "", + " // POST-ORDER", + " lstTraversed.concat(dctTree.value)", + "", + " ) : []", + " );", + " }", + " }", + "", + " // levelOrder :: [Tree {value: a, nest: [Tree]}] -> [a]", + " function levelOrder(lstTree) {", + " var lngTree = lstTree.length,", + " head = lngTree ? lstTree[0] : undefined,", + " tail = lstTree.slice(1);", + "", + " // Recursively take any value found in the head node", + " // of the remaining tail, deferring any child nodes", + " // of that head to the end of the tail", + " return lngTree ? (", + " head ? (", + " [head.value].concat(", + " levelOrder(", + " tail", + " .concat(head.nest || [])", + " )", + " )", + " ) : levelOrder(tail)", + " ) : [];", + " }", + "", + " // concatMap :: (a -> [b]) -> [a] -> [b]", + " function concatMap(f, xs) {", + " return [].concat.apply([], xs.map(f));", + " }", + "", + " var dctTree = {", + " value: 1,", + " nest: [{", + " value: 2,", + " nest: [{", + " value: 4,", + " nest: [{", + " value: 7", + " }]", + " }, {", + " value: 5", + " }]", + " }, {", + " value: 3,", + " nest: [{", + " value: 6,", + " nest: [{", + " value: 8", + " }, {", + " value: 9", + " }]", + " }]", + " }]", + " };", + "", + "", + " return ['preorder', 'inorder', 'postorder', 'level-order']", + " .reduce(function (a, k) {", + " return (", + " a[k] = traverse(k, dctTree),", + " a", + " );", + " }, {});", + "", + "})();", + "{{Out}}", + "{\"preorder\":[1, 2, 4, 7, 5, 3, 6, 8, 9], ", + "\"inorder\":[7, 4, 2, 5, 1, 8, 6, 9, 3], ", + "\"postorder\":[7, 4, 5, 2, 8, 9, 6, 3, 1], ", + "\"level-order\":[1, 2, 3, 4, 5, 6, 7, 8, 9]}", + "", + "===ES6===", + "{{Trans|Haskell}}", + "(() => {", + " // TRAVERSALS -------------------------------------------------------------", + "", + " // preorder Tree a -> [a]", + " const preorder = a => [a[v]]", + " .concat(a[l] ? preorder(a[l]) : [])", + " .concat(a[r] ? preorder(a[r]) : []);", + "", + " // inorder Tree a -> [a]", + " const inorder = a =>", + " (a[l] ? inorder(a[l]) : [])", + " .concat(a[v])", + " .concat(a[r] ? inorder(a[r]) : []);", + "", + " // postorder Tree a -> [a]", + " const postorder = a =>", + " (a[l] ? postorder(a[l]) : [])", + " .concat(a[r] ? postorder(a[r]) : [])", + " .concat(a[v]);", + "", + " // levelorder Tree a -> [a]", + " const levelorder = a => (function go(x) {", + " return x.length ? (", + " x[0] ? (", + " [x[0][v]].concat(", + " go(x.slice(1)", + " .concat([x[0][l], x[0][r]])", + " )", + " )", + " ) : go(x.slice(1))", + " ) : [];", + " })([a]);", + "", + "", + " // GENERIC FUNCTIONS -----------------------------------------------------", + "", + " // A list of functions applied to a list of arguments", + " // <*> :: [(a -> b)] -> [a] -> [b]", + " const ap = (fs, xs) => //", + " [].concat.apply([], fs.map(f => //", + " [].concat.apply([], xs.map(x => [f(x)]))));", + "", + " // intercalate :: String -> [a] -> String", + " const intercalate = (s, xs) => xs.join(s);", + "", + " // justifyLeft :: Int -> Char -> Text -> Text", + " const justifyLeft = (n, cFiller, strText) =>", + " n > strText.length ? (", + " (strText + cFiller.repeat(n))", + " .substr(0, n)", + " ) : strText;", + "", + " // unlines :: [String] -> String", + " const unlines = xs => xs.join('\\n');", + "", + " // unwords :: [String] -> String", + " const unwords = xs => xs.join(' ');", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) =>", + " Array.from({", + " length: Math.min(xs.length, ys.length)", + " }, (_, i) => f(xs[i], ys[i]));", + "", + " // TEST -------------------------------------------------------------------", + " // asciiTree :: String", + " const asciiTree = unlines([", + " ' 1',", + " ' / \\\\',", + " ' / \\\\',", + " ' / \\\\',", + " ' 2 3',", + " ' / \\\\ /',", + " ' 4 5 6',", + " ' / / \\\\',", + " ' 7 8 9'", + " ]);", + "", + " const [v, l, r] = [0, 1, 2],", + " tree = [1, [2, [4, [7]],", + " [5]", + " ],", + " [3, [6, [8],", + " [9]", + " ]]", + " ],", + "", + " // fs :: [(Tree a -> [a])]", + " fs = [preorder, inorder, postorder, levelorder];", + "", + " return asciiTree + '\\n\\n' +", + " intercalate('\\n',", + " zipWith(", + " (f, xs) => justifyLeft(12, ' ', f.name + ':') + unwords(xs),", + " fs,", + " ap(fs, [tree])", + " )", + " );", + "})();", + "{{Out}}", + " 1", + " / \\", + " / \\", + " / \\", + " 2 3", + " / \\ /", + " 4 5 6", + " / / \\", + " 7 8 9", + "", + "preorder: 1 2 4 7 5 3 6 8 9", + "inorder: 7 4 2 5 1 8 6 9 3", + "postorder: 7 4 5 2 8 9 6 3 1", + "levelorder: 1 2 3 4 5 6 7 8 9", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc806f", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function BinaryTree(value, left, right) {\n this.value = value;\n this.left = left;\n this.right = right;\n}\nBinaryTree.prototype.preorder = function(f) {this.walk(f,['this','left','right'])}\nBinaryTree.prototype.inorder = function(f) {this.walk(f,['left','this','right'])}\nBinaryTree.prototype.postorder = function(f) {this.walk(f,['left','right','this'])}\nBinaryTree.prototype.walk = function(func, order) {\n for (var i in order) \n switch (order[i]) {\n case \"this\": func(this.value); break;\n case \"left\": if (this.left) this.left.walk(func, order); break;\n case \"right\": if (this.right) this.right.walk(func, order); break;\n }\n}\nBinaryTree.prototype.levelorder = function(func) {\n var queue = [this];\n while (queue.length != 0) {\n var node = queue.shift();\n func(node.value);\n if (node.left) queue.push(node.left);\n if (node.right) queue.push(node.right);\n }\n}\n\n// convenience function for creating a binary tree\nfunction createBinaryTreeFromArray(ary) {\n var left = null, right = null;\n if (ary[1]) left = createBinaryTreeFromArray(ary[1]);\n if (ary[2]) right = createBinaryTreeFromArray(ary[2]);\n return new BinaryTree(ary[0], left, right);\n}\n\nvar tree = createBinaryTreeFromArray([1, [2, [4, [7]], [5]], [3, [6, [8],[9]]]]);\n\nprint(\"*** preorder ***\"); tree.preorder(print); \nprint(\"*** inorder ***\"); tree.inorder(print); \nprint(\"*** postorder ***\"); tree.postorder(print);\nprint(\"*** levelorder ***\"); tree.levelorder(print);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Truth table", + "type": "Waypoint", + "description": [ + "

A truth table is a display of the inputs to, and the output of a Boolean equation organised as a table where each row gives one combination of input values and the corresponding value of the equation.

", + "Task:", + "Input a Boolean equation from the user as a string then calculate and print a formatted truth table for the given equation. (One can assume that the user input is correct).", + "Print and show output for Boolean equations of two and three input variables, but any program should not be limited to that many variables in the equation. ", + "Either reverse-polish or infix notation expressions are allowed.Related tasks:", + " Boolean values", + " Ternary logicSee also:", + " Wolfram MathWorld entry on truth tables.", + " some \"truth table\" examples from Google." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "Actually a HTML document. Save as a .html document and double-click it. You should be fine.", + "Truth table", + "{{Out|Output in browser window after entering \"AB^\"}}", + "
A B AB^",
+      "F F F",
+      "F T T",
+      "T F T",
+      "T T F
", + "{{Out|Output in browser window after entering \"ABC^{{!}}\"}}", + "
A B C ABC^|",
+      "F F F F",
+      "F F T T",
+      "F T F T",
+      "F T T F",
+      "T F F T",
+      "T F T T",
+      "T T F T",
+      "T T T T
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc8073", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "Truth table\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Ulam spiral (for primes)", + "type": "Waypoint", + "description": [ + "

An Ulam spiral (of primes numbers) is a method of visualizing prime numbers when expressed in a (normally counter-clockwise) outward spiral (usually starting at 1), constructed on a square grid, starting at the \"center\".

An Ulam spiral is also known as a prime spiral.

The first grid (green) is shown with all numbers (primes and non-primes) shown, starting at 1.

In an Ulam spiral of primes, only the primes are shown (usually indicated by some glyph such as a dot or asterisk), and all non-primes as shown as a blank (or some other whitespace).

Of course, the grid and border are not to be displayed (but they are displayed here when using these Wiki HTML tables).

Normally, the spiral starts in the \"center\", and the 2nd number is to the viewer's right and the number spiral starts from there in a counter-clockwise direction.

There are other geometric shapes that are used as well, including clock-wise spirals.

Also, some spirals (for the 2nd number) is viewed upwards from the 1st number instead of to the right, but that is just a matter of orientation.

Sometimes, the starting number can be specified to show more visual striking patterns (of prime densities).

[A larger than necessary grid (numbers wise) is shown here to illustrate the pattern of numbers on the diagonals (which may be used by the method to orientate the direction of spiral-construction algorithm within the example computer programs)].

Then, in the next phase in the transformation of the Ulam prime spiral, the non-primes are translated to blanks.

In the orange grid below, the primes are left intact, and all non-primes are changed to blanks.

Then, in the final transformation of the Ulam spiral (the yellow grid), translate the primes to a glyph such as a or some other suitable glyph.

", + "

{| style=\"float:left;border: 2px solid black; background:lightgreen; color:black; margin-left:0;margin-right:auto;text-align:center;width:34em;height:34em;table-layout:fixed;font-size:70%\"

", + "

|-

", + "

| 65 || 64 || 63 || 62 || 61 || 60 || 59 || 58 || 57

", + "

|->

", + "

| 66 || 37 || 36 || 35 || 34 || 33 || 32 || 31 || 56

", + "

|-

", + "

| 67 || 38 || 17 || 16 || 15 || 14 || 13 || 30 || 55

", + "

|-

", + "

| 68 || 39 || 18 || 5 || 4 || 3 || 12 || 29 || 54

", + "

|-

", + "

| 69 || 40 || 19 || 6 || 1 || 2 || 11 || 28 || 53

", + "

|-

", + "

| 70 || 41 || 20 || 7 || 8 || 9 || 10 || 27 || 52

", + "

|-

", + "

| 71 || 42 || 21 || 22 || 23 || 24 || 25 || 26 || 51

", + "

|-

", + "

| 72 || 43 || 44 || 45 || 46 || 47 || 48 || 49 || 50

", + "

|-

", + "

| 73 || 74 || 75 || 76 || 77 || 78 || 79 || 80 || 81

", + "

|}

{| style=\"float:left;border: 2px solid black; background:orange; color:black; margin-left:20px;margin-right:auto;text-align:center;width:34em;height:34em;table-layout:fixed;font-size:70%\"

", + "

|-

", + "

| || || || || 61 || || 59 || ||

", + "

|-

", + "

| || 37 || || || || || || 31 ||

", + "

|-

", + "

| 67 || || 17 || || || || 13 || ||

", + "

|-

", + "

| || || || 5 || || 3 || || 29 ||

", + "

|-

", + "

| || || 19 || || || 2 || 11 || || 53

", + "

|-

", + "

| || 41 || || 7 || || || || ||

", + "

|-

", + "

| 71 || || || || 23 || || || ||

", + "

|-

", + "

| || 43 || || || || 47 || || ||

", + "

|-

", + "

| 73 || || || || || || 79 || ||

", + "

|}

{| style=\"float:left;border: 2px solid black; background:yellow; color:black; margin-left:20px;margin-right:auto;text-align:center;width:34em;height:34em;table-layout:fixed;font-size:70%\"

", + "

|-

", + "

| || || || || || || || ||

", + "

|-

", + "

| || || || || || || || ||

", + "

|-

", + "

| || || || || || || || ||

", + "

|-

", + "

| || || || || || || || ||

", + "

|-

", + "

| || || || || || || || ||

", + "

|-

", + "

| || || || || || || || ||

", + "

|-

", + "

| || || || || || || || ||

", + "

|-

", + "

| || || || || || || || ||

", + "

|-

", + "

| || || || || || || || ||

", + "

|}

", + "

The Ulam spiral becomes more visually obvious as the grid increases in size.

", + "Task", + "

For any sized N x N grid, construct and show an Ulam spiral (counter-clockwise) of primes starting at some specified initial number (the default would be 1), with some suitably dotty (glyph) representation to indicate primes, and the absence of dots to indicate non-primes.

You should demonstrate the generator by showing at Ulam prime spiral large enough to (almost) fill your terminal screen.

", + "Related tasks:", + " Spiral matrix", + " Zig-zag matrix", + " Identity_matrix See also", + "Wikipedia entry: Ulam spiral ", + "MathWorld™ entry: Prime Spiral" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": "null", + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc8075", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": ["\n"], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Universal Turing machine", + "type": "Waypoint", + "description": [ + "

One of the foundational mathematical constructs behind computer science

", + "

is the universal Turing Machine.

Indeed one way to definitively prove that a language

", + "

is turing-complete

", + "

is to implement a universal Turing machine in it.

", + "Task:

Simulate such a machine capable

", + "

of taking the definition of any other Turing machine and executing it.

Of course, you will not have an infinite tape,

", + "

but you should emulate this as much as is possible.

The three permissible actions on the tape are \"left\", \"right\" and \"stay\".

To test your universal Turing machine (and prove your programming language

", + "

is Turing complete!), you should execute the following two Turing machines

", + "

based on the following definitions.

", + "

Simple incrementer

", + "States: q0, qf", + "Initial state: q0", + "Terminating states: qf", + "Permissible symbols: B, 1", + "Blank symbol: B", + "Rules:", + "* (q0, 1, 1, right, q0)", + "* (q0, B, 1, stay, qf)", + "

The input for this machine should be a tape of 1 1 1

", + "

Three-state busy beaver

", + "States: a, b, c, halt", + "Initial state: a", + "Terminating states: halt", + "Permissible symbols: 0, 1", + "Blank symbol: 0", + "Rules:", + "* (a, 0, 1, right, b)", + "* (a, 1, 1, left, c)", + "* (b, 0, 1, left, a)", + "* (b, 1, 1, right, b)", + "* (c, 0, 1, left, b)", + "* (c, 1, 1, stay, halt)", + "

The input for this machine should be an empty tape.

", + "

Bonus:

5-state, 2-symbol probable Busy Beaver machine from Wikipedia

", + "States: A, B, C, D, E, H", + "Initial state: A", + "Terminating states: H", + "Permissible symbols: 0, 1", + "Blank symbol: 0", + "Rules:", + "* (A, 0, 1, right, B)", + "* (A, 1, 1, left, C)", + "* (B, 0, 1, right, C)", + "* (B, 1, 1, right, B)", + "* (C, 0, 1, right, D)", + "* (C, 1, 0, left, E)", + "* (D, 0, 1, left, A)", + "* (D, 1, 1, left, D)", + "* (E, 0, 1, stay, H)", + "* (E, 1, 0, left, A)", + "

The input for this machine should be an empty tape.

This machine runs for more than 47 millions steps.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{works with|FireFox}}", + "function tm(d,s,e,i,b,t,... r) {", + "\tdocument.write(d, '
')", + "\tif (i<0||i>=t.length) return", + "\tvar re=new RegExp(b,'g')", + "\twrite('*',s,i,t=t.split(''))", + "\tvar p={}; r.forEach(e=>((s,r,w,m,n)=>{p[s+'.'+r]={w,n,m:[0,1,-1][1+'RL'.indexOf(m)]}})(... e.split(/[ .:,]+/)))", + "\tfor (var n=1; s!=e; n+=1) {", + "\t\twith (p[s+'.'+t[i]]) t[i]=w,s=n,i+=m", + "\t\tif (i==-1) i=0,t.unshift(b)", + "\t\telse if (i==t.length) t[i]=b", + "\t\twrite(n,s,i,t)", + "\t}", + "\tdocument.write('
')", + "\tfunction write(n, s, i, t) {", + "\t\tt = t.join('')", + "\t\tt = t.substring(0,i) + '' + t.charAt(i) + '' + t.substr(i+1)", + "\t\tdocument.write((' '+n).slice(-3).replace(/ /g,' '), ': ', s, ' [', t.replace(re,' '), ']', '
')", + "\t}", + "}", + "", + "tm( 'Unary incrementer',", + "//\t s e i b t", + "\t'a', 'h', 0, 'B', '111',", + "//\t s.r: w, m, n", + "\t'a.1: 1, L, a',", + "\t'a.B: 1, S, h'", + ")", + "", + "tm( 'Unary adder',", + "\t1, 0, 0, '0', '1110111',", + "\t'1.1: 0, R, 2', // write 0 rigth goto 2", + "\t'2.1: 1, R, 2', // while (1) rigth", + "\t'2.0: 1, S, 0' // write 1 stay halt", + ")", + "", + "tm( 'Three-state busy beaver',", + "\t1, 0, 0, '0', '0',", + "\t'1.0: 1, R, 2',", + "\t'1.1: 1, R, 0',", + "\t'2.0: 0, R, 3',", + "\t'2.1: 1, R, 2',", + "\t'3.0: 1, L, 3',", + "\t'3.1: 1, L, 1'", + ")
", + "{{out}}", + " Unary incrementer
  *: a [111]
  1: a [ 111]
  2: h [1111]

Unary adder
   *: 1 [111 111]
  1: 2 [ 11 111]
  2: 3 [ 11 111]
  3: 3 [ 11 111]
  4: 0 [ 111111]

Three-state busy beaver
   *: 1 [ ]
  1: 2 [1 ]
  2: 3 [1  ]
  3: 3 [1 1]
  4: 3 [111]
  5: 1 [ 111]
  6: 2 [1111]
  7: 2 [1111]
  8: 2 [1111]
  9: 2 [1111 ]
 10: 3 [1111  ]
 11: 3 [1111 1]
 12: 3 [111111]
 13: 1 [111111]
 14: 0 [111111]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc807a", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function tm(d,s,e,i,b,t,... r) {\n\tdocument.write(d, '
')\n\tif (i<0||i>=t.length) return\n\tvar re=new RegExp(b,'g')\n\twrite('*',s,i,t=t.split(''))\n\tvar p={}; r.forEach(e=>((s,r,w,m,n)=>{p[s+'.'+r]={w,n,m:[0,1,-1][1+'RL'.indexOf(m)]}})(... e.split(/[ .:,]+/)))\n\tfor (var n=1; s!=e; n+=1) {\n\t\twith (p[s+'.'+t[i]]) t[i]=w,s=n,i+=m\n\t\tif (i==-1) i=0,t.unshift(b)\n\t\telse if (i==t.length) t[i]=b\n\t\twrite(n,s,i,t)\n\t}\n\tdocument.write('
')\n\tfunction write(n, s, i, t) {\n\t\tt = t.join('')\n\t\tt = t.substring(0,i) + '' + t.charAt(i) + '' + t.substr(i+1)\n\t\tdocument.write((' '+n).slice(-3).replace(/ /g,' '), ': ', s, ' [', t.replace(re,' '), ']', '
')\n\t}\n}\n\ntm( 'Unary incrementer',\n//\t s e i b t\n\t'a', 'h', 0, 'B', '111',\n//\t s.r: w, m, n\n\t'a.1: 1, L, a',\n\t'a.B: 1, S, h'\n)\n\ntm( 'Unary adder',\n\t1, 0, 0, '0', '1110111',\n\t'1.1: 0, R, 2', // write 0 rigth goto 2\n\t'2.1: 1, R, 2', // while (1) rigth\n\t'2.0: 1, S, 0' // write 1 stay halt\n)\n\ntm( 'Three-state busy beaver',\n\t1, 0, 0, '0', '0',\n\t'1.0: 1, R, 2',\n\t'1.1: 1, R, 0',\n\t'2.0: 0, R, 3',\n\t'2.1: 1, R, 2',\n\t'3.0: 1, L, 3',\n\t'3.1: 1, L, 1'\n)\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Vector products", + "type": "Waypoint", + "description": [ + "

A vector is defined as having three dimensions as being represented by an ordered collection of three numbers: (X, Y, Z).

If you imagine a graph with the x and y axis being at right angles to each other and having a third, z axis coming out of the page, then a triplet of numbers, (X, Y, Z) would represent a point in the region, and a vector from the origin to the point.

Given the vectors:

", + "

A = (a1, a2, a3)

", + "

B = (b1, b2, b3)

", + "

C = (c1, c2, c3)

", + "

then the following common vector products are defined:

", + "The dot product (a scalar quantity)::: A • B = a1b1 + a2b2 + a3b3 ", + "The cross product (a vector quantity)::: A x B = (a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1) ", + "The scalar triple product (a scalar quantity)::: A • (B x C) ", + "The vector triple product (a vector quantity)::: A x (B x C) ", + "Task:", + "

Given the three vectors:

", + "

a = ( 3, 4, 5)

", + "

b = ( 4, 3, 5)

", + "

c = (-5, -12, -13)

", + "Create a named function/subroutine/method to compute the dot product of two vectors.", + "Create a function to compute the cross product of two vectors.", + "Optionally create a function to compute the scalar triple product of three vectors.", + "Optionally create a function to compute the vector triple product of three vectors.", + "Compute and display: a • b", + "Compute and display: a x b", + "Compute and display: a • b x c, the scalar triple product.", + "Compute and display: a x b x c, the vector triple product.References:", + " A starting page on Wolfram MathWorld is .", + " Wikipedia dot product, Wikipedia cross product ", + "

Wikipedia triple product entries.

", + "Related tasks:", + " Dot product", + " Quaternion type" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "The dotProduct() function is generic and will create a dot product of any set of vectors provided they are all the same dimension.", + "The crossProduct() function expects two 3D vectors.", + "function dotProduct() {", + " var len = arguments[0] && arguments[0].length;", + " var argsLen = arguments.length;", + " var i, j = len;", + " var prod, sum = 0;", + " ", + " // If no arguments supplied, return undefined", + " if (!len) {", + " return;", + " }", + " ", + " // If all vectors not same length, return undefined", + " i = argsLen;", + " while (i--) {", + " ", + " if (arguments[i].length != len) {", + " return; // return undefined", + " }", + " }", + " ", + " // Sum terms", + " while (j--) {", + " i = argsLen;", + " prod = 1;", + " ", + " while (i--) {", + " prod *= arguments[i][j];", + " }", + " sum += prod;", + " }", + " return sum;", + "}", + "", + "function crossProduct(a, b) {", + "", + " // Check lengths", + " if (a.length != 3 || b.length != 3) {", + " return;", + " }", + " ", + " return [a[1]*b[2] - a[2]*b[1],", + " a[2]*b[0] - a[0]*b[2],", + " a[0]*b[1] - a[1]*b[0]];", + " ", + "}", + "", + "function scalarTripleProduct(a, b, c) {", + " return dotProduct(a, crossProduct(b, c));", + "}", + "", + "function vectorTripleProduct(a, b, c) {", + " return crossProduct(a, crossProduct(b, c));", + "}", + "", + "// Run tests", + "(function () {", + " var a = [3, 4, 5];", + " var b = [4, 3, 5];", + " var c = [-5, -12, -13];", + " ", + " alert(", + " 'A . B: ' + dotProduct(a, b) +", + " '\\n' +", + " 'A x B: ' + crossProduct(a, b) +", + " '\\n' +", + " 'A . (B x C): ' + scalarTripleProduct(a, b, c) +", + " '\\n' +", + " 'A x (B x C): ' + vectorTripleProduct(a, b, c)", + " ); ", + "}());", + "Output:", + "
",
+      "A . B: 49",
+      "A x B: 5,5,-7",
+      "A . (B x C): 6",
+      "A x (B x C): -267,204,-3",
+      "
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc808c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function dotProduct() {\n var len = arguments[0] && arguments[0].length;\n var argsLen = arguments.length;\n var i, j = len;\n var prod, sum = 0;\n \n // If no arguments supplied, return undefined\n if (!len) {\n return;\n }\n \n // If all vectors not same length, return undefined\n i = argsLen;\n while (i--) {\n \n if (arguments[i].length != len) {\n return; // return undefined\n }\n }\n \n // Sum terms\n while (j--) {\n i = argsLen;\n prod = 1;\n \n while (i--) {\n prod *= arguments[i][j];\n }\n sum += prod;\n }\n return sum;\n}\n\nfunction crossProduct(a, b) {\n\n // Check lengths\n if (a.length != 3 || b.length != 3) {\n return;\n }\n \n return [a[1]*b[2] - a[2]*b[1],\n a[2]*b[0] - a[0]*b[2],\n a[0]*b[1] - a[1]*b[0]];\n \n}\n\nfunction scalarTripleProduct(a, b, c) {\n return dotProduct(a, crossProduct(b, c));\n}\n\nfunction vectorTripleProduct(a, b, c) {\n return crossProduct(a, crossProduct(b, c));\n}\n\n// Run tests\n(function () {\n var a = [3, 4, 5];\n var b = [4, 3, 5];\n var c = [-5, -12, -13];\n \n alert(\n 'A . B: ' + dotProduct(a, b) +\n '\\n' +\n 'A x B: ' + crossProduct(a, b) +\n '\\n' +\n 'A . (B x C): ' + scalarTripleProduct(a, b, c) +\n '\\n' +\n 'A x (B x C): ' + vectorTripleProduct(a, b, c)\n ); \n}());\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Verify distribution uniformity/Naive", + "type": "Waypoint", + "description": [ + "

This task is an adjunct to Seven-sided dice from five-sided dice.

", + "Ttask:", + "

Create a function to check that the random integers returned from a small-integer generator function have uniform distribution.

", + "

The function should take as arguments:

", + "The function (or object) producing random integers.", + "The number of times to call the integer generator.", + "A 'delta' value of some sort that indicates how close to a flat distribution is close enough.", + "

The function should produce:

", + "Some indication of the distribution achieved.", + "An 'error' if the distribution is not flat enough.", + "

Show the distribution checker working when the produced distribution is flat enough and when it is not. (Use a generator from Seven-sided dice from five-sided dice).

See also:

", + "Verify distribution uniformity/Chi-squared test" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "{{trans|Tcl}}", + "function distcheck(random_func, times, opts) {", + " if (opts === undefined) opts = {}", + " opts['delta'] = opts['delta'] || 2;", + "", + " var count = {}, vals = [];", + " for (var i = 0; i < times; i++) {", + " var val = random_func();", + " if (! has_property(count, val)) {", + " count[val] = 1;", + " vals.push(val);", + " }", + " else", + " count[val] ++;", + " }", + " vals.sort(function(a,b) {return a-b});", + "", + " var target = times / vals.length;", + " var tolerance = target * opts['delta'] / 100; ", + "", + " for (var i = 0; i < vals.length; i++) {", + " var val = vals[i];", + " if (Math.abs(count[val] - target) > tolerance) ", + " throw \"distribution potentially skewed for \" + val +", + " \": expected result around \" + target + \", got \" +count[val];", + " else", + " print(val + \"\\t\" + count[val]);", + " }", + "}", + "", + "function has_property(obj, propname) {", + " return typeof(obj[propname]) == \"undefined\" ? false : true;", + "}", + "", + "try {", + " distcheck(function() {return Math.floor(10 * Math.random())}, 100000);", + " print();", + " distcheck(function() {return (Math.random() > 0.95 ? 1 : 0)}, 100000);", + "} catch (e) {", + " print(e);", + "}", + "Output:", + "
0       9945",
+      "1       9862",
+      "2       9954",
+      "3       10104",
+      "4       9861",
+      "5       10140",
+      "6       10066",
+      "7       10001",
+      "8       10101",
+      "9       9966",
+      "",
+      "distribution potentially skewed for 0: expected result around 50000, got 95040
", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc808e", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "function distcheck(random_func, times, opts) {\n if (opts === undefined) opts = {}\n opts['delta'] = opts['delta'] || 2;\n\n var count = {}, vals = [];\n for (var i = 0; i < times; i++) {\n var val = random_func();\n if (! has_property(count, val)) {\n count[val] = 1;\n vals.push(val);\n }\n else\n count[val] ++;\n }\n vals.sort(function(a,b) {return a-b});\n\n var target = times / vals.length;\n var tolerance = target * opts['delta'] / 100; \n\n for (var i = 0; i < vals.length; i++) {\n var val = vals[i];\n if (Math.abs(count[val] - target) > tolerance) \n throw \"distribution potentially skewed for \" + val +\n \": expected result around \" + target + \", got \" +count[val];\n else\n print(val + \"\\t\" + count[val]);\n }\n}\n\nfunction has_property(obj, propname) {\n return typeof(obj[propname]) == \"undefined\" ? false : true;\n}\n\ntry {\n distcheck(function() {return Math.floor(10 * Math.random())}, 100000);\n print();\n distcheck(function() {return (Math.random() > 0.95 ? 1 : 0)}, 100000);\n} catch (e) {\n print(e);\n}\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Vigenère cipher", + "type": "Waypoint", + "description": [ + "Task:", + "

Implement a Vigenère cypher, both encryption and decryption.

The program should handle keys and text of unequal length,

", + "

and should capitalize everything and discard non-alphabetic characters.

", + "

(If your program handles non-alphabetic characters in another way,

", + "

make a note of it.)

", + "Related tasks:", + " Caesar cipher", + " Rot-13", + " Substitution Cipher" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "// helpers", + "// helper", + "function ordA(a) {", + " return a.charCodeAt(0) - 65;", + "}", + "", + "// vigenere", + "function vigenere(text, key, decode) {", + " var i = 0, b;", + " key = key.toUpperCase().replace(/[^A-Z]/g, '');", + " return text.toUpperCase().replace(/[^A-Z]/g, '').replace(/[A-Z]/g, function(a) {", + " b = key[i++ % key.length];", + " return String.fromCharCode(((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65));", + " });", + "}", + "", + "// example", + "var text = \"The quick brown fox Jumped over the lazy Dog the lazy dog lazy dog dog\";", + "var key = 'alex';", + "var enc = vigenere(text,key);", + "var dec = vigenere(enc,key,true);", + "", + "console.log(enc);", + "console.log(dec);", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc8091", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "// helpers\n// helper\nfunction ordA(a) {\n return a.charCodeAt(0) - 65;\n}\n\n// vigenere\nfunction vigenere(text, key, decode) {\n var i = 0, b;\n key = key.toUpperCase().replace(/[^A-Z]/g, '');\n return text.toUpperCase().replace(/[^A-Z]/g, '').replace(/[A-Z]/g, function(a) {\n b = key[i++ % key.length];\n return String.fromCharCode(((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65));\n });\n}\n\n// example\nvar text = \"The quick brown fox Jumped over the lazy Dog the lazy dog lazy dog dog\";\nvar key = 'alex';\nvar enc = vigenere(text,key);\nvar dec = vigenere(enc,key,true);\n\nconsole.log(enc);\nconsole.log(dec);\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Water collected between towers", + "type": "Waypoint", + "description": [ + "Task:", + "

In a two-dimensional world, we begin with any bar-chart (or row of close-packed 'towers', each of unit width), and then it rains,

", + "

completely filling all convex enclosures in the chart with water.

", + "
9               ██           9               ██    ",
+      "8               ██           8               ██    ",
+      "7     ██        ██           7     ██≈≈≈≈≈≈≈≈██    ",
+      "6     ██  ██    ██           6     ██≈≈██≈≈≈≈██    ",
+      "5 ██  ██  ██  ████           5 ██≈≈██≈≈██≈≈████    ",
+      "4 ██  ██  ████████           4 ██≈≈██≈≈████████    ",
+      "3 ██████  ████████           3 ██████≈≈████████    ",
+      "2 ████████████████  ██       2 ████████████████≈≈██",
+      "1 ████████████████████       1 ████████████████████
", + "

In the example above, a bar chart representing the values [5, 3, 7, 2, 6, 4, 5, 9, 1, 2] has filled, collecting 14 units of water.

Write a function, in your language, from a given array of heights, to the number of water units that can be held in this way, by a corresponding bar chart.

Calculate the number of water units that could be collected by bar charts representing each of the following seven series:

   [[1, 5, 3, 7, 2],",
+      "    [5, 3, 7, 2, 6, 4, 5, 9, 1, 2],",
+      "    [2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1],",
+      "    [5, 5, 5, 5],",
+      "    [5, 6, 7, 8],",
+      "    [8, 7, 7, 6],",
+      "    [6, 7, 10, 7, 6]]
", + "

See, also:

Four Solutions to a Trivial Problem – a Google Tech Talk by Guy Steele", + "Water collected between towers on Stack Overflow, from which the example above is taken)", + "An interesting Haskell solution, using the Tardis monad, by Phil Freeman in a Github gist." + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "===ES5===", + "{{Trans|Haskell}}", + "(function () {", + " 'use strict';", + "", + " // waterCollected :: [Int] -> Int", + " var waterCollected = function (xs) {", + " return sum( // water above each bar", + " zipWith(function (a, b) {", + " return a - b; // difference between water level and bar", + " },", + " zipWith(min, // lower of two flanking walls", + " scanl1(max, xs), // highest walls to left", + " scanr1(max, xs) // highest walls to right", + " ), ", + " xs // tops of bars", + " )", + " .filter(function (x) {", + " return x > 0; // only bars with water above them", + " })", + " );", + " };", + "", + " // GENERIC FUNCTIONS ----------------------------------------", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " var zipWith = function (f, xs, ys) {", + " var ny = ys.length;", + " return (xs.length <= ny ? xs : xs.slice(0, ny))", + " .map(function (x, i) {", + " return f(x, ys[i]);", + " });", + " };", + "", + " // scanl1 is a variant of scanl that has no starting value argument", + " // scanl1 :: (a -> a -> a) -> [a] -> [a]", + " var scanl1 = function (f, xs) {", + " return xs.length > 0 ? scanl(f, xs[0], xs.slice(1)) : [];", + " };", + "", + " // scanr1 is a variant of scanr that has no starting value argument", + " // scanr1 :: (a -> a -> a) -> [a] -> [a]", + " var scanr1 = function (f, xs) {", + " return xs.length > 0 ? scanr(f, xs.slice(-1)[0], xs.slice(0, -1)) : [];", + " };", + "", + " // scanl :: (b -> a -> b) -> b -> [a] -> [b]", + " var scanl = function (f, startValue, xs) {", + " var lst = [startValue];", + " return xs.reduce(function (a, x) {", + " var v = f(a, x);", + " return lst.push(v), v;", + " }, startValue), lst;", + " };", + "", + " // scanr :: (b -> a -> b) -> b -> [a] -> [b]", + " var scanr = function (f, startValue, xs) {", + " var lst = [startValue];", + " return xs.reduceRight(function (a, x) {", + " var v = f(a, x);", + " return lst.push(v), v;", + " }, startValue), lst.reverse();", + " };", + "", + " // sum :: (Num a) => [a] -> a", + " var sum = function (xs) {", + " return xs.reduce(function (a, x) {", + " return a + x;", + " }, 0);", + " };", + "", + " // max :: Ord a => a -> a -> a", + " var max = function (a, b) {", + " return a > b ? a : b;", + " };", + "", + " // min :: Ord a => a -> a -> a", + " var min = function (a, b) {", + " return b < a ? b : a;", + " };", + "", + " // TEST ---------------------------------------------------", + " return [", + " [1, 5, 3, 7, 2],", + " [5, 3, 7, 2, 6, 4, 5, 9, 1, 2],", + " [2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1],", + " [5, 5, 5, 5],", + " [5, 6, 7, 8],", + " [8, 7, 7, 6],", + " [6, 7, 10, 7, 6]", + " ].map(waterCollected);", + "", + " //--> [2, 14, 35, 0, 0, 0, 0]", + "})();", + "", + "{{Out}}", + "[2, 14, 35, 0, 0, 0, 0]", + "", + "===ES6===", + "{{Trans|Haskell}}", + "", + "(() => {", + " 'use strict';", + " ", + " // waterCollected :: [Int] -> Int", + " const waterCollected = xs => {", + " const maxToRight = scanr1(max, xs),", + " maxToLeft = scanl1(max, xs),", + " levels = zipWith(min, maxToLeft, maxToRight);", + "", + " return sum(zipWith(difference, levels, xs)", + " .filter(x => x > 0));", + " };", + "", + "", + " // GENERIC FUNCTIONS ----------------------------------------", + "", + " // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]", + " const zipWith = (f, xs, ys) => {", + " const ny = ys.length;", + " return (xs.length <= ny ? xs : xs.slice(0, ny))", + " .map((x, i) => f(x, ys[i]));", + " }", + "", + " // scanl1 is a variant of scanl that has no starting value argument", + " // scanl1 :: (a -> a -> a) -> [a] -> [a]", + " const scanl1 = (f, xs) =>", + " xs.length > 0 ? scanl(f, xs[0], xs.slice(1)) : [];", + "", + " // scanr1 is a variant of scanr that has no starting value argument", + " // scanr1 :: (a -> a -> a) -> [a] -> [a]", + " const scanr1 = (f, xs) =>", + " xs.length > 0 ? scanr(f, xs.slice(-1)[0], xs.slice(0, -1)) : [];", + "", + " // scanl :: (b -> a -> b) -> b -> [a] -> [b]", + " const scanl = (f, startValue, xs) => {", + " const lst = [startValue];", + " return (", + " xs.reduce((a, x) => {", + " const v = f(a, x);", + " return (lst.push(v), v);", + " }, startValue),", + " lst", + " );", + " };", + "", + " // scanr :: (b -> a -> b) -> b -> [a] -> [b]", + " const scanr = (f, startValue, xs) => {", + " const lst = [startValue];", + " return (", + " xs.reduceRight((a, x) => {", + " const v = f(a, x);", + " return (lst.push(v), v);", + " }, startValue),", + " lst.reverse()", + " );", + " };", + "", + " // difference :: (Num a) => a -> a -> a", + " const difference = (a, b) => a - b;", + "", + " // sum :: (Num a) => [a] -> a", + " const sum = xs => xs.reduce((a, x) => a + x, 0);", + "", + " // max :: Ord a => a -> a -> a", + " const max = (a, b) => a > b ? a : b;", + "", + " // min :: Ord a => a -> a -> a", + " const min = (a, b) => b < a ? b : a;", + "", + "", + " // TEST ---------------------------------------------------", + " return [", + " [1, 5, 3, 7, 2],", + " [5, 3, 7, 2, 6, 4, 5, 9, 1, 2],", + " [2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1],", + " [5, 5, 5, 5],", + " [5, 6, 7, 8],", + " [8, 7, 7, 6],", + " [6, 7, 10, 7, 6]", + " ].map(waterCollected);", + "", + " //--> [2, 14, 35, 0, 0, 0, 0]", + "})();", + "", + "{{Out}}", + "[2, 14, 35, 0, 0, 0, 0]", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc8097", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "(function () {\n 'use strict';\n\n // waterCollected :: [Int] -> Int\n var waterCollected = function (xs) {\n return sum( // water above each bar\n zipWith(function (a, b) {\n return a - b; // difference between water level and bar\n },\n zipWith(min, // lower of two flanking walls\n scanl1(max, xs), // highest walls to left\n scanr1(max, xs) // highest walls to right\n ), \n xs // tops of bars\n )\n .filter(function (x) {\n return x > 0; // only bars with water above them\n })\n );\n };\n\n // GENERIC FUNCTIONS ----------------------------------------\n\n // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]\n var zipWith = function (f, xs, ys) {\n var ny = ys.length;\n return (xs.length <= ny ? xs : xs.slice(0, ny))\n .map(function (x, i) {\n return f(x, ys[i]);\n });\n };\n\n // scanl1 is a variant of scanl that has no starting value argument\n // scanl1 :: (a -> a -> a) -> [a] -> [a]\n var scanl1 = function (f, xs) {\n return xs.length > 0 ? scanl(f, xs[0], xs.slice(1)) : [];\n };\n\n // scanr1 is a variant of scanr that has no starting value argument\n // scanr1 :: (a -> a -> a) -> [a] -> [a]\n var scanr1 = function (f, xs) {\n return xs.length > 0 ? scanr(f, xs.slice(-1)[0], xs.slice(0, -1)) : [];\n };\n\n // scanl :: (b -> a -> b) -> b -> [a] -> [b]\n var scanl = function (f, startValue, xs) {\n var lst = [startValue];\n return xs.reduce(function (a, x) {\n var v = f(a, x);\n return lst.push(v), v;\n }, startValue), lst;\n };\n\n // scanr :: (b -> a -> b) -> b -> [a] -> [b]\n var scanr = function (f, startValue, xs) {\n var lst = [startValue];\n return xs.reduceRight(function (a, x) {\n var v = f(a, x);\n return lst.push(v), v;\n }, startValue), lst.reverse();\n };\n\n // sum :: (Num a) => [a] -> a\n var sum = function (xs) {\n return xs.reduce(function (a, x) {\n return a + x;\n }, 0);\n };\n\n // max :: Ord a => a -> a -> a\n var max = function (a, b) {\n return a > b ? a : b;\n };\n\n // min :: Ord a => a -> a -> a\n var min = function (a, b) {\n return b < a ? b : a;\n };\n\n // TEST ---------------------------------------------------\n return [\n [1, 5, 3, 7, 2],\n [5, 3, 7, 2, 6, 4, 5, 9, 1, 2],\n [2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1],\n [5, 5, 5, 5],\n [5, 6, 7, 8],\n [8, 7, 7, 6],\n [6, 7, 10, 7, 6]\n ].map(waterCollected);\n\n //--> [2, 14, 35, 0, 0, 0, 0]\n})();\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + }, + { + "title": "Wireworld", + "type": "Waypoint", + "description": [ + "

Wireworld is a cellular automaton with some similarities to Conway's Game of Life.

It is capable of doing sophisticated computations with appropriate programs

", + "

(it is actually Turing complete),

", + "

and is much simpler to program for.

A Wireworld arena consists of a Cartesian grid of cells,

", + "

each of which can be in one of four states.

", + "

All cell transitions happen simultaneously.

The cell transition rules are this:

", + "

{| class=wikitable

", + "

|-

", + "

! Input State

", + "

! Output State

", + "

! Condition

", + "

|-

", + "

| empty

", + "

| empty

", + "

|

", + "

|-

", + "

| electronhead

", + "

| electrontail

", + "

|

", + "

|-

", + "

| electrontail

", + "

| conductor

", + "

|

", + "

|-

", + "

| valign=top | conductor

", + "

| valign=top | electronhead

", + "

| if 1 or 2 cells in the neighborhood of the cell are in the state “electron head

", + "

|-

", + "

| conductor

", + "

| conductor

", + "

| otherwise

", + "

|}

", + "Task:", + "

Create a program that reads a Wireworld program from a file and displays an animation of the processing. Here is a sample description file (using \"H\" for an electron head, \"t\" for a tail, \".\" for a conductor and a space for empty) you may wish to test with, which demonstrates two cycle-3 generators and an inhibit gate:

", + "
",
+      "tH.........",
+      ".   .",
+      "   ...",
+      ".   .",
+      "Ht.. ......",
+      "
", + "

While text-only implementations of this task are possible, mapping cells to pixels is advisable if you wish to be able to display large designs. The logic is not significantly more complex.

" + ], + "challengeSeed": [ + "function replaceMe (foo) {", + " // Good luck!", + " return true;", + "}" + ], + "rawSolutions": [ + "=={{header|JavaScript}}==", + "You have to search and open the file manually.
", + "This is the HTML you need to test.", + "
",
+      "",
+      "Wireworld",
+      "",
+      "",
+      "
", + "", + "var ctx, sizeW, sizeH, scl = 10, map, tmp;", + "function getNeighbour( i, j ) {", + " var ii, jj, c = 0;", + " for( var b = -1; b < 2; b++ ) {", + " for( var a = -1; a < 2; a++ ) {", + " ii = i + a; jj = j + b;", + " if( ii < 0 || ii >= sizeW || jj < 0 || jj >= sizeH ) continue;", + " if( map[ii][jj] == 1 ) c++;", + " }", + " }", + " return ( c == 1 || c == 2 );", + "}", + "function simulate() {", + " drawWorld();", + " for( var j = 0; j < sizeH; j++ ) {", + " for( var i = 0; i < sizeW; i++ ) {", + " switch( map[i][j] ) {", + " case 0: tmp[i][j] = 0; break;", + " case 1: tmp[i][j] = 2; break;", + " case 2: tmp[i][j] = 3; break;", + " case 3: ", + " if( getNeighbour( i, j ) ) tmp[i][j] = 1;", + " else tmp[i][j] = 3;", + " break;", + " }", + " }", + " }", + " [tmp, map] = [map, tmp]; ", + " setTimeout( simulate, 200 );", + "}", + "function drawWorld() {", + " ctx.fillStyle = \"#000\"; ctx.fillRect( 0, 0, sizeW * scl, sizeH * scl );", + " for( var j = 0; j < sizeH; j++ ) {", + " for( var i = 0; i < sizeW; i++ ) {", + " switch( map[i][j] ) {", + " case 0: continue;", + " case 1: ctx.fillStyle = \"#03f\"; break;", + " case 2: ctx.fillStyle = \"#f30\"; break;", + " case 3: ctx.fillStyle = \"#ff3\"; break;", + " }", + " ctx.fillRect( i, j, 1, 1 );", + " }", + " }", + "}", + "function openFile( event ) {", + " var input = event.target;", + " var reader = new FileReader();", + " reader.onload = function() {", + " createWorld( reader.result );", + " };", + " reader.readAsText(input.files[0]);", + "}", + "function createWorld( txt ) {", + " var l = txt.split( \"\\n\" );", + " sizeW = parseInt( l[0] );", + " sizeH = parseInt( l[1] );", + " map = new Array( sizeW );", + " tmp = new Array( sizeW );", + " for( var i = 0; i < sizeW; i++ ) {", + " map[i] = new Array( sizeH );", + " tmp[i] = new Array( sizeH );", + " for( var j = 0; j < sizeH; j++ ) {", + " map[i][j] = tmp[i][j] = 0;", + " }", + " }", + " var t;", + " for( var j = 0; j < sizeH; j++ ) {", + " for( var i = 0; i < sizeW; i++ ) {", + " switch( l[j + 2][i] ) {", + " case \" \": t = 0; break;", + " case \"H\": t = 1; break;", + " case \"t\": t = 2; break;", + " case \".\": t = 3; break;", + " }", + " map[i][j] = t;", + " }", + " }", + " init();", + "}", + "function init() {", + " var canvas = document.createElement( \"canvas\" );", + " canvas.width = sizeW * scl;", + " canvas.height = sizeH * scl;", + " ctx = canvas.getContext( \"2d\" );", + " ctx.scale( scl, scl );", + " document.body.appendChild( canvas );", + " simulate();", + "}", + "", + "", + "" + ], + "tail": ["const replaceThis = 3;"], + "id": "5a23c84352665b21eecc809c", + "challengeType": 5, + "releasedOn": "December 27, 2017", + "isBeta": "true", + "betaSolutions": [ + "\nvar ctx, sizeW, sizeH, scl = 10, map, tmp;\nfunction getNeighbour( i, j ) {\n var ii, jj, c = 0;\n for( var b = -1; b < 2; b++ ) {\n for( var a = -1; a < 2; a++ ) {\n ii = i + a; jj = j + b;\n if( ii < 0 || ii >= sizeW || jj < 0 || jj >= sizeH ) continue;\n if( map[ii][jj] == 1 ) c++;\n }\n }\n return ( c == 1 || c == 2 );\n}\nfunction simulate() {\n drawWorld();\n for( var j = 0; j < sizeH; j++ ) {\n for( var i = 0; i < sizeW; i++ ) {\n switch( map[i][j] ) {\n case 0: tmp[i][j] = 0; break;\n case 1: tmp[i][j] = 2; break;\n case 2: tmp[i][j] = 3; break;\n case 3: \n if( getNeighbour( i, j ) ) tmp[i][j] = 1;\n else tmp[i][j] = 3;\n break;\n }\n }\n }\n [tmp, map] = [map, tmp]; \n setTimeout( simulate, 200 );\n}\nfunction drawWorld() {\n ctx.fillStyle = \"#000\"; ctx.fillRect( 0, 0, sizeW * scl, sizeH * scl );\n for( var j = 0; j < sizeH; j++ ) {\n for( var i = 0; i < sizeW; i++ ) {\n switch( map[i][j] ) {\n case 0: continue;\n case 1: ctx.fillStyle = \"#03f\"; break;\n case 2: ctx.fillStyle = \"#f30\"; break;\n case 3: ctx.fillStyle = \"#ff3\"; break;\n }\n ctx.fillRect( i, j, 1, 1 );\n }\n }\n}\nfunction openFile( event ) {\n var input = event.target;\n var reader = new FileReader();\n reader.onload = function() {\n createWorld( reader.result );\n };\n reader.readAsText(input.files[0]);\n}\nfunction createWorld( txt ) {\n var l = txt.split( \"\\n\" );\n sizeW = parseInt( l[0] );\n sizeH = parseInt( l[1] );\n map = new Array( sizeW );\n tmp = new Array( sizeW );\n for( var i = 0; i < sizeW; i++ ) {\n map[i] = new Array( sizeH );\n tmp[i] = new Array( sizeH );\n for( var j = 0; j < sizeH; j++ ) {\n map[i][j] = tmp[i][j] = 0;\n }\n }\n var t;\n for( var j = 0; j < sizeH; j++ ) {\n for( var i = 0; i < sizeW; i++ ) {\n switch( l[j + 2][i] ) {\n case \" \": t = 0; break;\n case \"H\": t = 1; break;\n case \"t\": t = 2; break;\n case \".\": t = 3; break;\n }\n map[i][j] = t;\n }\n }\n init();\n}\nfunction init() {\n var canvas = document.createElement( \"canvas\" );\n canvas.width = sizeW * scl;\n canvas.height = sizeH * scl;\n ctx = canvas.getContext( \"2d\" );\n ctx.scale( scl, scl );\n document.body.appendChild( canvas );\n simulate();\n}\n\n" + ], + "betaTests": [ + "assert(typeof replaceMe === 'function', 'message: replaceMe is a function.');" + ] + } +]