diff --git a/config.json b/config.json index 698bace5c..aacb72eb8 100644 --- a/config.json +++ b/config.json @@ -26,7 +26,7 @@ "test/%{snake_slug}_test.clj" ], "example": [ - "src/example.clj" + ".meta/src/example.clj" ], "exemplar": [ ".meta/exemplar.clj" @@ -122,7 +122,9 @@ "sequential-destructuring" ], "prerequisites": [ - "lists", "vectors", "strings" + "lists", + "vectors", + "strings" ], "status": "beta" }, @@ -138,8 +140,13 @@ "slug": "squeaky-clean", "name": "Squeaky Clean", "uuid": "3af5b219-d751-4243-89f7-c8f05216f534", - "concepts": ["chars"], - "prerequisites": ["basics", "strings"], + "concepts": [ + "chars" + ], + "prerequisites": [ + "basics", + "strings" + ], "status": "beta" }, { @@ -154,16 +161,27 @@ "slug": "coordinate-transformation", "name": "Coordinate Transformation", "uuid": "5b23eabd-6ebb-4fed-b889-9324ad174a5f", - "concepts": ["closures", "atoms"], - "prerequisites": ["vectors"], + "concepts": [ + "closures", + "atoms" + ], + "prerequisites": [ + "vectors" + ], "status": "beta" }, { "slug": "card-games", "name": "Card Games", "uuid": "01a06d2b-ffb1-4497-9bb3-d93ee2d0931b", - "concepts": ["lists"], - "prerequisites": ["basics", "conditionals", "booleans"], + "concepts": [ + "lists" + ], + "prerequisites": [ + "basics", + "conditionals", + "booleans" + ], "status": "beta" } ], @@ -172,17 +190,24 @@ "slug": "two-fer", "name": "Two Fer", "uuid": "1706ec00-9e51-45d1-ac3e-01b0360ea950", - "practices": ["strings"], - "prerequisites": ["strings"], - "difficulty": 1, - "topics": null + "practices": [ + "strings" + ], + "prerequisites": [ + "strings" + ], + "difficulty": 1 }, { "slug": "armstrong-numbers", "name": "Armstrong Numbers", "uuid": "0e0fec77-651a-45a7-af99-a768ebebef05", - "practices": ["numbers"], - "prerequisites": ["numbers"], + "practices": [ + "numbers" + ], + "prerequisites": [ + "numbers" + ], "difficulty": 1, "topics": [ "math" @@ -204,10 +229,13 @@ "name": "Reverse String", "uuid": "0f7b1858-15d0-467d-9f94-56408249c2f7", "practices": [], - "prerequisites": ["strings"], + "prerequisites": [ + "strings" + ], "difficulty": 1, "topics": [ - "strings", "core_functions" + "strings", + "core_functions" ] }, { @@ -215,7 +243,9 @@ "name": "Accumulate", "uuid": "49f62bbc-0f60-4922-b5a6-f266b80442f4", "practices": [], - "prerequisites": ["numbers"], + "prerequisites": [ + "numbers" + ], "difficulty": 2, "topics": [ "algorithms, core_functions" @@ -225,19 +255,30 @@ "slug": "acronym", "name": "Acronym", "uuid": "b99ed7da-98a8-43f0-8162-05c5408f6ac5", - "practices": ["strings"], - "prerequisites": ["strings", "booleans"], + "practices": [ + "strings" + ], + "prerequisites": [ + "strings", + "booleans" + ], "difficulty": 2, "topics": [ - "strings", "regular_expressions" + "strings", + "regular_expressions" ] }, { "slug": "all-your-base", "name": "All Your Base", "uuid": "7b8c5f7e-3c7d-4e69-ba8c-f29bb492a628", - "practices": ["numbers"], - "prerequisites": ["numbers", "vectors"], + "practices": [ + "numbers" + ], + "prerequisites": [ + "numbers", + "vectors" + ], "difficulty": 2, "topics": [ "math" @@ -247,8 +288,13 @@ "slug": "anagram", "name": "Anagram", "uuid": "11818959-7e42-4a1d-8dfd-288cea744d66", - "practices": ["strings"], - "prerequisites": ["strings", "vectors"], + "practices": [ + "strings" + ], + "prerequisites": [ + "strings", + "vectors" + ], "difficulty": 2, "topics": [ "strings" @@ -258,19 +304,31 @@ "slug": "bob", "name": "Bob", "uuid": "0317cc62-dd75-4841-86c3-01c055630fe7", - "practices": ["conditionals"], - "prerequisites": ["conditionals", "strings"], + "practices": [ + "conditionals" + ], + "prerequisites": [ + "conditionals", + "strings" + ], "difficulty": 2, "topics": [ - "strings", "regular_expressions", "conditionals" + "strings", + "regular_expressions", + "conditionals" ] }, { "slug": "collatz-conjecture", "name": "Collatz Conjecture", "uuid": "9516323c-721e-4bfc-84df-9bc32e467197", - "practices": ["numbers"], - "prerequisites": ["numbers", "conditionals"], + "practices": [ + "numbers" + ], + "prerequisites": [ + "numbers", + "conditionals" + ], "difficulty": 2, "topics": [ "math" @@ -280,8 +338,12 @@ "slug": "complex-numbers", "name": "Complex Numbers", "uuid": "ceaacb97-9c2c-43db-a9ac-28ebe6650f47", - "practices": ["numbers"], - "prerequisites": ["numbers"], + "practices": [ + "numbers" + ], + "prerequisites": [ + "numbers" + ], "difficulty": 2, "topics": [ "math" @@ -292,10 +354,15 @@ "name": "ETL", "uuid": "befca7ee-fc29-4ef0-afd7-2d3f68aa47fb", "practices": [], - "prerequisites": ["lists", "numbers", "strings"], + "prerequisites": [ + "lists", + "numbers", + "strings" + ], "difficulty": 2, "topics": [ - "integers", "maps" + "integers", + "maps" ] }, { @@ -303,18 +370,27 @@ "name": "Hamming", "uuid": "d120ad9a-98e9-4de7-9cb6-6aef3101cd1c", "practices": [], - "prerequisites": ["numbers", "strings", "conditionals"], + "prerequisites": [ + "numbers", + "strings", + "conditionals" + ], "difficulty": 2, "topics": [ - "strings", "conditionals" + "strings", + "conditionals" ] }, { "slug": "nth-prime", "name": "Nth Prime", "uuid": "167113f2-b015-4c04-809d-670193758c25", - "practices": ["numbers"], - "prerequisites": ["numbers"], + "practices": [ + "numbers" + ], + "prerequisites": [ + "numbers" + ], "difficulty": 2, "topics": [ "math" @@ -325,40 +401,61 @@ "name": "Nucleotide Count", "uuid": "223d10d6-539d-441f-89ba-77f7743e6092", "practices": [], - "prerequisites": ["strings", "conditionals"], + "prerequisites": [ + "strings", + "conditionals" + ], "difficulty": 2, "topics": [ - "strings", "conditionals", "exception_handling" + "strings", + "conditionals", + "exception_handling" ] }, { "slug": "pangram", "name": "Pangram", "uuid": "1f96161b-c83a-4f66-bc50-3e32e035da1f", - "practices": ["strings"], - "prerequisites": ["strings", "booleans"], + "practices": [ + "strings" + ], + "prerequisites": [ + "strings", + "booleans" + ], "difficulty": 2, "topics": [ - "strings", "maps" + "strings", + "maps" ] }, { "slug": "pig-latin", "name": "Pig Latin", "uuid": "a9b08dfd-3555-46bc-bc54-d605fd225c34", - "practices": ["strings"], - "prerequisites": ["strings"], + "practices": [ + "strings" + ], + "prerequisites": [ + "strings" + ], "difficulty": 2, "topics": [ - "strings", "regular_expressions" + "strings", + "regular_expressions" ] }, { "slug": "protein-translation", "name": "Protein Translation", "uuid": "591c3cc5-0d14-400d-85a2-4ce0e399813e", - "practices": ["strings"], - "prerequisites": ["strings", "vectors"], + "practices": [ + "strings" + ], + "prerequisites": [ + "strings", + "vectors" + ], "difficulty": 2, "topics": [ "pattern_matching", @@ -369,11 +466,19 @@ "slug": "raindrops", "name": "Raindrops", "uuid": "e670c978-8b71-4880-a543-3f9fb28d88b3", - "practices": ["conditionals"], - "prerequisites": ["numbers", "strings", "conditionals"], + "practices": [ + "conditionals" + ], + "prerequisites": [ + "numbers", + "strings", + "conditionals" + ], "difficulty": 2, "topics": [ - "integers", "strings", "conditionals" + "integers", + "strings", + "conditionals" ] }, { @@ -381,10 +486,13 @@ "name": "RNA Transcription", "uuid": "d8773153-d717-43f1-9324-c7e8cf00455c", "practices": [], - "prerequisites": ["strings"], + "prerequisites": [ + "strings" + ], "difficulty": 2, "topics": [ - "strings", "pattern_matching" + "strings", + "pattern_matching" ] }, { @@ -392,10 +500,16 @@ "name": "Robot Name", "uuid": "ce7df719-d3e2-444f-8ae3-f81c89fd15ce", "practices": [], - "prerequisites": ["numbers", "strings"], + "prerequisites": [ + "numbers", + "strings" + ], "difficulty": 2, "topics": [ - "sets", "conditionals", "regular_expressions", "randomness" + "sets", + "conditionals", + "regular_expressions", + "randomness" ] }, { @@ -403,7 +517,10 @@ "name": "Roman Numerals", "uuid": "cad43fab-50c2-470e-8364-6592e971d4df", "practices": [], - "prerequisites": ["numbers", "strings"], + "prerequisites": [ + "numbers", + "strings" + ], "difficulty": 2, "topics": [ "conditionals" @@ -414,10 +531,14 @@ "name": "Rotational Cipher", "uuid": "a40e8d4b-9793-4991-87d8-7efb92a3e3f2", "practices": [], - "prerequisites": ["numbers", "strings"], + "prerequisites": [ + "numbers", + "strings" + ], "difficulty": 2, "topics": [ - "algorithms", "regular_expressions" + "algorithms", + "regular_expressions" ] }, { @@ -425,10 +546,15 @@ "name": "Run-Length Encoding", "uuid": "fa1be98f-59b2-487e-948d-46e744d50dc4", "practices": [], - "prerequisites": ["numbers", "strings"], + "prerequisites": [ + "numbers", + "strings" + ], "difficulty": 2, "topics": [ - "strings", "regular_expressions", "parsing" + "strings", + "regular_expressions", + "parsing" ] }, { @@ -436,10 +562,14 @@ "name": "Scrabble Score", "uuid": "2804d2d1-0029-4473-8431-0857d4767d91", "practices": [], - "prerequisites": ["numbers", "strings"], + "prerequisites": [ + "numbers", + "strings" + ], "difficulty": 2, "topics": [ - "maps", "strings" + "maps", + "strings" ] }, { @@ -447,10 +577,15 @@ "name": "Secret Handshake", "uuid": "9c270d52-b1fe-4f1a-a639-2f7347c7cb92", "practices": [], - "prerequisites": ["numbers", "vectors", "strings"], + "prerequisites": [ + "numbers", + "vectors", + "strings" + ], "difficulty": 2, "topics": [ - "algorithms", "conditionals" + "algorithms", + "conditionals" ] }, { @@ -458,7 +593,10 @@ "name": "Series", "uuid": "f342d3f2-775f-4fb6-93c2-9aea4a8f5f22", "practices": [], - "prerequisites": ["numbers", "vectors"], + "prerequisites": [ + "numbers", + "vectors" + ], "difficulty": 2, "topics": [ "strings" @@ -468,8 +606,13 @@ "slug": "space-age", "name": "Space Age", "uuid": "c97868e9-36ca-4d00-9483-0fc6b4c37231", - "practices": ["floating-point-numbers"], - "prerequisites": ["numbers", "floating-point-numbers"], + "practices": [ + "floating-point-numbers" + ], + "prerequisites": [ + "numbers", + "floating-point-numbers" + ], "difficulty": 2, "topics": [ "math" @@ -480,18 +623,27 @@ "name": "Strain", "uuid": "8db4904c-a46f-4886-b214-0cf06b0f2ff1", "practices": [], - "prerequisites": ["conditionals", "numbers"], + "prerequisites": [ + "conditionals", + "numbers" + ], "difficulty": 2, "topics": [ - "algorithms", "conditionals", "filtering" + "algorithms", + "conditionals", + "filtering" ] }, { "slug": "sublist", "name": "Sublist", "uuid": "85dc1645-8424-45f2-8653-bc9730887b40", - "practices": ["lists"], - "prerequisites": ["lists"], + "practices": [ + "lists" + ], + "prerequisites": [ + "lists" + ], "difficulty": 2, "topics": [ "sets" @@ -502,7 +654,10 @@ "name": "Sum of Multiples", "uuid": "357de34a-c149-4a2c-b6a8-86ffb5eaa152", "practices": [], - "prerequisites": ["numbers", "conditionals"], + "prerequisites": [ + "numbers", + "conditionals" + ], "difficulty": 2, "topics": [ "math" @@ -512,11 +667,18 @@ "slug": "triangle", "name": "Triangle", "uuid": "a148a999-76ef-40d4-8bf7-96d6ae38876e", - "practices": ["floating-point-numbers", "conditionals"], - "prerequisites": ["floating-point-numbers", "conditionals"], + "practices": [ + "floating-point-numbers", + "conditionals" + ], + "prerequisites": [ + "floating-point-numbers", + "conditionals" + ], "difficulty": 2, "topics": [ - "integers", "conditionals" + "integers", + "conditionals" ] }, { @@ -524,10 +686,15 @@ "name": "Word Count", "uuid": "ea3cf3f6-35de-4da1-a74f-b7a13d89c39a", "practices": [], - "prerequisites": ["numbers", "conditionals", "strings"], + "prerequisites": [ + "numbers", + "conditionals", + "strings" + ], "difficulty": 2, "topics": [ - "regular_expressions", "strings" + "regular_expressions", + "strings" ] }, { @@ -535,10 +702,15 @@ "name": "Atbash Cipher", "uuid": "7d37e817-d2b7-4554-8885-b02d57d1d788", "practices": [], - "prerequisites": ["numbers", "conditionals", "strings"], + "prerequisites": [ + "numbers", + "conditionals", + "strings" + ], "difficulty": 3, "topics": [ - "algorithms", "regular_expressions" + "algorithms", + "regular_expressions" ] }, { @@ -546,10 +718,15 @@ "name": "Beer Song", "uuid": "56a4b06b-c48f-4a0f-883a-a08886472b56", "practices": [], - "prerequisites": ["numbers", "conditionals", "strings"], + "prerequisites": [ + "numbers", + "conditionals", + "strings" + ], "difficulty": 3, "topics": [ - "strings", "conditionals" + "strings", + "conditionals" ] }, { @@ -557,7 +734,9 @@ "name": "Binary", "uuid": "daf3daed-61ef-4964-8d33-e7a739c7a470", "practices": [], - "prerequisites": ["numbers"], + "prerequisites": [ + "numbers" + ], "difficulty": 3, "topics": [ "math" @@ -568,10 +747,14 @@ "name": "Binary Search", "uuid": "f32c6a4b-0f23-4cd2-95b2-f6e70e4b40b1", "practices": [], - "prerequisites": ["vectors"], + "prerequisites": [ + "vectors" + ], "difficulty": 3, "topics": [ - "algorithms", "recursion", "conditionals" + "algorithms", + "recursion", + "conditionals" ] }, { @@ -579,10 +762,13 @@ "name": "Binary Search Tree", "uuid": "53678d3d-de3f-483d-9f02-d2313290786d", "practices": [], - "prerequisites": ["vectors"], + "prerequisites": [ + "vectors" + ], "difficulty": 3, "topics": [ - "algorithms", "recursion" + "algorithms", + "recursion" ] }, { @@ -590,7 +776,10 @@ "name": "Change", "uuid": "7945eb6a-20eb-489d-90bd-020df3d9e2cb", "practices": [], - "prerequisites": ["numbers", "vectors"], + "prerequisites": [ + "numbers", + "vectors" + ], "difficulty": 3, "topics": [ "algorithms" @@ -601,10 +790,13 @@ "name": "Flatten Array", "uuid": "6b81cf43-e071-4daf-89a9-d10e213a5751", "practices": [], - "prerequisites": ["vectors"], + "prerequisites": [ + "vectors" + ], "difficulty": 3, "topics": [ - "core_functions", "seqs" + "core_functions", + "seqs" ] }, { @@ -612,7 +804,9 @@ "name": "Gigasecond", "uuid": "798445d8-acad-4b01-b471-3809f46a8a84", "practices": [], - "prerequisites": ["numbers"], + "prerequisites": [ + "numbers" + ], "difficulty": 3, "topics": [ "time" @@ -623,10 +817,14 @@ "name": "Grade School", "uuid": "a48ff289-baf0-4b13-a5aa-78f6ee91571b", "practices": [], - "prerequisites": ["numbers", "strings"], + "prerequisites": [ + "numbers", + "strings" + ], "difficulty": 3, "topics": [ - "maps", "core_functions" + "maps", + "core_functions" ] }, { @@ -634,10 +832,13 @@ "name": "Grains", "uuid": "2e57c7d4-d887-4dba-8483-60e026bdf5ea", "practices": [], - "prerequisites": ["numbers"], + "prerequisites": [ + "numbers" + ], "difficulty": 3, "topics": [ - "integers", "recursion" + "integers", + "recursion" ] }, { @@ -645,7 +846,9 @@ "name": "Hexadecimal", "uuid": "a4b1b39a-d942-4921-9b67-2bd913ff52a0", "practices": [], - "prerequisites": ["numbers"], + "prerequisites": [ + "numbers" + ], "difficulty": 3, "topics": [ "math" @@ -656,21 +859,31 @@ "name": "ISBN Verifier", "uuid": "0479e73c-acb3-4a36-949c-a2065bfb57e5", "practices": [], - "prerequisites": ["strings", "booleans"], + "prerequisites": [ + "strings", + "booleans" + ], "difficulty": 3, "topics": [ - "regular_expressions", "conditionals" + "regular_expressions", + "conditionals" ] }, { "slug": "isogram", "name": "Isogram", "uuid": "ced9928a-05dc-4afa-9645-a2f2e548fe6e", - "practices": ["strings"], - "prerequisites": ["strings", "booleans"], + "practices": [ + "strings" + ], + "prerequisites": [ + "strings", + "booleans" + ], "difficulty": 3, "topics": [ - "filtering", "strings" + "filtering", + "strings" ] }, { @@ -678,10 +891,13 @@ "name": "Kindergarten Garden", "uuid": "e40c52a7-9509-4a4d-9ad6-8ca7a3bdca1d", "practices": [], - "prerequisites": ["strings"], + "prerequisites": [ + "strings" + ], "difficulty": 3, "topics": [ - "strings", "conditionals" + "strings", + "conditionals" ] }, { @@ -689,10 +905,14 @@ "name": "Leap", "uuid": "336aa5ec-f868-4a8a-9fd2-989b6c2fd0be", "practices": [], - "prerequisites": ["conditionals", "numbers"], + "prerequisites": [ + "conditionals", + "numbers" + ], "difficulty": 3, "topics": [ - "integers", "conditionals" + "integers", + "conditionals" ] }, { @@ -700,7 +920,9 @@ "name": "Pascal's Triangle", "uuid": "29b16274-b413-4231-a1c7-aff8f93c9b7e", "practices": [], - "prerequisites": ["numbers"], + "prerequisites": [ + "numbers" + ], "difficulty": 3, "topics": [ "math" @@ -711,7 +933,9 @@ "name": "Perfect Numbers", "uuid": "e10b7063-75ac-46d6-848c-c50db87bddc7", "practices": [], - "prerequisites": ["numbers"], + "prerequisites": [ + "numbers" + ], "difficulty": 3, "topics": [ "math" @@ -722,7 +946,9 @@ "name": "Phone Number", "uuid": "41b95380-2bba-407b-b400-7d8a627f18fa", "practices": [], - "prerequisites": ["strings"], + "prerequisites": [ + "strings" + ], "difficulty": 3, "topics": [ "parsing" @@ -733,7 +959,9 @@ "name": "Prime Factors", "uuid": "96005f0f-5153-4915-9f28-326b41b63fab", "practices": [], - "prerequisites": ["numbers"], + "prerequisites": [ + "numbers" + ], "difficulty": 3, "topics": [ "math" @@ -744,21 +972,36 @@ "name": "Proverb", "uuid": "540d93a9-707f-4043-b46c-1dc83f2d50d8", "practices": [], - "prerequisites": ["strings", "vectors"], + "prerequisites": [ + "strings", + "vectors" + ], "difficulty": 3, "topics": [ - "vectors", "strings", "conditionals" + "vectors", + "strings", + "conditionals" ] }, { "slug": "say", "name": "Say", "uuid": "0ff7efbe-855e-4a81-9b64-f07d1557813f", - "practices": ["numbers", "strings", "conditionals"], - "prerequisites": ["numbers", "strings", "conditionals"], + "practices": [ + "numbers", + "strings", + "conditionals" + ], + "prerequisites": [ + "numbers", + "strings", + "conditionals" + ], "difficulty": 3, "topics": [ - "strings", "integers", "exception_handling" + "strings", + "integers", + "exception_handling" ] }, { @@ -766,7 +1009,10 @@ "name": "Trinary", "uuid": "f8a7f5eb-e317-4ffa-bdef-6e30a36511eb", "practices": [], - "prerequisites": ["numbers", "strings"], + "prerequisites": [ + "numbers", + "strings" + ], "difficulty": 3, "topics": [ "math" @@ -777,7 +1023,10 @@ "name": "Allergies", "uuid": "a71bc471-8359-4019-8ad1-e456774388b7", "practices": [], - "prerequisites": ["vectors", "booleans"], + "prerequisites": [ + "vectors", + "booleans" + ], "difficulty": 4, "topics": [ "conditionals" @@ -788,18 +1037,26 @@ "name": "Crypto Square", "uuid": "7387b271-d765-497c-9b85-481c947439b6", "practices": [], - "prerequisites": ["strings"], + "prerequisites": [ + "strings" + ], "difficulty": 4, "topics": [ - "algorithms", "sorting", "regular_expressions" + "algorithms", + "sorting", + "regular_expressions" ] }, { "slug": "difference-of-squares", "name": "Difference of Squares", "uuid": "6f69d8fe-9da2-48f9-a635-b9f54b626daf", - "practices": ["numbers"], - "prerequisites": ["numbers"], + "practices": [ + "numbers" + ], + "prerequisites": [ + "numbers" + ], "difficulty": 4, "topics": [ "math" @@ -810,18 +1067,27 @@ "name": "Dominoes", "uuid": "da04dfa4-5a66-49a5-a7ca-6320cfa4158f", "practices": [], - "prerequisites": ["numbers", "booleans"], + "prerequisites": [ + "numbers", + "booleans" + ], "difficulty": 4, "topics": [ - "graph_theory", "games" + "graph_theory", + "games" ] }, { "slug": "largest-series-product", "name": "Largest Series Product", "uuid": "2978747b-86e6-48f0-aef2-2d00714c8c5e", - "practices": ["numbers"], - "prerequisites": ["numbers", "strings"], + "practices": [ + "numbers" + ], + "prerequisites": [ + "numbers", + "strings" + ], "difficulty": 4, "topics": [ "math" @@ -832,18 +1098,25 @@ "name": "Meetup", "uuid": "81e37fc7-13cd-46a9-987c-c9bda4ff1ead", "practices": [], - "prerequisites": ["numbers"], + "prerequisites": [ + "numbers" + ], "difficulty": 4, "topics": [ - "dates", "time" + "dates", + "time" ] }, { "slug": "octal", "name": "Octal", "uuid": "fa596153-0cbe-40e9-a4d6-1a66fe6ef7e5", - "practices": ["numbers"], - "prerequisites": ["numbers"], + "practices": [ + "numbers" + ], + "prerequisites": [ + "numbers" + ], "difficulty": 4, "topics": [ "math" @@ -854,7 +1127,11 @@ "name": "Spiral Matrix", "uuid": "71d92de0-9f54-4e07-9a8f-fcd477f00219", "practices": [], - "prerequisites": ["vectors", "numbers", "conditionals"], + "prerequisites": [ + "vectors", + "numbers", + "conditionals" + ], "difficulty": 4, "topics": [ "recursivity" @@ -865,10 +1142,13 @@ "name": "Clock", "uuid": "83b7ffc2-aadd-4c26-9794-5e7f851eea8b", "practices": [], - "prerequisites": ["numbers"], + "prerequisites": [ + "numbers" + ], "difficulty": 5, "topics": [ - "dates", "time" + "dates", + "time" ] }, { @@ -876,7 +1156,9 @@ "name": "Diamond", "uuid": "cc0d15ad-d562-458c-8d05-4b213693cfb9", "practices": [], - "prerequisites": ["strings"], + "prerequisites": [ + "strings" + ], "difficulty": 5, "topics": [ "transforming" @@ -887,10 +1169,14 @@ "name": "Luhn", "uuid": "e2d0287c-2fe9-4f46-abfb-4db855d7489b", "practices": [], - "prerequisites": ["numbers", "strings"], + "prerequisites": [ + "numbers", + "strings" + ], "difficulty": 5, "topics": [ - "integers", "conditionals" + "integers", + "conditionals" ] }, { @@ -898,7 +1184,10 @@ "name": "Sieve", "uuid": "0e87bb30-3e7e-49dc-9f80-2d291dfb0111", "practices": [], - "prerequisites": ["vectors", "numbers"], + "prerequisites": [ + "vectors", + "numbers" + ], "difficulty": 5, "topics": [ "math" @@ -908,22 +1197,36 @@ "slug": "robot-simulator", "name": "Robot Simulator", "uuid": "e69ecf2e-8629-4d20-a90f-6de7536247ce", - "practices": ["conditionals"], - "prerequisites": ["conditionals"], + "practices": [ + "conditionals" + ], + "prerequisites": [ + "conditionals" + ], "difficulty": 6, "topics": [ - "strings", "conditionals" + "strings", + "conditionals" ] }, { "slug": "wordy", "name": "Wordy", "uuid": "5528f567-2b5b-498a-b166-984b2c90f6a5", - "practices": ["numbers", "strings", "conditionals"], - "prerequisites": ["numbers", "strings", "conditionals"], + "practices": [ + "numbers", + "strings", + "conditionals" + ], + "prerequisites": [ + "numbers", + "strings", + "conditionals" + ], "difficulty": 6, "topics": [ - "regular_expressions", "parsing" + "regular_expressions", + "parsing" ] }, { @@ -931,7 +1234,10 @@ "name": "Bank Account", "uuid": "d67a7a46-050c-4472-84bd-2e216079a452", "practices": [], - "prerequisites": ["conditionals", "numbers"], + "prerequisites": [ + "conditionals", + "numbers" + ], "difficulty": 7, "topics": [ "conditionals" @@ -942,7 +1248,10 @@ "name": "Matching Brackets", "uuid": "86f005c6-1754-4907-becb-a0997fd52d05", "practices": [], - "prerequisites": ["strings", "booleans"], + "prerequisites": [ + "strings", + "booleans" + ], "difficulty": 7, "topics": [ "parsing" @@ -953,10 +1262,15 @@ "name": "Minesweeper", "uuid": "e07e545c-997f-424b-b4ca-34fd7cc06bf7", "practices": [], - "prerequisites": ["vectors", "conditionals", "strings"], + "prerequisites": [ + "vectors", + "conditionals", + "strings" + ], "difficulty": 7, "topics": [ - "algorithms", "games" + "algorithms", + "games" ] }, { @@ -964,7 +1278,10 @@ "name": "Poker", "uuid": "f842d531-e2a1-4573-90c3-b77177df4787", "practices": [], - "prerequisites": ["conditionals", "strings"], + "prerequisites": [ + "conditionals", + "strings" + ], "difficulty": 7, "topics": [ "games" @@ -975,10 +1292,15 @@ "name": "Queen Attack", "uuid": "edd7932d-50a6-4350-b945-2bb8a8c891c7", "practices": [], - "prerequisites": ["booleans", "conditionals", "numbers"], + "prerequisites": [ + "booleans", + "conditionals", + "numbers" + ], "difficulty": 7, "topics": [ - "equality", "conditionals" + "equality", + "conditionals" ] }, { @@ -986,7 +1308,9 @@ "name": "Go Counting", "uuid": "f0210181-7fe5-49f9-9036-be4256612b3e", "practices": [], - "prerequisites": ["strings"], + "prerequisites": [ + "strings" + ], "difficulty": 9, "topics": [ "games" @@ -997,7 +1321,10 @@ "name": "POV", "uuid": "ca557f64-9e2d-4ab0-8788-4133764ef703", "practices": [], - "prerequisites": ["strings", "vectors"], + "prerequisites": [ + "strings", + "vectors" + ], "difficulty": 10, "topics": [ "conditionals" @@ -1008,7 +1335,10 @@ "name": "Yacht", "uuid": "459c8468-efc4-46a6-bbc0-9937167827a7", "practices": [], - "prerequisites": ["strings", "vectors"], + "prerequisites": [ + "strings", + "vectors" + ], "difficulty": 5, "topics": [ "conditionals" @@ -1019,11 +1349,26 @@ "name": "Zipper", "uuid": "331b2960-baae-4331-a462-a434fd6e8767", "practices": [], - "prerequisites": ["strings", "vectors"], + "prerequisites": [ + "strings", + "vectors" + ], "difficulty": 9, "topics": [ "conditionals" ] + }, + { + "slug": "list-ops", + "name": "List Ops", + "uuid": "699fb4ec-210d-454d-a41a-f7014abf8423", + "practices": [], + "prerequisites": [ + "lists", + "closures" + ], + "difficulty": 5, + "status": "wip" } ] }, @@ -1127,14 +1472,14 @@ } ], "tags": [ + "execution_mode/compiled", "paradigm/declarative", "paradigm/functional", - "typing/dynamic", - "execution_mode/compiled", - "platform/windows", - "platform/mac", "platform/linux", + "platform/mac", + "platform/windows", "runtime/jvm", + "typing/dynamic", "used_for/artificial_intelligence", "used_for/backends", "used_for/cross_platform_development", diff --git a/exercises/practice/list-ops/.docs/instructions.append.md b/exercises/practice/list-ops/.docs/instructions.append.md new file mode 100644 index 000000000..e226d470a --- /dev/null +++ b/exercises/practice/list-ops/.docs/instructions.append.md @@ -0,0 +1,8 @@ +# Instructions append + +## Implementation tips + +- The instructions use lists because they are synced with a shared repository to maintain consistency across tracks. + However, for this exercise in the Clojure track, you should assume that you are working with vectors instead of lists. +- It is important not to reuse existing Clojure built-in functions with similar functionality, as doing so would diminish the intended learning value of the exercise. + Some of these functions include `into`, `concat`, `cat`, `lazy-cat`, `mapcat`, `flatten`, `filter`, `filterv`, `remove`, `count`, `map`, `mapv`, `reduce`, `transduce`, `reverse`, and `rseq` from the **clojure.core** namespace. diff --git a/exercises/practice/list-ops/.docs/instructions.md b/exercises/practice/list-ops/.docs/instructions.md new file mode 100644 index 000000000..ebc5dffed --- /dev/null +++ b/exercises/practice/list-ops/.docs/instructions.md @@ -0,0 +1,19 @@ +# Instructions + +Implement basic list operations. + +In functional languages list operations like `length`, `map`, and `reduce` are very common. +Implement a series of basic list operations, without using existing functions. + +The precise number and names of the operations to be implemented will be track dependent to avoid conflicts with existing names, but the general operations you will implement include: + +- `append` (_given two lists, add all items in the second list to the end of the first list_); +- `concatenate` (_given a series of lists, combine all items in all lists into one flattened list_); +- `filter` (_given a predicate and a list, return the list of all items for which `predicate(item)` is True_); +- `length` (_given a list, return the total number of items within it_); +- `map` (_given a function and a list, return the list of the results of applying `function(item)` on all items_); +- `foldl` (_given a function, a list, and initial accumulator, fold (reduce) each item into the accumulator from the left_); +- `foldr` (_given a function, a list, and an initial accumulator, fold (reduce) each item into the accumulator from the right_); +- `reverse` (_given a list, return a list with all the original items, but in reversed order_). + +Note, the ordering in which arguments are passed to the fold functions (`foldl`, `foldr`) is significant. diff --git a/exercises/practice/list-ops/.meta/config.json b/exercises/practice/list-ops/.meta/config.json new file mode 100644 index 000000000..1035f4f39 --- /dev/null +++ b/exercises/practice/list-ops/.meta/config.json @@ -0,0 +1,21 @@ +{ + "authors": [ + "bobbicodes" + ], + "contributors": [ + "kahgoh", + "tasxatzial" + ], + "files": { + "solution": [ + "src/list_ops.clj" + ], + "test": [ + "test/list_ops_test.clj" + ], + "example": [ + ".meta/src/example.clj" + ] + }, + "blurb": "Implement basic list operations." +} diff --git a/exercises/practice/list-ops/.meta/src/example.clj b/exercises/practice/list-ops/.meta/src/example.clj new file mode 100644 index 000000000..c4bc083f6 --- /dev/null +++ b/exercises/practice/list-ops/.meta/src/example.clj @@ -0,0 +1,34 @@ +(ns list-ops) + +(defn foldl [f coll init] + (loop [acc init l coll] + (cond + (empty? l) acc + :else (recur (f acc (first l)) (rest l))))) + +(defn append [coll1 coll2] + (list-ops/foldl (fn [acc elem] (conj acc elem)) coll2 coll1)) + +(defn concatenate [coll] + (cond + (empty? coll) [] + :else (list-ops/foldl (fn [acc elem] (list-ops/append acc elem)) (rest coll) (first coll)))) + +(defn select-if [pred coll] + (loop [acc [] l coll] + (cond + (empty? l) acc + (pred (first l)) (recur (conj acc (first l)) (rest l)) + :else (recur acc (rest l))))) + +(defn length [coll] + (list-ops/foldl (fn [acc elem] (+ acc 1)) coll 0)) + +(defn apply-to-each [f coll] + (list-ops/foldl (fn [acc elem] (conj acc (f elem))) coll [])) + +(defn reverse-order [coll] + (list-ops/foldl (fn [acc elem] (cons elem acc)) coll [])) + +(defn foldr [f coll init] + (list-ops/foldl f (list-ops/reverse-order coll) init)) diff --git a/exercises/practice/list-ops/.meta/tests.toml b/exercises/practice/list-ops/.meta/tests.toml new file mode 100644 index 000000000..08b1edc04 --- /dev/null +++ b/exercises/practice/list-ops/.meta/tests.toml @@ -0,0 +1,106 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[485b9452-bf94-40f7-a3db-c3cf4850066a] +description = "append entries to a list and return the new list -> empty lists" + +[2c894696-b609-4569-b149-8672134d340a] +description = "append entries to a list and return the new list -> list to empty list" + +[e842efed-3bf6-4295-b371-4d67a4fdf19c] +description = "append entries to a list and return the new list -> empty list to list" + +[71dcf5eb-73ae-4a0e-b744-a52ee387922f] +description = "append entries to a list and return the new list -> non-empty lists" + +[28444355-201b-4af2-a2f6-5550227bde21] +description = "concatenate a list of lists -> empty list" + +[331451c1-9573-42a1-9869-2d06e3b389a9] +description = "concatenate a list of lists -> list of lists" + +[d6ecd72c-197f-40c3-89a4-aa1f45827e09] +description = "concatenate a list of lists -> list of nested lists" + +[0524fba8-3e0f-4531-ad2b-f7a43da86a16] +description = "filter list returning only values that satisfy the filter function -> empty list" + +[88494bd5-f520-4edb-8631-88e415b62d24] +description = "filter list returning only values that satisfy the filter function -> non-empty list" + +[1cf0b92d-8d96-41d5-9c21-7b3c37cb6aad] +description = "returns the length of a list -> empty list" + +[d7b8d2d9-2d16-44c4-9a19-6e5f237cb71e] +description = "returns the length of a list -> non-empty list" + +[c0bc8962-30e2-4bec-9ae4-668b8ecd75aa] +description = "return a list of elements whose values equal the list value transformed by the mapping function -> empty list" + +[11e71a95-e78b-4909-b8e4-60cdcaec0e91] +description = "return a list of elements whose values equal the list value transformed by the mapping function -> non-empty list" + +[613b20b7-1873-4070-a3a6-70ae5f50d7cc] +description = "folds (reduces) the given list from the left with a function -> empty list" +include = false + +[e56df3eb-9405-416a-b13a-aabb4c3b5194] +description = "folds (reduces) the given list from the left with a function -> direction independent function applied to non-empty list" +include = false + +[d2cf5644-aee1-4dfc-9b88-06896676fe27] +description = "folds (reduces) the given list from the left with a function -> direction dependent function applied to non-empty list" +include = false + +[36549237-f765-4a4c-bfd9-5d3a8f7b07d2] +description = "folds (reduces) the given list from the left with a function -> empty list" +reimplements = "613b20b7-1873-4070-a3a6-70ae5f50d7cc" + +[7a626a3c-03ec-42bc-9840-53f280e13067] +description = "folds (reduces) the given list from the left with a function -> direction independent function applied to non-empty list" +reimplements = "e56df3eb-9405-416a-b13a-aabb4c3b5194" + +[d7fcad99-e88e-40e1-a539-4c519681f390] +description = "folds (reduces) the given list from the left with a function -> direction dependent function applied to non-empty list" +reimplements = "d2cf5644-aee1-4dfc-9b88-06896676fe27" + +[aeb576b9-118e-4a57-a451-db49fac20fdc] +description = "folds (reduces) the given list from the right with a function -> empty list" +include = false + +[c4b64e58-313e-4c47-9c68-7764964efb8e] +description = "folds (reduces) the given list from the right with a function -> direction independent function applied to non-empty list" +include = false + +[be396a53-c074-4db3-8dd6-f7ed003cce7c] +description = "folds (reduces) the given list from the right with a function -> direction dependent function applied to non-empty list" +include = false + +[17214edb-20ba-42fc-bda8-000a5ab525b0] +description = "folds (reduces) the given list from the right with a function -> empty list" +reimplements = "aeb576b9-118e-4a57-a451-db49fac20fdc" + +[e1c64db7-9253-4a3d-a7c4-5273b9e2a1bd] +description = "folds (reduces) the given list from the right with a function -> direction independent function applied to non-empty list" +reimplements = "c4b64e58-313e-4c47-9c68-7764964efb8e" + +[8066003b-f2ff-437e-9103-66e6df474844] +description = "folds (reduces) the given list from the right with a function -> direction dependent function applied to non-empty list" +reimplements = "be396a53-c074-4db3-8dd6-f7ed003cce7c" + +[94231515-050e-4841-943d-d4488ab4ee30] +description = "reverse the elements of the list -> empty list" + +[fcc03d1e-42e0-4712-b689-d54ad761f360] +description = "reverse the elements of the list -> non-empty list" + +[40872990-b5b8-4cb8-9085-d91fc0d05d26] +description = "reverse the elements of the list -> list of lists is not flattened" diff --git a/exercises/practice/list-ops/deps.edn b/exercises/practice/list-ops/deps.edn new file mode 100644 index 000000000..561c3e2da --- /dev/null +++ b/exercises/practice/list-ops/deps.edn @@ -0,0 +1,6 @@ +{:aliases {:test {:extra-paths ["test"] + :extra-deps {io.github.cognitect-labs/test-runner + {:git/url "https://github.com/cognitect-labs/test-runner.git" + :sha "705ad25bbf0228b1c38d0244a36001c2987d7337"}} + :main-opts ["-m" "cognitect.test-runner"] + :exec-fn cognitect.test-runner.api/test}}} \ No newline at end of file diff --git a/exercises/practice/list-ops/project.clj b/exercises/practice/list-ops/project.clj new file mode 100644 index 000000000..31eb1b1b7 --- /dev/null +++ b/exercises/practice/list-ops/project.clj @@ -0,0 +1,4 @@ +(defproject list-ops "0.1.0-SNAPSHOT" + :description "list-ops exercise." + :url "https://github.com/exercism/clojure/tree/main/exercises/list-ops" + :dependencies [[org.clojure/clojure "1.10.0"]]) diff --git a/exercises/practice/list-ops/src/list_ops.clj b/exercises/practice/list-ops/src/list_ops.clj new file mode 100644 index 000000000..28d30ea73 --- /dev/null +++ b/exercises/practice/list-ops/src/list_ops.clj @@ -0,0 +1,49 @@ +(ns list-ops) + +(defn append + "Given two vectors, it adds all the items in the second vector to the end of the first vector" + [coll1 coll2] + ;; your code goes here +) + +(defn concatenate + "Given a vector of vectors, it combines all the vectors into one flattened vector" + [colls] + ;; your code goes here +) + +(defn select-if + "Given a predicate and a vector, it returns the vector of all items for which predicate(item) is true" + [pred coll] + ;; your code goes here +) + +(defn length + "Given a vector, it returns the number of items within it" + [coll] + ;; your code goes here +) + +(defn apply-to-each + "Given a function and a vector, it returns the vector of the results of applying function(item) on all items" + [f coll] + ;; your code goes here +) + +(defn foldl + "Given a function, a vector, and initial accumulator, it folds (reduces) each item into the accumulator from the left" + [f coll init] + ;; your code goes here +) + +(defn foldr + "Given a function, a vector, and an initial accumulator, it folds (reduces) each item into the accumulator from the right" + [f coll init] + ;; your code goes here +) + +(defn reverse-order + "Given a vector, it returns a vector with all the original items, but in reverse order" + [coll] + ;; your code goes here +) diff --git a/exercises/practice/list-ops/test/list_ops_test.clj b/exercises/practice/list-ops/test/list_ops_test.clj new file mode 100644 index 000000000..2b269075a --- /dev/null +++ b/exercises/practice/list-ops/test/list_ops_test.clj @@ -0,0 +1,63 @@ +(ns list-ops-test + (:require [clojure.test :refer [deftest testing is]] + list-ops)) + +(deftest append-test + (testing "empty vectors" + (is (= [] (list-ops/append [] [])))) + (testing "vector to empty vector" + (is (= [1 2 3 4] (list-ops/append [] [1 2 3 4])))) + (testing "empty vector to vector" + (is (= [1 2 3 4] (list-ops/append [1 2 3 4] [])))) + (testing "non-empty vectors" + (is (= [1 2 2 3 4 5] (list-ops/append [1 2] [2 3 4 5]))))) + +(deftest concatenate-test + (testing "empty vector" + (is (= [] (list-ops/concatenate [])))) + (testing "vector of vectors" + (is (= [1 2 3 4 5 6] (list-ops/concatenate [[1 2] [3] [] [4 5 6]])))) + (testing "vector of nested vectors" + (is (= [[1] [2] [3] [] [4 5 6]] (list-ops/concatenate [[[1] [2]] [[3]] [[]] [[4 5 6]]]))))) + +(deftest select-if-test + (testing "empty vector" + (is (= [] (list-ops/select-if (fn [x] (= (mod x 2) 1)) []))) + (testing "non-empty vector" + (is (= [1 3 5] (list-ops/select-if (fn [x] (= (mod x 2) 1)) [1 2 3 5])))))) + +(deftest length-test + (testing "empty vector" + (is (= 0 (list-ops/length [])))) + (testing "non-empty vector" + (is (= 4 (list-ops/length [1 2 3 4]))))) + +(deftest apply-to-each-test + (testing "empty vector" + (is (= [] (list-ops/apply-to-each (fn [x] (+ x 1)) [])))) + (testing "non-empty vector" + (is (= [2 4 6 8] (list-ops/apply-to-each (fn [x] (+ x 1)) [1 3 5 7]))))) + +(deftest foldl-test + (testing "empty vector" + (is (= 2 (list-ops/foldl (fn [acc el] (* el acc)) [] 2)))) + (testing "direction independent function applied to non-empty vector" + (is (= 15 (list-ops/foldl (fn [acc el] (+ el acc)) [1 2 3 4] 5)))) + (testing "direction dependent function applied to non-empty vector" + (is (= 64 (list-ops/foldl (fn [acc el] (/ el acc)) [1 2 3 4] 24))))) + +(deftest foldr-test + (testing "empty vector" + (is (= 2 (list-ops/foldr (fn [acc el] (* el acc)) [] 2)))) + (testing "direction independent function applied to non-empty vector" + (is (= 15 (list-ops/foldr (fn [acc el] (+ el acc)) [1 2 3 4] 5)))) + (testing "direction dependent function applied to non-empty vector" + (is (= 9 (list-ops/foldr (fn [acc el] (/ el acc)) [1 2 3 4] 24))))) + +(deftest reverse-order-test + (testing "empty vector" + (is (= [] (list-ops/reverse-order [])))) + (testing "non-empty vector" + (is (= [7 5 3 1] (list-ops/reverse-order [1 3 5 7])))) + (testing "vector of vectors is not flattened" + (is (= [[4 5 6] [] [3] [1 2]] (list-ops/reverse-order [[1 2] [3] [] [4 5 6]])))))