From ae16ebfd587f2a0eb7f44fd53ed5030acfbeab32 Mon Sep 17 00:00:00 2001 From: Naomi Carrigan Date: Tue, 27 Jun 2023 11:29:56 -0700 Subject: [PATCH] feat: rewrite functional spreadsheet project (#49970) Co-authored-by: Jessica Wilkins <67210629+jdwilkin4@users.noreply.github.com> --- .../index.md | 10 + .../meta.json | 361 +++++------------- .../642db8c409d9991d0b3b2f0d.md | 113 ++++++ .../642dccb78549c9285835ebc2.md | 104 +++++ .../642ddfdea4200e313f80a4b6.md | 92 +++++ .../642def66e6a60432c9a0371e.md | 85 +++++ .../642df32c0c2db433d8b46d46.md | 81 ++++ .../642df9df4b5216350de7b0d2.md | 121 ++++++ .../642dfb07e7fa6736251541c8.md | 85 +++++ .../642e0011c45c893845842058.md | 85 +++++ .../642e004130958c3975aa3a4a.md | 109 ++++++ .../642e02be7845f13b014cd2b0.md | 122 ++++++ .../6434552bcc0a951a0a99df3b.md | 104 +++++ .../64345b810a6e481e5e326849.md | 110 ++++++ .../64345c560591891f64976f7a.md | 97 +++++ .../64347464f78cd9209545f35c.md | 88 +++++ .../6434750c53db16218f41e6e1.md | 107 ++++++ .../6434759f78ec812264ff8f34.md | 109 ++++++ .../643475e13dc727231acd0f72.md | 142 +++++++ .../643498328cb52026123e2b91.md | 92 +++++ .../643498755d54c6279ba09078.md | 131 +++++++ .../6437124c4c03dd4c8fb35d56.md | 133 +++++++ .../6437133052eaf04d7300e622.md | 127 ++++++ .../643715013330824ecaa70442.md | 154 ++++++++ .../64496d1e5af8c0148fbef96d.md | 129 +++++++ .../64496d80bc174a158c973080.md | 143 +++++++ .../64496df724dd3716a71fe971.md | 157 ++++++++ .../64496e9c6d7a2e189948e441.md | 129 +++++++ .../6449749d20436c1f1dfadcf2.md | 132 +++++++ .../6449755666005520330cec5b.md | 122 ++++++ .../64497da4062602213ecf32e7.md | 147 +++++++ .../64497de936a2f322327e5c58.md | 122 ++++++ .../64497e0e5e5a2c2329785af4.md | 114 ++++++ .../64497e764135bd24b7960dd3.md | 152 ++++++++ .../6449842c6f6c84261075e4c9.md | 166 ++++++++ .../64498473a17adc26ef0ecc2d.md | 116 ++++++ .../6449849b78f43527be1e8a98.md | 150 ++++++++ .../64498542cab69128ab24e4de.md | 149 ++++++++ .../6449860d84c9e22cbd7b497c.md | 117 ++++++ .../6449863f592af72d9be0959e.md | 143 +++++++ .../6449874d5191562eb3313b3f.md | 129 +++++++ .../6449876e7aae0d2f8257a497.md | 168 ++++++++ .../64498b085028fc30a58bb6a7.md | 143 +++++++ .../646d0889c6ff4baa46ac1c50.md | 153 ++++++++ .../646d09a07241aaab1e777080.md | 136 +++++++ .../646d0a022da7bcabf3e3aca3.md | 160 ++++++++ .../646d0d20108440acc95a6b32.md | 145 +++++++ .../646d0db5175974ad8633b71c.md | 133 +++++++ .../646d0e4636e14eae2bb3b992.md | 145 +++++++ .../646d1980018efaaec2b1c28b.md | 143 +++++++ .../646d19fc4705e4af65c3e688.md | 126 ++++++ .../646d1b96dd7ea4b0061458bc.md | 136 +++++++ .../646d1cadf0d96ab0b7e12da4.md | 128 +++++++ .../646d1d67f9261fb15a795588.md | 139 +++++++ .../646d1e531042dfb24da1f032.md | 129 +++++++ .../646d3141790b3cb337dd611a.md | 141 +++++++ .../646d382c4d70ceb3dba1e830.md | 139 +++++++ .../646d386a685620b49db4be76.md | 127 ++++++ .../646d38c326f3c8b54023de38.md | 127 ++++++ .../646d38f906b94cb5fe6ce7de.md | 133 +++++++ .../646d3952f6af37b6a1c241c2.md | 125 ++++++ .../646d39c156fe94b7482c3ab6.md | 164 ++++++++ .../646d3b27cd3c56b875256301.md | 159 ++++++++ .../646d3bc75fe0c9b972da3323.md | 141 +++++++ .../646d3c146e10b0ba222bb2a7.md | 145 +++++++ .../646d3d037872fbbae0a8ec0e.md | 167 ++++++++ .../646d3d65be79c8bb9c7df9ff.md | 164 ++++++++ .../646d3d80c3b4aebc4103618e.md | 207 ++++++++++ .../646d3da8501e15bcd355ba1d.md | 186 +++++++++ .../646d3e135ab3abbdbfe5c899.md | 164 ++++++++ .../646d3e64b15f92be6e61704e.md | 146 +++++++ .../646d3ee7b17ae3bf48610033.md | 144 +++++++ .../646d3f1fd12f76c02c823bb8.md | 140 +++++++ .../646d3f718b5f8dc102cd528e.md | 164 ++++++++ .../646d404259f512c1a9e86ac1.md | 198 ++++++++++ .../646d40c543943ec250039682.md | 163 ++++++++ .../646d40fe4b7b50c30c2b4cd8.md | 170 +++++++++ .../646d41e23b583fc3b8cc4579.md | 170 +++++++++ .../646d423fade4a9c4636acd13.md | 160 ++++++++ .../646d42f58deb2fc52adc6611.md | 205 ++++++++++ .../646d43587d926bc5b6cb2e50.md | 168 ++++++++ .../646d448479c8fdc8dcec868c.md | 159 ++++++++ .../646d44da986f2bc9b72f5fe2.md | 195 ++++++++++ .../646d451c2e44afca71b67818.md | 177 +++++++++ .../646d4554721d43cb19a68bc4.md | 169 ++++++++ .../646d45b739da5ecbf830c108.md | 159 ++++++++ .../646d45ee725632cca2555146.md | 161 ++++++++ .../646d4626420eeecd51f241c2.md | 186 +++++++++ .../646d467c6994f4ce0dc416a4.md | 172 +++++++++ .../646d46c03e7d02cecb30f021.md | 167 ++++++++ .../646d4717a689e1cfa232e357.md | 188 +++++++++ .../646d4769ba65f1d05ef6b634.md | 164 ++++++++ .../646d47c8f58107d10f1e5106.md | 162 ++++++++ .../646d4813c17b37d1e261a566.md | 162 ++++++++ .../646d486aec20f7d2a581cc36.md | 150 ++++++++ .../646d48b936802fd34c3f05af.md | 189 +++++++++ .../646d498c8ebc31d3f753b22e.md | 182 +++++++++ .../646d49bfff9079d4b38df115.md | 190 +++++++++ .../646d4a07a8fb14d55cd70e09.md | 183 +++++++++ .../646d4a5b32a1cad6165df286.md | 178 +++++++++ .../646d4a8dbc04c6d6bb0001f8.md | 171 +++++++++ .../646d4ab9b3b4c5d74fdd2154.md | 175 +++++++++ .../646d4b3d80ea98d824c8a4f9.md | 314 +++++++++++++++ .../6491d38f5b09a021c4b5d5fe.md | 184 +++++++++ .../step-001.md | 78 ---- .../step-002.md | 80 ---- .../step-003.md | 84 ---- .../step-004.md | 88 ----- .../step-005.md | 94 ----- .../step-006.md | 94 ----- .../step-007.md | 90 ----- .../step-008.md | 82 ---- .../step-009.md | 84 ---- .../step-010.md | 82 ---- .../step-011.md | 87 ----- .../step-012.md | 92 ----- .../step-013.md | 98 ----- .../step-014.md | 97 ----- .../step-015.md | 102 ----- .../step-016.md | 104 ----- .../step-017.md | 100 ----- .../step-018.md | 103 ----- .../step-019.md | 110 ------ .../step-020.md | 105 ----- .../step-021.md | 107 ------ .../step-022.md | 120 ------ .../step-023.md | 114 ------ .../step-024.md | 112 ------ .../step-025.md | 120 ------ .../step-026.md | 128 ------- .../step-027.md | 131 ------- .../step-028.md | 133 ------- .../step-029.md | 134 ------- .../step-030.md | 138 ------- .../step-031.md | 142 ------- .../step-032.md | 139 ------- .../step-033.md | 140 ------- .../step-034.md | 141 ------- .../step-035.md | 139 ------- .../step-036.md | 142 ------- .../step-037.md | 150 -------- .../step-038.md | 146 ------- .../step-039.md | 150 -------- .../step-040.md | 158 -------- .../step-041.md | 157 -------- .../step-042.md | 170 --------- .../step-043.md | 163 -------- .../step-044.md | 158 -------- .../step-045.md | 157 -------- .../step-046.md | 154 -------- .../step-047.md | 159 -------- .../step-048.md | 154 -------- .../step-049.md | 156 -------- .../step-050.md | 156 -------- .../step-051.md | 160 -------- .../step-052.md | 159 -------- .../step-053.md | 173 --------- .../step-054.md | 176 --------- .../step-055.md | 176 --------- .../step-056.md | 176 --------- .../step-057.md | 177 --------- .../step-058.md | 183 --------- .../step-059.md | 183 --------- .../step-060.md | 187 --------- .../step-061.md | 189 --------- .../step-062.md | 184 --------- .../step-063.md | 183 --------- .../step-064.md | 182 --------- .../step-065.md | 186 --------- .../step-066.md | 182 --------- .../step-067.md | 192 ---------- .../step-068.md | 186 --------- .../step-069.md | 184 --------- .../step-070.md | 188 --------- .../step-071.md | 190 --------- .../step-072.md | 192 ---------- .../step-073.md | 188 --------- .../step-074.md | 190 --------- .../step-075.md | 197 ---------- .../step-076.md | 195 ---------- .../step-077.md | 200 ---------- .../step-078.md | 208 ---------- .../step-079.md | 211 ---------- .../step-080.md | 217 ----------- .../step-081.md | 220 ----------- .../step-082.md | 229 ----------- .../step-083.md | 225 ----------- .../step-084.md | 225 ----------- .../step-085.md | 230 ----------- .../step-086.md | 232 ----------- .../step-087.md | 237 ------------ .../step-088.md | 239 ------------ .../step-089.md | 251 ------------ .../step-090.md | 251 ------------ .../step-091.md | 257 ------------- .../step-092.md | 261 ------------- .../step-093.md | 260 ------------- .../step-094.md | 260 ------------- .../step-095.md | 262 ------------- .../step-096.md | 266 ------------- .../step-097.md | 273 ------------- .../step-098.md | 267 ------------- .../step-099.md | 276 ------------- .../step-100.md | 271 ------------- .../step-101.md | 268 ------------- .../step-102.md | 270 ------------- .../step-103.md | 265 ------------- .../step-104.md | 267 ------------- .../step-105.md | 264 ------------- .../step-106.md | 272 ------------- .../step-107.md | 268 ------------- .../step-108.md | 269 ------------- .../step-109.md | 275 ------------- .../step-110.md | 272 ------------- .../step-111.md | 272 ------------- .../step-112.md | 269 ------------- .../step-113.md | 271 ------------- .../step-114.md | 273 ------------- .../step-115.md | 279 -------------- .../step-116.md | 285 -------------- .../step-117.md | 288 -------------- .../step-118.md | 292 -------------- .../step-119.md | 297 -------------- .../step-120.md | 291 -------------- .../step-121.md | 301 --------------- .../step-122.md | 293 -------------- .../step-123.md | 298 --------------- .../step-124.md | 293 -------------- .../step-125.md | 298 --------------- .../step-126.md | 308 --------------- .../step-127.md | 300 --------------- .../step-128.md | 312 --------------- .../step-129.md | 318 --------------- .../step-130.md | 312 --------------- .../step-131.md | 312 --------------- .../step-132.md | 311 --------------- .../step-133.md | 316 --------------- .../step-134.md | 320 ---------------- .../step-135.md | 325 ---------------- .../step-136.md | 327 ---------------- .../step-137.md | 328 ---------------- .../step-138.md | 324 ---------------- .../step-139.md | 327 ---------------- .../step-140.md | 330 ---------------- .../step-141.md | 316 --------------- 245 files changed, 15059 insertions(+), 29042 deletions(-) create mode 100644 client/src/pages/learn/2022/javascript-algorithms-and-data-structures/learn-functional-programming-by-building-a-spreadsheet/index.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642db8c409d9991d0b3b2f0d.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642dccb78549c9285835ebc2.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642ddfdea4200e313f80a4b6.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642def66e6a60432c9a0371e.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642df32c0c2db433d8b46d46.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642df9df4b5216350de7b0d2.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642dfb07e7fa6736251541c8.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e0011c45c893845842058.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e004130958c3975aa3a4a.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e02be7845f13b014cd2b0.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434552bcc0a951a0a99df3b.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64345b810a6e481e5e326849.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64345c560591891f64976f7a.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64347464f78cd9209545f35c.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434750c53db16218f41e6e1.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434759f78ec812264ff8f34.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643475e13dc727231acd0f72.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643498328cb52026123e2b91.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643498755d54c6279ba09078.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6437124c4c03dd4c8fb35d56.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6437133052eaf04d7300e622.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643715013330824ecaa70442.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496d1e5af8c0148fbef96d.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496d80bc174a158c973080.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496df724dd3716a71fe971.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496e9c6d7a2e189948e441.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449749d20436c1f1dfadcf2.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449755666005520330cec5b.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497da4062602213ecf32e7.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497de936a2f322327e5c58.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497e0e5e5a2c2329785af4.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497e764135bd24b7960dd3.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449842c6f6c84261075e4c9.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498473a17adc26ef0ecc2d.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449849b78f43527be1e8a98.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498542cab69128ab24e4de.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449860d84c9e22cbd7b497c.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449863f592af72d9be0959e.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449874d5191562eb3313b3f.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449876e7aae0d2f8257a497.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498b085028fc30a58bb6a7.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0889c6ff4baa46ac1c50.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d09a07241aaab1e777080.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0a022da7bcabf3e3aca3.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0d20108440acc95a6b32.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0db5175974ad8633b71c.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0e4636e14eae2bb3b992.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1980018efaaec2b1c28b.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d19fc4705e4af65c3e688.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1b96dd7ea4b0061458bc.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1cadf0d96ab0b7e12da4.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1d67f9261fb15a795588.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1e531042dfb24da1f032.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3141790b3cb337dd611a.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d382c4d70ceb3dba1e830.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d386a685620b49db4be76.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d38c326f3c8b54023de38.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d38f906b94cb5fe6ce7de.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3952f6af37b6a1c241c2.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d39c156fe94b7482c3ab6.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3b27cd3c56b875256301.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3bc75fe0c9b972da3323.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3c146e10b0ba222bb2a7.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d037872fbbae0a8ec0e.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d65be79c8bb9c7df9ff.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d80c3b4aebc4103618e.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3da8501e15bcd355ba1d.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3e135ab3abbdbfe5c899.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3e64b15f92be6e61704e.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3ee7b17ae3bf48610033.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3f1fd12f76c02c823bb8.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3f718b5f8dc102cd528e.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d404259f512c1a9e86ac1.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d40c543943ec250039682.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d40fe4b7b50c30c2b4cd8.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d41e23b583fc3b8cc4579.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d423fade4a9c4636acd13.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d42f58deb2fc52adc6611.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d43587d926bc5b6cb2e50.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d448479c8fdc8dcec868c.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d44da986f2bc9b72f5fe2.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d451c2e44afca71b67818.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4554721d43cb19a68bc4.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d45b739da5ecbf830c108.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d45ee725632cca2555146.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4626420eeecd51f241c2.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d467c6994f4ce0dc416a4.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d46c03e7d02cecb30f021.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4717a689e1cfa232e357.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4769ba65f1d05ef6b634.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d47c8f58107d10f1e5106.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4813c17b37d1e261a566.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d486aec20f7d2a581cc36.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d48b936802fd34c3f05af.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d498c8ebc31d3f753b22e.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d49bfff9079d4b38df115.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a07a8fb14d55cd70e09.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a5b32a1cad6165df286.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a8dbc04c6d6bb0001f8.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4ab9b3b4c5d74fdd2154.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4b3d80ea98d824c8a4f9.md create mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6491d38f5b09a021c4b5d5fe.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-001.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-002.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-003.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-004.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-005.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-006.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-007.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-008.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-009.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-010.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-011.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-012.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-013.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-014.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-015.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-016.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-017.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-018.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-019.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-020.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-021.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-022.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-023.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-024.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-025.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-026.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-027.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-028.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-029.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-030.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-031.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-032.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-033.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-034.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-035.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-036.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-037.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-038.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-039.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-040.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-041.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-042.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-043.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-044.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-045.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-046.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-047.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-048.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-049.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-050.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-051.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-052.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-053.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-054.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-055.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-056.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-057.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-058.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-059.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-060.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-061.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-062.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-063.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-064.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-065.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-066.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-067.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-068.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-069.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-070.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-071.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-072.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-073.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-074.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-075.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-076.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-077.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-078.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-079.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-080.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-081.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-082.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-083.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-084.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-085.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-086.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-087.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-088.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-089.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-090.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-091.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-092.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-093.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-094.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-095.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-096.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-097.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-098.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-099.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-100.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-101.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-102.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-103.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-104.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-105.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-106.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-107.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-108.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-109.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-110.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-111.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-112.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-113.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-114.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-115.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-116.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-117.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-118.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-119.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-120.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-121.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-122.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-123.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-124.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-125.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-126.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-127.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-128.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-129.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-130.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-131.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-132.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-133.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-134.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-135.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-136.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-137.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-138.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-139.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-140.md delete mode 100644 curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-141.md diff --git a/client/src/pages/learn/2022/javascript-algorithms-and-data-structures/learn-functional-programming-by-building-a-spreadsheet/index.md b/client/src/pages/learn/2022/javascript-algorithms-and-data-structures/learn-functional-programming-by-building-a-spreadsheet/index.md new file mode 100644 index 00000000000..b7d3d33e8a7 --- /dev/null +++ b/client/src/pages/learn/2022/javascript-algorithms-and-data-structures/learn-functional-programming-by-building-a-spreadsheet/index.md @@ -0,0 +1,10 @@ +--- +title: Introduction to the Learn Functional Programming by Building a Spreadsheet +block: learn-functional-programming-by-building-a-spreadsheet +superBlock: JavaScript Algorithms and Data Structures +isBeta: true +--- + +## Introduction to the Learn Functional Programming by Building a Spreadsheet + +This is a test for the new project-based curriculum. diff --git a/curriculum/challenges/_meta/learn-functional-programming-by-building-a-spreadsheet/meta.json b/curriculum/challenges/_meta/learn-functional-programming-by-building-a-spreadsheet/meta.json index 2e96acf7182..db39d158faa 100644 --- a/curriculum/challenges/_meta/learn-functional-programming-by-building-a-spreadsheet/meta.json +++ b/curriculum/challenges/_meta/learn-functional-programming-by-building-a-spreadsheet/meta.json @@ -10,571 +10,416 @@ "template": "", "required": [], "superBlock": "2022/javascript-algorithms-and-data-structures", + "superOrder": 4, "isBeta": true, "challengeOrder": [ [ - "5d79253297c0ebb149ea9fed", + "642db8c409d9991d0b3b2f0d", "Step 1" ], [ - "5d7925323be8848dbc58a07a", + "642dccb78549c9285835ebc2", "Step 2" ], [ - "5d792532f631702ae6d23e11", + "642ddfdea4200e313f80a4b6", "Step 3" ], [ - "5d7925329445167ecc2ac9c9", + "642def66e6a60432c9a0371e", "Step 4" ], [ - "5d792532b07918c3a5904913", + "642df32c0c2db433d8b46d46", "Step 5" ], [ - "5d792533cc8b18b6c133edc7", + "642df9df4b5216350de7b0d2", "Step 6" ], [ - "5d7925337954ed57a565a135", + "642dfb07e7fa6736251541c8", "Step 7" ], [ - "5d79253352e33dd59ec2f6de", + "642e0011c45c893845842058", "Step 8" ], [ - "5d792533d31e4f7fad33011d", + "642e004130958c3975aa3a4a", "Step 9" ], [ - "5d792533e7707b9645d7b540", + "642e02be7845f13b014cd2b0", "Step 10" ], [ - "5d79253378595ec568f70ab6", + "6434552bcc0a951a0a99df3b", "Step 11" ], [ - "5d7925330918ae4a2f282e7e", + "64345b810a6e481e5e326849", "Step 12" ], [ - "5d792533ed00e75d129e1b18", + "64345c560591891f64976f7a", "Step 13" ], [ - "5d792533a5c42fb4d1a4b70d", + "64347464f78cd9209545f35c", "Step 14" ], [ - "5d79253358e8f646cbeb2bb0", + "6434750c53db16218f41e6e1", "Step 15" ], [ - "5d792533bb38fab70b27f527", + "6434759f78ec812264ff8f34", "Step 16" ], [ - "5d79253386060ed9eb04a070", + "643475e13dc727231acd0f72", "Step 17" ], [ - "5d792533717672657b81aa69", + "643498328cb52026123e2b91", "Step 18" ], [ - "5d7925335ab63018dcec11fe", + "643498755d54c6279ba09078", "Step 19" ], [ - "5d7925330f300c342315066d", + "6437124c4c03dd4c8fb35d56", "Step 20" ], [ - "5d792533aa6443215c9b16bf", + "6437133052eaf04d7300e622", "Step 21" ], [ - "5d7925334c5e22586dd72962", + "643715013330824ecaa70442", "Step 22" ], [ - "5d79253307ecd49e030bdcd1", + "64496d1e5af8c0148fbef96d", "Step 23" ], [ - "5d792534257122211d3043af", + "64496d80bc174a158c973080", "Step 24" ], [ - "5d7925346f4f2da6df4354a6", + "64496df724dd3716a71fe971", "Step 25" ], [ - "5d792534cac2dbe0a719ea7a", + "64496e9c6d7a2e189948e441", "Step 26" ], [ - "5d792534857332d07ccba3ad", + "6449749d20436c1f1dfadcf2", "Step 27" ], [ - "5d792534d586ef495ea9df90", + "6449755666005520330cec5b", "Step 28" ], [ - "5d79253410532e13d13fe574", + "64497da4062602213ecf32e7", "Step 29" ], [ - "5d7925342415527083bd6667", + "64497de936a2f322327e5c58", "Step 30" ], [ - "5d792534c3d26890ac1484d4", + "64497e0e5e5a2c2329785af4", "Step 31" ], [ - "5d792534b92f3d1cd4410ce3", + "64497e764135bd24b7960dd3", "Step 32" ], [ - "5d7925341193948dfe6d76b4", + "6449842c6f6c84261075e4c9", "Step 33" ], [ - "5d792534cf81365cfca58794", + "64498473a17adc26ef0ecc2d", "Step 34" ], [ - "5d7925348ee084278ff15556", + "6449849b78f43527be1e8a98", "Step 35" ], [ - "5d7925348a6a41c32f7a4e3e", + "64498542cab69128ab24e4de", "Step 36" ], [ - "5d792534408c5be896b0a46e", + "6449860d84c9e22cbd7b497c", "Step 37" ], [ - "5d792534f0eda837510e9192", + "6449863f592af72d9be0959e", "Step 38" ], [ - "5d7925346b911fce161febaf", + "6449874d5191562eb3313b3f", "Step 39" ], [ - "5d79253483eada4dd69258eb", + "6449876e7aae0d2f8257a497", "Step 40" ], [ - "5d7925342b2b993ef18cd45f", + "64498b085028fc30a58bb6a7", "Step 41" ], [ - "5d7925341747ad42b12f8e68", + "646d0889c6ff4baa46ac1c50", "Step 42" ], [ - "5d792535b0b3c198ee3ed6f9", + "646d09a07241aaab1e777080", "Step 43" ], [ - "5d7925357a0533eb221b005d", + "646d0a022da7bcabf3e3aca3", "Step 44" ], [ - "5d792535591db67ee15b4106", + "646d0d20108440acc95a6b32", "Step 45" ], [ - "5d792535f1f7adf77de5831d", + "646d0db5175974ad8633b71c", "Step 46" ], [ - "5d7925353d2c505eafd50cd9", + "646d0e4636e14eae2bb3b992", "Step 47" ], [ - "5d79253539b5e944ba3e314c", + "646d1980018efaaec2b1c28b", "Step 48" ], [ - "5d792535a4f1cbff7a8b9a0b", + "646d19fc4705e4af65c3e688", "Step 49" ], [ - "5d792535e3304f15a8890162", + "646d1b96dd7ea4b0061458bc", "Step 50" ], [ - "5d792535a40ea5ac549d6804", + "646d1cadf0d96ab0b7e12da4", "Step 51" ], [ - "5d7925358c220e5b2998909e", + "646d1d67f9261fb15a795588", "Step 52" ], [ - "5d7925357729e183a49498aa", + "646d1e531042dfb24da1f032", "Step 53" ], [ - "5d79253555aa652afbb68086", + "646d3141790b3cb337dd611a", "Step 54" ], [ - "5d79253582be306d339564f6", + "646d382c4d70ceb3dba1e830", "Step 55" ], [ - "5d7925352047e5c54882c436", + "646d386a685620b49db4be76", "Step 56" ], [ - "5d79253568e441c0adf9db9f", + "646d38c326f3c8b54023de38", "Step 57" ], [ - "5d7925356ab117923b80c9cd", + "646d38f906b94cb5fe6ce7de", "Step 58" ], [ - "5d792535e54a8cd729a0d708", + "646d3952f6af37b6a1c241c2", "Step 59" ], [ - "5d7925353b307724a462b06b", + "646d39c156fe94b7482c3ab6", "Step 60" ], [ - "5d792536735f71d746ee5d99", + "646d3b27cd3c56b875256301", "Step 61" ], [ - "5d792536ad340d9dff2e4a96", + "646d3bc75fe0c9b972da3323", "Step 62" ], [ - "5d7925369614afd92d01fed5", + "646d3c146e10b0ba222bb2a7", "Step 63" ], [ - "5d792536504e68254fe02236", + "646d3d037872fbbae0a8ec0e", "Step 64" ], [ - "5d792536c8d2f0fdfad768fe", + "646d3d65be79c8bb9c7df9ff", "Step 65" ], [ - "5d79253639028b8ec56afcda", + "646d3d80c3b4aebc4103618e", "Step 66" ], [ - "5d792536834f2fd93e84944f", + "646d3da8501e15bcd355ba1d", "Step 67" ], [ - "5d792536ddff9ea73c90a994", + "646d3e135ab3abbdbfe5c899", "Step 68" ], [ - "5d7925361596f84067904f7f", + "646d3e64b15f92be6e61704e", "Step 69" ], [ - "5d792536dd8a4daf255488ac", + "646d3ee7b17ae3bf48610033", "Step 70" ], [ - "5d792536449c73004f265fb1", + "646d3f1fd12f76c02c823bb8", "Step 71" ], [ - "5d79253685fc69b8fe60a0d2", + "646d3f718b5f8dc102cd528e", "Step 72" ], [ - "5d792536dc6e3ab29525de9e", + "646d404259f512c1a9e86ac1", "Step 73" ], [ - "5d792536cfd0fd893c630abb", + "646d40c543943ec250039682", "Step 74" ], [ - "5d7925366a5ff428fb483b40", + "646d40fe4b7b50c30c2b4cd8", "Step 75" ], [ - "5d7925365d4035eeb2e395fd", + "646d41e23b583fc3b8cc4579", "Step 76" ], [ - "5d7925364c106e9aaf05a16f", + "646d423fade4a9c4636acd13", "Step 77" ], [ - "5d792536970cd8e819cc8a96", + "646d42f58deb2fc52adc6611", "Step 78" ], [ - "5d792536e33baeaa60129e0a", + "646d43587d926bc5b6cb2e50", "Step 79" ], [ - "5d7925379e2a488f333e2d43", + "646d448479c8fdc8dcec868c", "Step 80" ], [ - "5d7925379000785f6d8d9af3", + "646d44da986f2bc9b72f5fe2", "Step 81" ], [ - "5d79253791391b0acddd0ac5", + "646d451c2e44afca71b67818", "Step 82" ], [ - "5d7925373104ae5ae83f20a5", + "646d4554721d43cb19a68bc4", "Step 83" ], [ - "5d7925373b7127cfaeb50c26", + "646d45b739da5ecbf830c108", "Step 84" ], [ - "5d792537cb3a5cd6baca5e1a", + "646d45ee725632cca2555146", "Step 85" ], [ - "5d79253742f3313d55db981f", + "646d4626420eeecd51f241c2", "Step 86" ], [ - "5d7925379e0180a438ce7f95", + "646d467c6994f4ce0dc416a4", "Step 87" ], [ - "5d792537c80984dfa5501b96", + "646d46c03e7d02cecb30f021", "Step 88" ], [ - "5d7925377b54d8a76efb5657", + "646d4717a689e1cfa232e357", "Step 89" ], [ - "5d7925371398513549bb6395", + "646d4769ba65f1d05ef6b634", "Step 90" ], [ - "5d792537ea3eaf302bf2d359", + "646d47c8f58107d10f1e5106", "Step 91" ], [ - "5d792537533b1c7843bfd029", + "646d4813c17b37d1e261a566", "Step 92" ], [ - "5d792537dc0fe84345d4f19e", + "646d486aec20f7d2a581cc36", "Step 93" ], [ - "5d792537b6cadae0f4b0cda1", + "646d48b936802fd34c3f05af", "Step 94" ], [ - "5d79253770083fb730c93a93", + "646d498c8ebc31d3f753b22e", "Step 95" ], [ - "5d792537fef76b226b63b93b", + "646d49bfff9079d4b38df115", "Step 96" ], [ - "5d79253760fca25ccbbd8990", + "646d4a07a8fb14d55cd70e09", "Step 97" ], [ - "5d7925374321824cba309875", + "6491d38f5b09a021c4b5d5fe", "Step 98" ], [ - "5d7925381e8565a5c50ba7f1", + "646d4a5b32a1cad6165df286", "Step 99" ], [ - "5d7925383f1b77db7f1ff59e", + "646d4a8dbc04c6d6bb0001f8", "Step 100" ], [ - "5d792538de9fa3f298bcd5f6", + "646d4ab9b3b4c5d74fdd2154", "Step 101" ], [ - "5d7925385b74f69642e1fea5", + "646d4b3d80ea98d824c8a4f9", "Step 102" - ], - [ - "5d7925380ea76d55b2c97d7b", - "Step 103" - ], - [ - "5d792538be4fe331f1a6c008", - "Step 104" - ], - [ - "5d792538d169f33142175b95", - "Step 105" - ], - [ - "5d792538e48b5a2c6e5bbe12", - "Step 106" - ], - [ - "5d7925387f3e9da5ec856dbe", - "Step 107" - ], - [ - "5d79253824ae9b4a6e6f3108", - "Step 108" - ], - [ - "5d7925383f122a279f4c54ad", - "Step 109" - ], - [ - "5d7925387b682e962f209269", - "Step 110" - ], - [ - "5d792538de774217b173288e", - "Step 111" - ], - [ - "5d79253891d93585323d1f3c", - "Step 112" - ], - [ - "5d7925384e34e944ecb4612d", - "Step 113" - ], - [ - "5d792538631844ad0bdfb4c3", - "Step 114" - ], - [ - "5d792538e2a8d20cc580d481", - "Step 115" - ], - [ - "5d792538f5004390d6678554", - "Step 116" - ], - [ - "5d792539dd4fd4c96fd85f7e", - "Step 117" - ], - [ - "5d79253949802f8587c8bbd3", - "Step 118" - ], - [ - "5d7925395888767e9304c082", - "Step 119" - ], - [ - "5d7925393b30099e37a34668", - "Step 120" - ], - [ - "5d7925398157757b23730fdd", - "Step 121" - ], - [ - "5d792539de4b9ac14dd40409", - "Step 122" - ], - [ - "5d792539534f1bf991bb987f", - "Step 123" - ], - [ - "5d7925394089b762f93ffa52", - "Step 124" - ], - [ - "5d792539ec758d45a6900173", - "Step 125" - ], - [ - "5d7925398d525f61a9ff3a79", - "Step 126" - ], - [ - "5d792539a222f385c5c17d2b", - "Step 127" - ], - [ - "5d7925398a7184b41b12a0e0", - "Step 128" - ], - [ - "5d7925399afb905c34730a75", - "Step 129" - ], - [ - "5d792539728d1aa7788e2c9b", - "Step 130" - ], - [ - "5d79253939434a2724c0ec41", - "Step 131" - ], - [ - "5d792539b9e1d3c54d8fe94a", - "Step 132" - ], - [ - "5d792539b2e0bd8f9e8213e4", - "Step 133" - ], - [ - "5d792539239148965a1a59a5", - "Step 134" - ], - [ - "5d792539e1446045d0df6d28", - "Step 135" - ], - [ - "5d79253a2febbb77098730b9", - "Step 136" - ], - [ - "5d79253a98bd9fdf7ce68d0a", - "Step 137" - ], - [ - "5d79253a1e9abf29de64c177", - "Step 138" - ], - [ - "5d79253a8b29d78984369e4b", - "Step 139" - ], - [ - "5d79253ad297a31cbe073718", - "Step 140" - ], - [ - "5dc10b8b93704f41d279eb5b", - "Step 141" ] ] } \ No newline at end of file diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642db8c409d9991d0b3b2f0d.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642db8c409d9991d0b3b2f0d.md new file mode 100644 index 00000000000..3ca57fbf522 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642db8c409d9991d0b3b2f0d.md @@ -0,0 +1,113 @@ +--- +id: 642db8c409d9991d0b3b2f0d +title: Step 1 +challengeType: 0 +dashedName: step-1 +--- + +# --description-- + +Your project starts with a basic HTML container and some corresponding CSS. Your first task will be to programmatically generate the cells for your spreadsheet. + +The global `window` object represents the browser window (or tab). It has an `onload` property which allows you to define behavior when the window has loaded the entire page, including stylesheets and scripts. + +Start by setting the `onload` property of `window` to an arrow function with no parameters. In the function, declare a `container` variable and assign it the value of getting the element by the `id` of `container`. + +# --hints-- + +You should access the `onload` property of the `window` object. + +```js +assert.match(code, /window\.onload/); +``` + +You should set the `onload` property to a function. + +```js +assert.isFunction(window.onload); +``` + +You should use arrow syntax. + +```js +assert.match(code, /window\.onload\s*=\s*\(/); +``` + +Your `onload` function should not take any parameters. + +```js +assert.match(code, /window\.onload\s*=\s*\(\s*\)/); +``` + +You should declare a `container` variable in your `onload` function. + +```js +assert.match(code, /window\.onload\s*=\s*\(\s*\)\s*=>\s*\{\s*(?:let|var|const)\s+container/); +``` + +Your `container` variable should be declared with `const`. + +```js +assert.match(code, /window\.onload\s*=\s*\(\s*\)\s*=>\s*\{\s*const\s+container/); +``` + +You should use `document.getElementById()` + +```js +assert.match(code, /document\.getElementById\(/); +``` + +You should get the element with the `id` of `container`. + +```js +assert.match(code, /document\.getElementById\(\s*('|"|`)container\1\s*\)/); +``` + +You should assign the `#container` element to `container`. + +```js +assert.match(code, /window\.onload\s*=\s*\(\s*\)\s*=>\s*\{\s*const\s+container\s*=\s*document\.getElementById\(\s*('|"|`)container\1\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642dccb78549c9285835ebc2.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642dccb78549c9285835ebc2.md new file mode 100644 index 00000000000..d7095d5ca8a --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642dccb78549c9285835ebc2.md @@ -0,0 +1,104 @@ +--- +id: 642dccb78549c9285835ebc2 +title: Step 2 +challengeType: 0 +dashedName: step-2 +--- + +# --description-- + +Functions are ideal for reusable logic. When a function itself needs to reuse logic, you can declare a nested function to handle that logic. Here is an example of a nested function: + +```js +const outer = () => { + const inner = () => { + + }; +}; +``` + +Declare a nested `createLabel` function using arrow syntax. It should take a `name` parameter. + +# --hints-- + +You should declare a `createLabel` variable in your `onload` function. + +```js +assert.match(code, /window\.onload\s*=\s*\(\s*\)\s*=>\s*\{\s*(?:const\s+container\s*=\s*document\.getElementById\(\s*('|"|`)container\1\s*\);?)?\s*(?:let|var|const)\s*createLabel/); +``` + +Your `createLabel` variable should be declared after your `container` variable. + +```js +assert.match(code, /window\.onload\s*=\s*\(\s*\)\s*=>\s*\{\s*const\s+container\s*=\s*document\.getElementById\(\s*('|"|`)container\1\s*\);?\s*(?:let|var|const)\s*createLabel/); +``` + +Your `createLabel` variable should be declared with `const`. + +```js +assert.match(code, /window\.onload\s*=\s*\(\s*\)\s*=>\s*\{\s*const\s+container\s*=\s*document\.getElementById\(\s*('|"|`)container\1\s*\);?\s*const\s*createLabel/); +``` + +Your `createLabel` variable should be an arrow function. + +```js +assert.match(code, /window\.onload\s*=\s*\(\s*\)\s*=>\s*\{\s*const\s+container\s*=\s*document\.getElementById\(\s*('|"|`)container\1\s*\);?\s*const\s*createLabel\s*=\s*\(?.*\)?\s*=>/); +``` + +Your `createLabel` function should have a `name` parameter. + +```js +assert.match(code, /window\.onload\s*=\s*\(\s*\)\s*=>\s*\{\s*const\s+container\s*=\s*document\.getElementById\(\s*('|"|`)container\1\s*\);?\s*const\s*createLabel\s*=\s*\(?\s*name\s*\)?\s*=>/); +``` + +Your `createLabel` function should be empty. + +```js +assert.match(code, /window\.onload\s*=\s*\(\s*\)\s*=>\s*\{\s*const\s+container\s*=\s*document\.getElementById\(\s*('|"|`)container\1\s*\);?\s*const\s*createLabel\s*=\s*\(?\s*name\s*\)?\s*=>\s*\{\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- +window.onload = () => { + const container = document.getElementById("container"); + +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642ddfdea4200e313f80a4b6.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642ddfdea4200e313f80a4b6.md new file mode 100644 index 00000000000..77b8875bb96 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642ddfdea4200e313f80a4b6.md @@ -0,0 +1,92 @@ +--- +id: 642ddfdea4200e313f80a4b6 +title: Step 3 +challengeType: 0 +dashedName: step-3 +--- + +# --description-- + +Remember that the `document` object has a `.createElement()` method which allows you to dynamically create new HTML elements. + +In your `createLabel` function, declare a `label` variable and assign it a new `div` element. + +# --hints-- + +You should declare a `label` variable in your `createLabel` function. + +```js +assert.match(code, /const\s*createLabel\s*=\s*\(?\s*name\s*\)?\s*=>\s*\{\s*(?:const|let|var)\s*label/); +``` + +Your `label` variable should be declared with `const`. + +```js +assert.match(code, /const\s*createLabel\s*=\s*\(?\s*name\s*\)?\s*=>\s*\{\s*const\s*label/); +``` + +You should use the `.createElement()` method of the `document` object. + +```js +assert.match(code, /document\.createElement\(/); +``` + +You should pass the string `div` to the `.createElement()` method. + +```js +assert.match(code, /document\.createElement\(\s*('|"|`)div\1\s*\)/); +``` + +You should assign your new `div` element to `label`. + +```js +assert.match(code, /const\s*label\s*=\s*document\.createElement\(\s*('|"|`)div\1\s*\)/) +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + + } +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642def66e6a60432c9a0371e.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642def66e6a60432c9a0371e.md new file mode 100644 index 00000000000..6aab064ecef --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642def66e6a60432c9a0371e.md @@ -0,0 +1,85 @@ +--- +id: 642def66e6a60432c9a0371e +title: Step 4 +challengeType: 0 +dashedName: step-4 +--- + +# --description-- + +Set the `className` of the `label` element to `label`, and set the `textContent` to the `name` parameter. + +# --hints-- + +You should access the `className` property of the `label` element. + +```js +assert.match(code, /label\.className/); +``` + +You should set the `className` property to the string `label`. + +```js +assert.match(code, /label\.className\s*=\s*('|"|`)label\1/); +``` + +You should access the `textContent` property of the `label` element. + +```js +assert.match(code, /label\.textContent/); +``` + +You should set the `textContent` property to the value of `name`. + +```js +assert.match(code, /label\.textContent\s*=\s*name/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + + } +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642df32c0c2db433d8b46d46.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642df32c0c2db433d8b46d46.md new file mode 100644 index 00000000000..cd4fbb784c5 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642df32c0c2db433d8b46d46.md @@ -0,0 +1,81 @@ +--- +id: 642df32c0c2db433d8b46d46 +title: Step 5 +challengeType: 0 +dashedName: step-5 +--- + +# --description-- + +Finally, use the `.appendChild()` method to add your `label` element to the `container` element. + +# --hints-- + +You should access the `.appendChild()` method of the `container` element. + +```js +assert.match(code, /container\.appendChild\(/); +``` + +You should pass your `label` element to the `.appendChild()` method. + +```js +assert.match(code, /container\.appendChild\(\s*label\s*\)/); +``` + +You should append `label` after setting the attributes. + +```js +assert.match(code, /const\s*label\s*=\s*document.createElement\(\s*('|"|`)div\1\s*\);?\s*label\.className\s*=\s*('|"|`)label\2;?\s*label\.textContent\s*=\s*name;?\s*container\.appendChild\(\s*label\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + + } +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642df9df4b5216350de7b0d2.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642df9df4b5216350de7b0d2.md new file mode 100644 index 00000000000..6b97233445b --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642df9df4b5216350de7b0d2.md @@ -0,0 +1,121 @@ +--- +id: 642df9df4b5216350de7b0d2 +title: Step 6 +challengeType: 0 +dashedName: step-6 +--- + +# --description-- + +You will need a function to generate a range of numbers. + +Declare an empty `range` function which takes a `start` and `end` parameter. Use the `Array()` constructor and implicitly return an empty array. + +# --hints-- + +You should declare a `range` variable. + +```js +assert.match(code, /(?:let|var|const)\s*range/); +``` + +You should use `const` to declare your `range` variable. + +```js +assert.match(code, /const\s*range/); +``` + +Your `range` variable should be a function. + +```js +assert.isFunction(range); +``` + +Your `range` function should use arrow syntax. + +```js +assert.match(code, /const\s*range\s*=\s*\(.*\)\s*=>/); +``` + +Your `range` function should take a `start` parameter first. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start/) +``` + +Your `range` function should take an `end` parameter second. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)/); +``` + +Your `range` function should use an implicit return. Remember that this means you will not use curly brackets. + +```js +assert.notMatch(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*{/); +``` + +Your `range` function should use the `Array()` constructor. Primitive constructors do not need the `new` keyword. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(/); +``` + +You should not pass anything to the `Array()` constructor. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- + +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642dfb07e7fa6736251541c8.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642dfb07e7fa6736251541c8.md new file mode 100644 index 00000000000..34b11e9b256 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642dfb07e7fa6736251541c8.md @@ -0,0 +1,85 @@ +--- +id: 642dfb07e7fa6736251541c8 +title: Step 7 +challengeType: 0 +dashedName: step-7 +--- + +# --description-- + +Your array will need to be the size of the range. You can calculate this by finding the difference between `end` and `start`, and adding `1` to the result. + +Pass this calculation as the argument for your `Array()` constructor. + +# --hints-- + +You should subtract `start` from `end`. + +```js +assert.match(code, /end\s*-\s*start/); +``` + +You should add `1` to your `end - start` calculation. + +```js +assert.match(code, /end\s*-\s*start\s*\+\s*1/); +``` + +You should pass your calculation to the `Array()` constructor. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(\s*end\s*-\s*start\s*\+\s*1\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- +const range = (start, end) => Array(); +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e0011c45c893845842058.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e0011c45c893845842058.md new file mode 100644 index 00000000000..2698f6ad2b8 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e0011c45c893845842058.md @@ -0,0 +1,85 @@ +--- +id: 642e0011c45c893845842058 +title: Step 8 +challengeType: 0 +dashedName: step-8 +--- + +# --description-- + +The `Array()` constructor has a `.fill()` method which can be used to fill an array with a value. You can use this to fill your array with the `start` value. + +Chain the `.fill()` method to your `Array()` constructor, and pass it the `start` value. + +# --hints-- + +You should use the `.fill()` method. + +```js +assert.match(code, /\.fill\(/); +``` + +You should call the `.fill()` method on your `Array()` constructor. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(\s*end\s*-\s*start\s*\+\s*1\s*\)\.fill\(/); +``` + +You should pass `start` to the `.fill()` method. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(\s*end\s*-\s*start\s*\+\s*1\s*\).fill\(\s*start\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- +const range = (start, end) => Array(end - start + 1); +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e004130958c3975aa3a4a.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e004130958c3975aa3a4a.md new file mode 100644 index 00000000000..aa9a9db2ec4 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e004130958c3975aa3a4a.md @@ -0,0 +1,109 @@ +--- +id: 642e004130958c3975aa3a4a +title: Step 9 +challengeType: 0 +dashedName: step-9 +--- + +# --description-- + +Currently your `range` function returns an array with the correct length, but all of the values are the value of `start`. To fix this, chain the `.map()` method to your `.fill()` method. + +Pass the `.map()` method a callback which takes `element` and `index` as parameters and returns the sum of those parameters. + +# --hints-- + +You should use the `.map()` method. + +```js +assert.match(code, /\.map\(/); +``` + +You should chain the `.map()` method to your `.fill()` method. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(\s*end\s*-\s*start\s*\+\s*1\s*\).fill\(\s*start\s*\)\.map\(/); +``` + +You should pass a callback function to `.map()` using arrow syntax. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(\s*end\s*-\s*start\s*\+\s*1\s*\).fill\(\s*start\s*\)\.map\(\s*\(.*\)\s*=>/); +``` + +Your `.map()` callback should take `element` as the first parameter. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(\s*end\s*-\s*start\s*\+\s*1\s*\).fill\(\s*start\s*\)\.map\(\s*\(\s*element/); +``` + +Your `.map()` callback should take `index` as the second parameter. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(\s*end\s*-\s*start\s*\+\s*1\s*\).fill\(\s*start\s*\)\.map\(\s*\(\s*element\s*,\s*index\s*\)\s*=>/); +``` + +Your `.map()` callback should use an implicit return. + +```js +assert.notMatch(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(\s*end\s*-\s*start\s*\+\s*1\s*\).fill\(\s*start\s*\)\.map\(\s*\(\s*element\s*,\s*index\s*\)\s*=>\s*\{/); +``` + +Your `.map()` callback should implicitly return the sum of `element` and `index`. + +```js +assert.match(code, /const\s*range\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*Array\(\s*end\s*-\s*start\s*\+\s*1\s*\).fill\(\s*start\s*\)\.map\(\s*\(\s*element\s*,\s*index\s*\)\s*=>\s*(element\s*\+\s*index|index\s*\+\s*element)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- +const range = (start, end) => Array(end - start + 1).fill(start); +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e02be7845f13b014cd2b0.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e02be7845f13b014cd2b0.md new file mode 100644 index 00000000000..c280f9d99ad --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/642e02be7845f13b014cd2b0.md @@ -0,0 +1,122 @@ +--- +id: 642e02be7845f13b014cd2b0 +title: Step 10 +challengeType: 0 +dashedName: step-10 +--- + +# --description-- + +Now that you have a `range` function, you can use it to create a range of letters as well. + +Declare a `charRange` function using `const` and arrow syntax. It should take a `start` and `end` parameter. The function should implicitly return the result of calling `range()` with `start` and `end` as the arguments. + +# --hints-- + +You should declare a `charRange` variable. + +```js +assert.match(code, /(?:let|const|var)\s*charRange/); +``` + +Your `charRange` variable should be declared with `const`. + +```js +assert.match(code, /const\s*charRange/); +``` + +Your `charRange` variable should be a function. + +```js +assert.isFunction(charRange); +``` + +Your `charRange` function should use arrow syntax. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(.*\)\s*=>/); +``` + +Your `charRange` function should take `start` as the first parameter. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(\s*start/); +``` + +Your `charRange` function should take `end` as the second parameter. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)/); +``` + +Your `charRange` function should use an implicit return. + +```js +assert.notMatch(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*{/); +``` + +Your `charRange` function should call your `range` function. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*range\(/); +``` + +You should pass `start` and `end` as the arguments to your `range` call. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*range\(\s*start\s*,\s*end\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +--fcc-editable-region-- + +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434552bcc0a951a0a99df3b.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434552bcc0a951a0a99df3b.md new file mode 100644 index 00000000000..e72b47c2c9d --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434552bcc0a951a0a99df3b.md @@ -0,0 +1,104 @@ +--- +id: 6434552bcc0a951a0a99df3b +title: Step 11 +challengeType: 0 +dashedName: step-11 +--- + +# --description-- + +Your `range` function expects numbers, but your `start` and `end` values will be strings (specifically, they will be single characters such as `A`). + +Convert your `start` and `end` values in your `range()` call to numbers by using the `.charCodeAt()` method on them, passing the number `0` as the argument to that method. + +# --hints-- + +You should use the `.charCodeAt()` method. + +```js +assert.match(code, /\.charCodeAt\(/); +``` + +You should call the `.charCodeAt()` method on `start`. + +```js +assert.match(code, /start\.charCodeAt\(/); +``` + +You should pass `0` to the `.charCodeAt()` method of `start`. + +```js +assert.match(code, /start\.charCodeAt\(\s*0\s*\)/); +``` + +You should call the `.charCodeAt()` method on `end`. + +```js +assert.match(code, /end\.charCodeAt\(/); +``` + +You should pass `0` to the `.charCodeAt()` method of `end`. + +```js +assert.match(code, /end\.charCodeAt\(\s*0\s*\)/); +``` + +You should use the `.charCodeAt()` methods directly in your `range` call. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*range\(\s*start\.charCodeAt\(\s*0\s*\)\s*,\s*end\.charCodeAt\(\s*0\s*\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +--fcc-editable-region-- +const charRange = (start, end) => range(start, end); +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64345b810a6e481e5e326849.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64345b810a6e481e5e326849.md new file mode 100644 index 00000000000..dc0a283a680 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64345b810a6e481e5e326849.md @@ -0,0 +1,110 @@ +--- +id: 64345b810a6e481e5e326849 +title: Step 12 +challengeType: 0 +dashedName: step-12 +--- + +# --description-- + +`range()` will return an array of numbers, which you need to convert back into characters. Chain the `.map()` method to your `range()` call. + +Pass a callback function that takes `code` as the parameter and implicitly returns the value of passing `code` to the `String.fromCharCode()` method. + +# --hints-- + +You should use the `.map()` method. + +```js +assert.lengthOf(code.match(/\.map\(/g), 2); +``` + +You should chain the `.map()` method to your `range` call. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*range\(\s*start\.charCodeAt\(\s*0\s*\)\s*,\s*end\.charCodeAt\(\s*0\s*\)\s*\)\.map\(/); +``` + +You should use arrow syntax for the `.map()` callback. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*range\(\s*start\.charCodeAt\(\s*0\s*\)\s*,\s*end\.charCodeAt\(\s*0\s*\)\s*\).map\(\s*\(?.*\)?\s*=>/); +``` + +Your `.map()` callback should take a `code` parameter. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*range\(\s*start\.charCodeAt\(\s*0\s*\)\s*,\s*end\.charCodeAt\(\s*0\s*\)\s*\).map\(\s*\(?\s*code\s*\)?\s*=>/); +``` + +Your `.map()` callback should use an implicit return. + +```js +assert.notMatch(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*range\(\s*start\.charCodeAt\(\s*0\s*\)\s*,\s*end\.charCodeAt\(\s*0\s*\)\s*\).map\(\s*\(?\s*code\s*\)?\s*=>\s*\{/); +``` + +Your `.map()` callback should return the result of calling `String.fromCharCode()`. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*range\(\s*start\.charCodeAt\(\s*0\s*\)\s*,\s*end\.charCodeAt\(\s*0\s*\)\s*\).map\(\s*\(?\s*code\s*\)?\s*=>\s*String\.fromCharCode\(/); +``` + +You should pass the variable `code` to `String.fromCharCode()`. + +```js +assert.match(code, /const\s*charRange\s*=\s*\(\s*start\s*,\s*end\s*\)\s*=>\s*range\(\s*start\.charCodeAt\(\s*0\s*\)\s*,\s*end\.charCodeAt\(\s*0\s*\)\s*\).map\(\s*\(?\s*code\s*\)?\s*=>\s*String\.fromCharCode\(\s*code\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +--fcc-editable-region-- +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)); +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64345c560591891f64976f7a.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64345c560591891f64976f7a.md new file mode 100644 index 00000000000..51d5bc5f178 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64345c560591891f64976f7a.md @@ -0,0 +1,97 @@ +--- +id: 64345c560591891f64976f7a +title: Step 13 +challengeType: 0 +dashedName: step-13 +--- + +# --description-- + +Now that your helper functions are complete, back in your `onload` event handler you should declare a `letters` variable. Assign it the result of calling `charRange()` with the letters `A` and `J` as arguments. + +# --hints-- + +You should declare a `letters` variable. + +```js +assert.match(code, /(?:let|const|var)\s*letters/); +``` + +You should use `const` to declare your `letters` variable. + +```js +assert.match(code, /const\s*letters/); +``` + +You should assign a `charRange()` call to your `letters` variable. + +```js +assert.match(code, /const\s*letters\s*=\s*charRange\(/); +``` + +You should pass `A` as the first argument to your `charRange()` call. + +```js +assert.match(code, /const\s*letters\s*=\s*charRange\(\s*('|"|`)A\1/); +``` + +You should pass `J` as the second argument to your `charRange()` call. + +```js +assert.match(code, /const\s*letters\s*=\s*charRange\(\s*('|"|`)A\1\s*,\s*('|"|`)J\2\s*\)/) +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } +--fcc-editable-region-- + +--fcc-editable-region-- +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64347464f78cd9209545f35c.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64347464f78cd9209545f35c.md new file mode 100644 index 00000000000..93f8895d535 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64347464f78cd9209545f35c.md @@ -0,0 +1,88 @@ +--- +id: 64347464f78cd9209545f35c +title: Step 14 +challengeType: 0 +dashedName: step-14 +--- + +# --description-- + +Now call the `.forEach()` method of your `letters` array, and pass your `createLabel` function reference as the callback. + +You should see some letters appear across the top of your spreadsheet. + +# --hints-- + +You should call the `.forEach()` method on your `letters` array. + +```js +assert.match(code, /letters\.forEach\(/); +``` + +You should pass your `createLabel` function reference to the `.forEach()` method. + +```js +assert.match(code, /letters\.forEach\(\s*createLabel\s*\)/); +``` + +You should not pass a `createLabel` function call. + +```js +assert.notMatch(code, /letters\.forEach\(\s*createLabel\(\s*\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); +--fcc-editable-region-- + +--fcc-editable-region-- +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434750c53db16218f41e6e1.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434750c53db16218f41e6e1.md new file mode 100644 index 00000000000..ee5b7a363f8 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434750c53db16218f41e6e1.md @@ -0,0 +1,107 @@ +--- +id: 6434750c53db16218f41e6e1 +title: Step 15 +challengeType: 0 +dashedName: step-15 +--- + +# --description-- + +Remember that `range()` returns an array, so you can chain array methods directly to the function call. + +Call `range()` with `1` and `99` as the arguments, and chain the `.forEach()` method. Pass the `.forEach()` method an empty callback which takes `number` as the parameter. + +# --hints-- + +You should call your `range()` function. + +```js +assert.lengthOf(code.match(/range\(/g), 2); +``` + +You should pass `1` as the first argument to your `range()` call. + +```js +assert.match(code, /range\(\s*1/); +``` + +You should pass `99` as the second argument to your `range()` call. + +```js +assert.match(code, /range\(\s*1\s*,\s*99\s*\)/); +``` + +You should chain the `.forEach()` method to your `range()` call. + +```js +assert.match(code, /range\(\s*1\s*,\s*99\s*\)\.forEach\(/); +``` + +You should pass a callback function to `.forEach()` using arrow syntax. + +```js +assert.match(code, /range\(\s*1\s*,\s*99\s*\)\.forEach\(\s*\(?.*\)?\s*=>/); +``` + +Your callback function should have `number` as the only parameter. + +```js +assert.match(code, /range\(\s*1\s*,\s*99\s*\)\.forEach\(\s*\(?\s*number\s*\)?\s*=>/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); +--fcc-editable-region-- + +--fcc-editable-region-- +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434759f78ec812264ff8f34.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434759f78ec812264ff8f34.md new file mode 100644 index 00000000000..68ac4adb75e --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6434759f78ec812264ff8f34.md @@ -0,0 +1,109 @@ +--- +id: 6434759f78ec812264ff8f34 +title: Step 16 +challengeType: 0 +dashedName: step-16 +--- + +# --description-- + +In your callback, call `createLabel()` and pass `number` as the argument. You should see some numbers appear in your spreadsheet. + +Then call the `.forEach()` method on your `letters` array. Pass an empty callback function which takes a `letter` argument. + +# --hints-- + +You should call your `createLabel()` function. + +```js +assert.match(code, /range\(\s*1\s*,\s*99\s*\)\.forEach\(\s*\(?\s*number\s*\)?\s*=>\s*\{\s*createLabel\(/); +``` + +You should pass `number` to your `createLabel()` call. + +```js +assert.match(code, /range\(\s*1\s*,\s*99\s*\)\.forEach\(\s*\(?\s*number\s*\)?\s*=>\s*\{\s*createLabel\(/) +``` + +You should call the `.forEach()` method on your `letters` array. + +```js +assert.lengthOf(code.match(/letters\.forEach\(/g), 2) +``` + +You should pass a callback function with arrow syntax to your `.forEach()` method. + +```js +assert.match(code, /letters\.forEach\(\s*\(?.*\)?\s*=>\s*\{/) +``` + +Your callback function should have a `letter` parameter. + +```js +assert.match(code, /letters\.forEach\(\s*\(?\s*letter\s*\)?\s*=>\s*\{/) +``` + +Your callback function should be empty. + +```js +assert.match(code, /letters\.forEach\(\s*\(?\s*letter\s*\)?\s*=>\s*\{\s*\}/) +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); +--fcc-editable-region-- + range(1, 99).forEach(number => { + + }) +--fcc-editable-region-- +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643475e13dc727231acd0f72.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643475e13dc727231acd0f72.md new file mode 100644 index 00000000000..f6179caf013 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643475e13dc727231acd0f72.md @@ -0,0 +1,142 @@ +--- +id: 643475e13dc727231acd0f72 +title: Step 17 +challengeType: 0 +dashedName: step-17 +--- + +# --description-- + +Now in your nested `.forEach()` call, declare an `input` variable. Use the `.createElement()` method of the `document` object to create an `input` element. Set the `type` attribute to `text` and the `id` attribute to `letter + number`. + +For accessibility, set the `aria-label` attribute to the same value as the `id` attribute. + +# --hints-- + +You should declare an `input` variable. + +```js +assert.match(code, /(?:var|let|const)\s*input/) +``` + +You should use `const` to declare your `input` variable. + +```js +assert.match(code, /const\s*input/) +``` + +You should call the `.createElement()` method of the `document` object. + +```js +assert.lengthOf(code.match(/document\.createElement\(/g), 2) +``` + +You should pass the string `input` to the `.createElement()` method. + +```js +assert.match(code, /document\.createElement\(\s*('|"|`)input\1\s*\)/) +``` + +You should assign your new `input` element to your `input` variable. + +```js +assert.match(code, /const\s*input\s*=\s*document\.createElement\(\s*('|"|`)input\1\s*\)/) +``` + +You should access the `type` property of your `input` element. + +```js +assert.match(code, /input\.type/); +``` + +You should set the `type` attribute of your `input` element to `text`. + +```js +assert.match(code, /input\.type\s*=\s*('|"|`)text\1/) +``` + +You should access the `id` property of your `input` element. + +```js +assert.match(code, /input\.id/); +``` + +You should set the `id` attribute of your `input` element to `letter + number`. + +```js +assert.match(code, /input\.id\s*=\s*letter\s\+\snumber/) +``` + +You should access the `ariaLabel` property of your `input` element. + +```js +assert.match(code, /input\.ariaLabel/); +``` + +You should set the `aria-label` attribute of your `input` element to `letter + number`. + +```js +assert.match(code, /input\.ariaLabel\s*=\s*letter\s\+\snumber/) +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); +--fcc-editable-region-- + letters.forEach(letter => { + + }) +--fcc-editable-region-- + }) +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643498328cb52026123e2b91.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643498328cb52026123e2b91.md new file mode 100644 index 00000000000..f036d9ff9aa --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643498328cb52026123e2b91.md @@ -0,0 +1,92 @@ +--- +id: 643498328cb52026123e2b91 +title: Step 18 +challengeType: 0 +dashedName: step-18 +--- + +# --description-- + +Append the `input` element to your `container` element as a child. + +You should now be able to see the cells of your spreadsheet. + +# --hints-- + +You should call the `.appendChild()` method on your `container` element. + +```js +assert.lengthOf(code.match(/container\.appendChild\(/g), 2); +``` + +You should pass your `input` element to the `.appendChild()` method. + +```js +assert.match(code, /container\.appendChild\(\s*input\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); +--fcc-editable-region-- + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + + }) +--fcc-editable-region-- + }) +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643498755d54c6279ba09078.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643498755d54c6279ba09078.md new file mode 100644 index 00000000000..c190c5df99e --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643498755d54c6279ba09078.md @@ -0,0 +1,131 @@ +--- +id: 643498755d54c6279ba09078 +title: Step 19 +challengeType: 0 +dashedName: step-19 +--- + +# --description-- + +Most spreadsheet programs include built-in functions for calculation. + +Declare a `sum` function that takes a `nums` parameter, which will be an array of numbers. It should return the result of calling `reduce` on the array to sum all of the numbers. + +# --hints-- + +You should declare a `sum` variable. + +```js +assert.match(code, /(?:let|const|var)\s*sum/); +``` + +You should use `const` to declare your `sum` variable. + +```js +assert.match(code, /const\s*sum/); +``` + +Your `sum` variable should be a function. + +```js +assert.isFunction(sum); +``` + +Your `sum` function should use arrow syntax. + +```js +assert.match(code, /const\s*sum\s*=\(?.*\)?\s*=>/); +``` + +Your `sum` function should have a `nums` parameter. + +```js +assert.match(code, /const\s*sum\s*=\s*\(?\s*nums\s*\)?\s*=>/); +``` + +Your `sum` function should use an implicit return. + +```js +assert.notMatch(code, /const\s*sum\s*=\s*\(?\s*nums\s*\)?\s*=>\s*{/); +``` + +Your `sum` function should return the result of calling `.reduce()` on `nums`. + +```js +assert.match(code, /const\s*sum\s*=\(?\s*nums\s*\)?\s*=>\s*nums\.reduce\(/); +``` + +Your `sum` function should return the sum of all numbers in `nums`. + +```js +const numbers = [1, 2, 3, 4, 5]; +assert.equal(sum(numbers), 15); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- + +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + container.appendChild(input); + }) + }) +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6437124c4c03dd4c8fb35d56.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6437124c4c03dd4c8fb35d56.md new file mode 100644 index 00000000000..0380ef2a7aa --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6437124c4c03dd4c8fb35d56.md @@ -0,0 +1,133 @@ +--- +id: 6437124c4c03dd4c8fb35d56 +title: Step 20 +challengeType: 0 +dashedName: step-20 +--- + +# --description-- + +Declare an `isEven` function, which takes a `num` parameter and returns `true` if the number is even, and `false` otherwise. Use the modulo operator `%` to determine if a number is even or odd. + +# --hints-- + +You should declare an `isEven` variable. + +```js +assert.match(code, /(?:let|const|var)\s*isEven/); +``` + +You should use `const` to declare your `isEven` variable. + +```js +assert.match(code, /const\s*isEven/); +``` + +Your `isEven` variable should be a function. + +```js +assert.isFunction(isEven); +``` + +Your `isEven` function should use arrow syntax. + +```js +assert.match(code, /const\s*isEven\s*=\s*\(?.*\)?\s*=>/); +``` + +Your `isEven` function should have a `num` argument. + +```js +assert.match(code, /const\s*isEven\s*=\s*\(?\s*num\s*\)?\s*=>/); +``` + +Your `isEven` function should use the modulo operator `%`. + +```js +assert.match(isEven.toString(), /%/); +``` + +Your `isEven` function should return `true` for even numbers. + +```js +assert.isTrue(isEven(2)); +assert.isTrue(isEven(1000)); +assert.isTrue(isEven(42)); +``` + +Your `isEven` function should return `false` for odd numbers. + +```js +assert.isFalse(isEven(1)); +assert.isFalse(isEven(333)); +assert.isFalse(isEven(777777777)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- + +--fcc-editable-region-- +const sum = nums => nums.reduce((acc, el) => acc + el, 0); + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + container.appendChild(input); + }) + }) +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6437133052eaf04d7300e622.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6437133052eaf04d7300e622.md new file mode 100644 index 00000000000..1faf5d65bcf --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6437133052eaf04d7300e622.md @@ -0,0 +1,127 @@ +--- +id: 6437133052eaf04d7300e622 +title: Step 21 +challengeType: 0 +dashedName: step-21 +--- + +# --description-- + +Declare an `average` function which takes an array of numbers as the `nums` parameter. It should return the average of all the numbers in the array. + +The average can be calculated by dividing the sum of all the numbers in the array by the length of the array. Remember that you have a `sum` function you can use. + +# --hints-- + +You should declare an `average` variable. + +```js +assert.match(code, /(?:let|const|var)\s+average/); +``` + +You should use `const` to declare your `average` variable. + +```js +assert.match(code, /const\s+average/); +``` + +Your `average` variable should be a function. + +```js +assert.isFunction(average); +``` + +Your `average` function should use arrow syntax. + +```js +assert.match(code, /const\s+average\s*=\s*\(?.*\)?\s*=>/); +``` + +Your `average` function should have a `nums` parameter. + +```js +assert.match(code, /const\s+average\s*=\s*\(?\s*nums\s*\)?/); +``` + +Your `average` function should use an implicit return. + +```js +assert.notMatch(code, /const\s+average\s*=\s*\(?\s*nums\s*\)?\s*=>\s*{/); +``` + +Your `average` function should return the average value of the `nums` array. + +```js +assert.equal(average([1,2,3]), 2); +assert.equal(average([1,2,3,4,5]), 3); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +--fcc-editable-region-- + +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + container.appendChild(input); + }) + }) +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643715013330824ecaa70442.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643715013330824ecaa70442.md new file mode 100644 index 00000000000..e07b64fe6a1 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/643715013330824ecaa70442.md @@ -0,0 +1,154 @@ +--- +id: 643715013330824ecaa70442 +title: Step 22 +challengeType: 0 +dashedName: step-22 +--- + +# --description-- + +Your next function will calculate the median value of an array of numbers. Start by declaring a `median` arrow function that takes a `nums` parameter. + +In the function, declare a `sorted` variable and assign it the value of sorting a copy of the `nums` array. + +You should use the `slice()` method for creating a shallow copy of the array. + +# --hints-- + +You should declare a `median` variable. + +```js +assert.match(code, /(?:let|const|var)\s+median/); +``` + +You should use `const` to declare your `median` variable. + +```js +assert.match(code, /const\s+median/); +``` + +Your `median` variable should be a function. + +```js +assert.isFunction(median); +``` + +Your `median` function should use arrow syntax. + +```js +assert.match(code, /const\s+median\s*=\s*\(?/); +``` + +Your `median` function should have a `nums` parameter. + +```js +assert.match(code, /const\s+median\s*=\s*\(?\s*nums\s*\)?/); +``` + +Your `median` function should not use an implicit return. + +```js +assert.match(code, /const\s+median\s*=\s*\(?\s*nums\s*\)?\s*=>\s*\{/); +``` + +Your `median` function should have a `sorted` variable. + +```js +assert.match(code, /const\s+median\s*=\s*\(?\s*nums\s*\)?\s*=>\s*\{\s*(?:let|var|const)\s+sorted/); +``` + +You should use `const` to declare your `sorted` variable. + +```js +assert.match(code, /const\s+median\s*=\s*\(?\s*nums\s*\)?\s*=>\s*\{\s*const\s+sorted/); +``` + +You should use `.slice()` to assign a copy of the `nums` array to `sorted`. + +```js +assert.match(code, /const\s+median\s*=\s*\(?\s*nums\s*\)?\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)/); +``` + +You should chain the `.sort()` method to your `.slice()` method. + +```js +assert.match(code, /const\s+median\s*=\s*\(?\s*nums\s*\)?\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(/); +``` + +You should pass a callback function to your `sort` method to accurately sort the numbers in ascending order. Use an implicit return for clarity. + +```js +assert.match(code, /const\s+median\s*=\s*\(?\s*nums\s*\)?\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +--fcc-editable-region-- + +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + container.appendChild(input); + }) + }) +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496d1e5af8c0148fbef96d.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496d1e5af8c0148fbef96d.md new file mode 100644 index 00000000000..d9107f59a66 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496d1e5af8c0148fbef96d.md @@ -0,0 +1,129 @@ +--- +id: 64496d1e5af8c0148fbef96d +title: Step 23 +challengeType: 0 +dashedName: step-23 +--- + +# --description-- + +Now declare a `length` variable and assign it the length of your sorted array, and a `middle` variable that has the value of the length divided by `2`, subtracted by `1`. + +# --hints-- + +You should declare a `length` variable after your `sorted` variable. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*(?:var|let|const)\s+length/); +``` + +You should use `const` to declare your `length` variable. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length/); +``` + +You should assign the length of the `sorted` array to your `length` variable. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?/); +``` + +You should declare a `middle` variable after your `length` variable. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*(?:var|let|const)\s+middle/); +``` + +You should use `const` to declare your `middle` variable. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle/); +``` + +You should assign `middle` the value of dividing your `length` variable by `2`. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2/); +``` + +You should subtract `1` from your `length / 2` calculation. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2\s*-\s*1/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +--fcc-editable-region-- +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + container.appendChild(input); + }) + }) +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496d80bc174a158c973080.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496d80bc174a158c973080.md new file mode 100644 index 00000000000..40d5b6d8671 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496d80bc174a158c973080.md @@ -0,0 +1,143 @@ +--- +id: 64496d80bc174a158c973080 +title: Step 24 +challengeType: 0 +dashedName: step-24 +--- + +# --description-- + +Using ternary syntax, check if `length` is even using your `isEven` function. If it is, return the average of the number at the `middle` index and the number after that. If it's odd, return the number at the `middle` index – you'll need to round the `middle` value up. + +# --hints-- + +You should use the `return` keyword. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2\s*-\s*1\s*;?\s*return/); +``` + +You should call your `isEven()` function after your `return` keyword. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2\s*-\s*1\s*;?\s*return\s+isEven\(/); +``` + +You should pass your `length` variable to your `isEven()` call. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2\s*-\s*1\s*;?\s*return\s+isEven\(\s*length\s*\)/); +``` + +You should use ternary syntax to check the truthiness of your `isEven()` call. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2\s*-\s*1\s*;?\s*return\s+isEven\(\s*length\s*\)\s*\?/); +``` + +If the ternary is truthy, you should call your `average()` function. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2\s*-\s*1\s*;?\s*return\s+isEven\(\s*length\s*\)\s*\?\s*average\(/); +``` + +You should pass an array to your `average()` function. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2\s*-\s*1\s*;?\s*return\s+isEven\(\s*length\s*\)\s*\?\s*average\(\s*\[/); +``` + +The first element of the array passed to `average()` should be the element at the `middle` index of your `sorted` array. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2\s*-\s*1\s*;?\s*return\s+isEven\(\s*length\s*\)\s*\?\s*average\(\s*\[\s*sorted\[\s*middle\s*\]/); +``` + +The first element of the array passed to `average()` should be the element at the `middle + 1` index of your `sorted` array. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2\s*-\s*1\s*;?\s*return\s+isEven\(\s*length\s*\)\s*\?\s*average\(\s*\[\s*sorted\[\s*middle\s*\]\s*,\s*sorted\[\s*middle\s*\+\s*1\s*\]\s*\]\)/); +``` + +If the ternary is false, you should return the value of `sorted` at the `middle` index. Use `Math.ceil()` to round the `middle` value up. + +```js +assert.match(code, /const\s+median\s*=\s*nums\s*=>\s*\{\s*const\s+sorted\s*=\s*nums\.slice\(\s*\)\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*a\s*-\s*b\s*\)\s*\s*;?\s*const\s+length\s*=\s*sorted\.length;?\s*const\s+middle\s*=\s*length\s*\/\s*2\s*-\s*1\s*;?\s*return\s+isEven\(\s*length\s*\)\s*\?\s*average\(\s*\[\s*sorted\[\s*middle\s*\]\s*,\s*sorted\[\s*middle\s*\+\s*1\s*\]\s*\]\s*\)\s*:\s*sorted\[\s*Math\.ceil\(\s*middle\s*\)\s*\];?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +--fcc-editable-region-- +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + container.appendChild(input); + }) + }) +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496df724dd3716a71fe971.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496df724dd3716a71fe971.md new file mode 100644 index 00000000000..9422e15afaf --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496df724dd3716a71fe971.md @@ -0,0 +1,157 @@ +--- +id: 64496df724dd3716a71fe971 +title: Step 25 +challengeType: 0 +dashedName: step-25 +--- + +# --description-- + +To keep track of all of your spreadsheet's functions, delcare a `spreadsheetFunctions` object. Using destructuring syntax, set `sum`, `average`, and `median` as properties and values on the `spreadsheetFunctions` object. + +# --hints-- + +You should declare a `spreadsheetFunctions` variable. + +```js +assert.match(code, /(?:const|let|var)\s+spreadsheetFunctions/); +``` + +You should use `const` to declare your `spreadsheetFunctions` variable. + +```js +assert.match(code, /const\s+spreadsheetFunctions/); +``` + +Your `spreadsheetFunctions` variable should be an object. + +```js +assert.isObject(spreadsheetFunctions); +``` + +Your `spreadsheetFunctions` object should have a `sum` property. + +```js +assert.property(spreadsheetFunctions, "sum"); +``` + +Your `sum` property should be your `sum` function. + +```js +assert.equal(spreadsheetFunctions?.sum, sum); +``` + +Your `spreadsheetFunctions` object should have an `average` property. + +```js +assert.property(spreadsheetFunctions, "average"); +``` + +Your `average` property should be your `average` function. + +```js +assert.equal(spreadsheetFunctions?.average, average); +``` + +Your `spreadsheetFunctions` object should have a `median` property. + +```js +assert.property(spreadsheetFunctions, "median"); +``` + +Your `median` property should be your `median` function. + +```js +assert.equal(spreadsheetFunctions?.median, median); +``` + +You should use destructuring syntax to assign your properties. + +```js +const objectText = code.replace(/.*const\s*spreadsheetFunctions\s*=\s*\{([^}]*)}.*/s, "$1"); +assert.include(objectText, "sum"); +assert.include(objectText, "average"); +assert.include(objectText, "median"); +assert.notInclude(objectText, ":"); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + container.appendChild(input); + }) + }) +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496e9c6d7a2e189948e441.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496e9c6d7a2e189948e441.md new file mode 100644 index 00000000000..45011711b45 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64496e9c6d7a2e189948e441.md @@ -0,0 +1,129 @@ +--- +id: 64496e9c6d7a2e189948e441 +title: Step 26 +challengeType: 0 +dashedName: step-26 +--- + +# --description-- + +Now you can start using your spreadsheet functions. Begin by declaring an `update` arrow function. It should take an `event` parameter. + +# --hints-- + +You should declare an `update` variable. + +```js +assert.match(code, /(?:let|const|var)\s+update/); +``` + +You should use `const` to declare your `update` variable. + +```js +assert.match(code, /const\s+update/); +``` + +Your `update` variable should be a function. + +```js +assert.isFunction(update); +``` + +Your `update` function should take an `event` parameter. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>/); +``` + +Your `update` function should be empty. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + container.appendChild(input); + }) + }) +} + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449749d20436c1f1dfadcf2.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449749d20436c1f1dfadcf2.md new file mode 100644 index 00000000000..441a5da6cbb --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449749d20436c1f1dfadcf2.md @@ -0,0 +1,132 @@ +--- +id: 6449749d20436c1f1dfadcf2 +title: Step 27 +challengeType: 0 +dashedName: step-27 +--- + +# --description-- + +In your `window.onload` function, you need to tell your `input` elements to call the `update` function when the value changes. You can do this by directly setting the `onchange` property. + +Set the `onchange` property to be a reference to your `update` function. + +# --hints-- + +Your `window.onload` function should access the `onchange` property of the `input` element. + +```js +assert.match(window.onload.toString(), /input\.onchange/); +``` + +Your `window.onload` function should set the `onchange` property to `update`. + +```js +assert.match(window.onload.toString(), /input\.onchange\s*=\s*update/); +``` + +Your `window.onload` function should not call your `update` function. + +```js +assert.notMatch(window.onload.toString(), /update\(\s*\)/); +``` + +Your `input` elements should all have your `update` function as the `onchange` property. + +```js +const inputs = document.querySelectorAll('input'); +inputs.forEach(input => { + assert.property(input, 'onchange'); + assert.equal(input.onchange, update); +}) +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; +--fcc-editable-region-- + +--fcc-editable-region-- + container.appendChild(input); + }) + }) +} + +const update = event => { + +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449755666005520330cec5b.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449755666005520330cec5b.md new file mode 100644 index 00000000000..179b4592f0a --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449755666005520330cec5b.md @@ -0,0 +1,122 @@ +--- +id: 6449755666005520330cec5b +title: Step 28 +challengeType: 0 +dashedName: step-28 +--- + +# --description-- + +Since your `update` event is running as a `change` event listener, the `event` argument will be a change event. + +The `target` property of the change event represents the element that changed. Assign the `target` property to a new variable called `element`. + +# --hints-- + +You should declare an `element` variable in your `update` function. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*(?:var|let|const)\s+element/); +``` + +You should use `const` to declare your `element` variable. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element/); +``` + +You should assign the `target` property of the `event` argument to your `element` variable. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +--fcc-editable-region-- +const update = event => { + +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497da4062602213ecf32e7.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497da4062602213ecf32e7.md new file mode 100644 index 00000000000..aa40b2b445a --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497da4062602213ecf32e7.md @@ -0,0 +1,147 @@ +--- +id: 64497da4062602213ecf32e7 +title: Step 29 +challengeType: 0 +dashedName: step-29 +--- + +# --description-- + +Because the `change` event is triggering on an `input` element, the element will have a `value` property that represents the current value of the input. + +Assign the `value` property of `element` to a new variable called `value`, and use `.replace()` to remove all whitespace. + +# --hints-- + +You should declare a `value` variable after your `element` variable. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*(?:const|let|var)\s+value/); +``` + +You should use `const` to declare your `value` variable. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value/); +``` + +You should assign the `value` property of `element` to your `value` variable. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value/); +``` + +You should call the `.replace()` method on the `value` property of the `element`. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(/); +``` + +You should pass a regular expression to match whitespace to your `.replace()` method. Use the `\s` character class. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\//); +``` + +You should make your regular expression global. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g/); +``` + +You should pass an empty string as your second argument to the `.replace()` method. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +--fcc-editable-region-- +const update = event => { + const element = event.target; + +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497de936a2f322327e5c58.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497de936a2f322327e5c58.md new file mode 100644 index 00000000000..d8123352375 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497de936a2f322327e5c58.md @@ -0,0 +1,122 @@ +--- +id: 64497de936a2f322327e5c58 +title: Step 30 +challengeType: 0 +dashedName: step-30 +--- + +# --description-- + +Now you need to check if the `value` does not include the `id` of the element. Create an `if` condition to do so. + +# --hints-- + +You should create an `if` block. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(/); +``` + +Your `if` condition should check if `value` includes the `id` of the `element`. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*!value\.includes\(\s*element\.id\s*\)/); +``` + +Your `if` block should be empty. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*!value\.includes\(\s*element\.id\s*\)\s*\)\s*\{\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +--fcc-editable-region-- +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497e0e5e5a2c2329785af4.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497e0e5e5a2c2329785af4.md new file mode 100644 index 00000000000..94274ab2be7 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497e0e5e5a2c2329785af4.md @@ -0,0 +1,114 @@ +--- +id: 64497e0e5e5a2c2329785af4 +title: Step 31 +challengeType: 0 +dashedName: step-31 +--- + +# --description-- + +Spreadsheet software typically uses `=` at the beginning of a cell to indicate a calculation should be used, and spreadsheet functions should be evaluated. + +Update your `if` condition to also check if the first character of `value` is `=`. + +# --hints-- + +Your `if` condition should also check if the first character of `value` is `=`. You may use `[0]`, `.startsWith()`, or `.charAt(0)`. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +--fcc-editable-region-- +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id)) { + + } +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497e764135bd24b7960dd3.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497e764135bd24b7960dd3.md new file mode 100644 index 00000000000..010d9566ada --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64497e764135bd24b7960dd3.md @@ -0,0 +1,152 @@ +--- +id: 64497e764135bd24b7960dd3 +title: Step 32 +challengeType: 0 +dashedName: step-32 +--- + +# --description-- + +In order to run your spreadsheet functions, you need to be able to parse and evaluate the input string. This is a great time to use another function. + +Declare an `evalFormula` arrow function which takes the parameters `x` and `cells`. + +# --hints-- + +You should declare an `evalFormula` variable. + +```js +assert.match(code, /(?:let|const|var)\s*evalFormula/); +``` + +You should use `const` to declare your `evalFormula` variable. + +```js +assert.match(code, /const\s*evalFormula/); +``` + +Your `evalFormula` variable should be a function. + +```js +assert.isFunction(evalFormula); +``` + +Your `evalFormula` function should use arrow syntax. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(/); +``` + +Your `evalFormula` function should have `x` as the first parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x/); +``` + +Your `evalFormula` function should have `cells` as the second parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>/); +``` + +Your `evalFormula` function should be empty. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- + +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449842c6f6c84261075e4c9.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449842c6f6c84261075e4c9.md new file mode 100644 index 00000000000..935aa053795 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449842c6f6c84261075e4c9.md @@ -0,0 +1,166 @@ +--- +id: 6449842c6f6c84261075e4c9 +title: Step 33 +challengeType: 0 +dashedName: step-33 +--- + +# --description-- + +In your `evalFormula`, declare an `idToText` arrow function which takes an `id` parameter. + +Your `idToText` function should return the result of calling `.find()` on the `cells` array with a callback function that takes an `cell` parameter and returns `cell.id === id`. + +# --hints-- + +You should declare an `idToText` variable in your `evalFormula` function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*(?:const|let|var)\s+idToText/); +``` + +You should use `const` to declare your `idToText` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText/); +``` + +Your `idToText` variable should be an arrow function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?.*\)?\s*=>/); +``` + +Your `idToText` function should have an `id` parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>/); +``` + +You should assign `idToText` the result of calling the `.find()` method on your `cells` array. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(/); +``` + +You should pass a callback function to your `.find()` method. Use arrow syntax. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?.*\)?\s*=>/); +``` + +Your callback function should have a `cell` parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>/); +``` + +Your callback function should use an implicit return. + +```js +assert.notMatch(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*\{/); +``` + +Your callback function should return whether `cell.id` is strictly equal to `id`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498473a17adc26ef0ecc2d.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498473a17adc26ef0ecc2d.md new file mode 100644 index 00000000000..dd56044e660 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498473a17adc26ef0ecc2d.md @@ -0,0 +1,116 @@ +--- +id: 64498473a17adc26ef0ecc2d +title: Step 34 +challengeType: 0 +dashedName: step-34 +--- + +# --description-- + +Your `idToText` function currently returns an `input` element. Update it to return the `value` of that `input` element. + +# --hints-- + +You should return the `value` property of the return value of the `.find()` method. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449849b78f43527be1e8a98.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449849b78f43527be1e8a98.md new file mode 100644 index 00000000000..e27060dab09 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449849b78f43527be1e8a98.md @@ -0,0 +1,150 @@ +--- +id: 6449849b78f43527be1e8a98 +title: Step 35 +challengeType: 0 +dashedName: step-35 +--- + +# --description-- + +You need to be able to match cell ranges in a formula. Cell ranges can look like `A1:B12` or `A3:A25`. You can use a regular expression to match these patterns. + +Start by declaring a `rangeRegex` variable and assign it a regular expression that matches `A` through `J` (the range of columns in your spreadsheet). Use a capture group with a character class to achieve this. + +# --hints-- + +You should declare a `rangeRegex` variable after your `idToText` function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*(?:var|let|const)\s+rangeRegex/); +``` + +You should use `const` to declare your `rangeRegex` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex/); +``` + +Your `rangeRegex` variable should be a regular expression. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/.*\/;?/); +``` + +Your `rangeRegex` should use a capture group. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(.*\)\/;?/); +``` + +Your `rangeRegex` should use a character class in the capture group. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[.*\]\)\/;?/); +``` + +Your `rangeRegex` should use a character class to match `A` through `J`. + + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\/;?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498542cab69128ab24e4de.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498542cab69128ab24e4de.md new file mode 100644 index 00000000000..399ef9c1f26 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498542cab69128ab24e4de.md @@ -0,0 +1,149 @@ +--- +id: 64498542cab69128ab24e4de +title: Step 36 +challengeType: 0 +dashedName: step-36 +--- + +# --description-- + +After matching a cell letter successfully, your `rangeRegex` needs to match the cell number. Cell numbers in your sheet range from `1` to `99`. + +Add a capture group after your letter capture group. Your new capture group should match one or two digits – the first digit should be `1` through `9`, and the second digit should be `0` through `9`. The second digit should be optional. + +# --hints-- + +You should add a second capture group to your `rangeRegex`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(.*\)\/;?/); +``` + +Your second capture group should have a character class. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[.*\]\??\)\/;?/); +``` + +Your second capture group should have two character classes. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[.*\]\[.*\]\??\)\/;?/); +``` + +Your first new character class should match the digits `1` through `9`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[.*\]\??\)\/;?/); +``` + +Your second new character class should match the digits `0` through `9`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\??\)\/;?/); +``` + +Your second new character class should be optional. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/;?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])/; +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449860d84c9e22cbd7b497c.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449860d84c9e22cbd7b497c.md new file mode 100644 index 00000000000..d5dfb0a845e --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449860d84c9e22cbd7b497c.md @@ -0,0 +1,117 @@ +--- +id: 6449860d84c9e22cbd7b497c +title: Step 37 +challengeType: 0 +dashedName: step-37 +--- + +# --description-- + +Ranges are separated by a colon. After your two capture groups, your `rangeRegex` should look for a colon. + +# --hints-- + +You should add a colon after your second capture group. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\/;?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?)/; +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449863f592af72d9be0959e.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449863f592af72d9be0959e.md new file mode 100644 index 00000000000..b9aeec38582 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449863f592af72d9be0959e.md @@ -0,0 +1,143 @@ +--- +id: 6449863f592af72d9be0959e +title: Step 38 +challengeType: 0 +dashedName: step-38 +--- + +# --description-- + +After your `rangeRegex` finds the `:`, it needs to look for the same letter and number pattern as it did before. + +Copy your two existing capture groups and paste them after the colon. + +# --hints-- + +You should add a third capture group to your `rangeRegex`, after the colon. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(.*\)/); +``` + +Your third capture group should use a character class. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[.*\]\)/); +``` + +Your third capture group should match the characters `A` through `J`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)/); +``` + +You should add a fourth capture group to your `rangeRegex`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(.*\)/); +``` + +Your fourth capture group should match one or two digits. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):/; +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449874d5191562eb3313b3f.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449874d5191562eb3313b3f.md new file mode 100644 index 00000000000..da43051e048 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449874d5191562eb3313b3f.md @@ -0,0 +1,129 @@ +--- +id: 6449874d5191562eb3313b3f +title: Step 39 +challengeType: 0 +dashedName: step-39 +--- + +# --description-- + +Finally, make your `rangeRegex` global and case-insensitive. + +# --hints-- + +Your `rangeRegex` should be case-insensitive. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/g?i/); +``` + +Your `rangeRegex` should be global. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/i?g/); +``` + +Your `rangeRegex` should be both global and case-insensitive. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/; +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449876e7aae0d2f8257a497.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449876e7aae0d2f8257a497.md new file mode 100644 index 00000000000..d7d9aeb5284 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6449876e7aae0d2f8257a497.md @@ -0,0 +1,168 @@ +--- +id: 6449876e7aae0d2f8257a497 +title: Step 40 +challengeType: 0 +dashedName: step-40 +--- + +# --description-- + +Declare a `rangeFromString` arrow function that takes two parameters, `num1` and `num2`. The function should implicitly return the result of calling `range` with `num1` and `num2` as arguments. + +To be safe, parse `num1` and `num2` into integers as you pass them into `range`. + +# --hints-- + +You should declare a `rangeFromString` variable after your `rangeRegex`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*(?:var|let|const)\s+rangeFromString/); +``` + +You should use `const` to declare your `rangeFromString` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString/); +``` + +Your `rangeFromString` variable should be an arrow function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(?.*\)?\s*=>/); +``` + +Your `rangeFromString` function should have `num1` as the first parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(?\s*num1/); +``` + +Your `rangeFromString` function should have `num2` as the second parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>/); +``` + +Your `rangeFromString` function should use an implicit return. + +```js +assert.notMatch(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*\{/); +``` + +Your `rangeFromString` function should return the result of calling your `range` function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(/); +``` + +You should call `parseInt` with `num1` as an argument and pass the result to the `range` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)/); +``` + +You should call `parseInt` with `num2` as the argument and pass the result to the `range` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498b085028fc30a58bb6a7.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498b085028fc30a58bb6a7.md new file mode 100644 index 00000000000..d58c3fa4ce9 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/64498b085028fc30a58bb6a7.md @@ -0,0 +1,143 @@ +--- +id: 64498b085028fc30a58bb6a7 +title: Step 41 +challengeType: 0 +dashedName: step-41 +--- + +# --description-- + +Declare a function `elemValue` which takes a `num` parameter. The function should be empty. + +# --hints-- + +You should declare an `elemValue` variable after your `rangeFromString()` function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*(?:var|let|const)\s+elemValue/); +``` + +You should use `const` to declare your `elemValue` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue/); +``` + +Your `elemValue` variable should be an arrow function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?.*\)?\s*=>/); +``` + +Your `elemValue` function should have `num` as the only parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>/); +``` + +Your `elemValue` function should be empty. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0889c6ff4baa46ac1c50.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0889c6ff4baa46ac1c50.md new file mode 100644 index 00000000000..7c0c3e6d0e9 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0889c6ff4baa46ac1c50.md @@ -0,0 +1,153 @@ +--- +id: 646d0889c6ff4baa46ac1c50 +title: Step 42 +challengeType: 0 +dashedName: step-42 +--- + +# --description-- + +In your `elemValue` function, declare a function called `inner` which takes a `character` parameter. + +Then, return your `inner` function. + +# --hints-- + +You should declare an `inner` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*(?:var|let|const)\s+inner/); +``` + +You should use `const` to declare your `inner` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner/); +``` + +Your `inner` variable should be an arrow function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?.*\)?\s*=>/); +``` + +Your `inner` function should have `character` as the only parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>/); +``` + +Your `inner` function should be empty. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*\}/); +``` + +You should explicitly return your `inner` function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*\};?\s*return\s+inner/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => { + + } +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d09a07241aaab1e777080.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d09a07241aaab1e777080.md new file mode 100644 index 00000000000..b3a6c7e7d7b --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d09a07241aaab1e777080.md @@ -0,0 +1,136 @@ +--- +id: 646d09a07241aaab1e777080 +title: Step 43 +challengeType: 0 +dashedName: step-43 +--- + +# --description-- + +In your `inner` function, return the result of calling `idToText` with `character + num` as the argument. + +# --hints-- + +Your `inner` function should use an explicit return. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return/); +``` + +Your `inner` function should return the result of calling your `idToText` function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(/); +``` + +You should pass `character + num` as the argument to your `idToText` function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => { + const inner = character => { + + } + return inner; + } +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0a022da7bcabf3e3aca3.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0a022da7bcabf3e3aca3.md new file mode 100644 index 00000000000..f5ba0ed6d12 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0a022da7bcabf3e3aca3.md @@ -0,0 +1,160 @@ +--- +id: 646d0a022da7bcabf3e3aca3 +title: Step 44 +challengeType: 0 +dashedName: step-44 +--- + +# --description-- + +The concept of returning a function within a function is called currying. This approach allows you to create a variable that holds a function to be called later, but with a reference to the parameters of the outer function call. + +For example: + +```js +const innerOne = elemValue(1); +const final = innerOne("A"); +``` + +`innerOne` would be your `inner` function, with `num` set to `1`, and `final` would have the value of the cell with the `id` of `A1`. This is possible because functions have access to all variables declared at their creation. This is called closure. + +You'll get some more practice with this. Declare a function called `addCharacters` which takes a `character1` parameter. + +# --hints-- + +You should declare an `addCharacters` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*(?:var|let|const)\s+addCharacters/); +``` + +You should use `const` to declare your `addCharacters` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters/); +``` + +Your `addCharacters` variable should be an arrow function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?.*\)?\s*=>/); +``` + +Your `addCharacters` function should not use an implicit return. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?.*\)?\s*=>\s*\{/); +``` + +Your `addCharacters` function should have a `character1` parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => { + const inner = character => { + return idToText(character + num); + } + return inner; + } + +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0d20108440acc95a6b32.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0d20108440acc95a6b32.md new file mode 100644 index 00000000000..cd6f530d636 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0d20108440acc95a6b32.md @@ -0,0 +1,145 @@ +--- +id: 646d0d20108440acc95a6b32 +title: Step 45 +challengeType: 0 +dashedName: step-45 +--- + +# --description-- + +In your `elemValue` function, you explicitly declared a function called `inner` and returned it. However, because you are using arrow syntax, you can implicitly return a function. For example: + +```js +const curry = soup => veggies => {}; +``` + +`curry` is a function which takes a `soup` parameter and returns a function which takes a `veggies` parameter. Using this syntax, update your `addCharacters` function to return an empty function which takes a `character2` parameter. + +# --hints-- + +Your `addCharacters` function should use an implicit return. + +```js +assert.notMatch(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\{/); +``` + +Your `elemValue` function should return an arrow function which has a `character2` parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>/); +``` + +Your inner arrow function should be empty. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\{\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => { + const inner = character => { + return idToText(character + num); + } + return inner; + } + const addCharacters = character1 => { + + } +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0db5175974ad8633b71c.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0db5175974ad8633b71c.md new file mode 100644 index 00000000000..31875191914 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0db5175974ad8633b71c.md @@ -0,0 +1,133 @@ +--- +id: 646d0db5175974ad8633b71c +title: Step 46 +challengeType: 0 +dashedName: step-46 +--- + +# --description-- + +Your inner functions can also return a function. Using the same arrow syntax, update your `addCharacters` function to return a third function which takes a `num` parameter. + +# --hints-- + +Your inner arrow function should return another arrow function with a `num` parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>/); +``` + +Your inner-most arrow function should be empty. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*\{\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => { + const inner = character => { + return idToText(character + num); + } + return inner; + } + const addCharacters = character1 => character2 => { + + } +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0e4636e14eae2bb3b992.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0e4636e14eae2bb3b992.md new file mode 100644 index 00000000000..1d41054a373 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d0e4636e14eae2bb3b992.md @@ -0,0 +1,145 @@ +--- +id: 646d0e4636e14eae2bb3b992 +title: Step 47 +challengeType: 0 +dashedName: step-47 +--- + +# --description-- + +Now update your innermost function in the `addCharacters` chain to implicitly return the result of calling `charRange()` with `character1` and `character2` as the arguments. + +# --hints-- + +Your innermost function should use an implicit return. + +```js +assert.notMatch(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*\{/); +``` + +Your innermost function should return the result of calling `charRange()`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(/); +``` + +You should pass `character1` as the first argument to your `charRange()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1/); +``` + +You should pass `character2` as the second argument to your `charRange()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{\s*const\s+inner\s*=\s*\(?\s*character\s*\)?\s*=>\s*\{\s*return\s+idToText\(\s*character\s*\+\s*num\s*\);?\s*};?\s*return\s+inner;?\s*\}\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => { + const inner = character => { + return idToText(character + num); + } + return inner; + } + const addCharacters = character1 => character2 => num => { + + } +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1980018efaaec2b1c28b.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1980018efaaec2b1c28b.md new file mode 100644 index 00000000000..b5f8c3a18a7 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1980018efaaec2b1c28b.md @@ -0,0 +1,143 @@ +--- +id: 646d1980018efaaec2b1c28b +title: Step 48 +challengeType: 0 +dashedName: step-48 +--- + +# --description-- + +Use the same syntax as your `addCharacters` function to update your `elemValue` function. It should no longer declare `inner`, but should return the function implicitly. + +# --hints-- + +Your `elemValue` function should use an implicit return. + +```js +assert.notMatch(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\{/); +``` + +Your `elemValue` function should implicitly return an arrow function with a `character` parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>/); +``` + +Your inner arrow function should use an implicit return. + +```js +assert.notMatch(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*\{/); +``` + +Your inner arrow function should return the result of calling `idToText()` with `character + num` as the argument. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => { + const inner = character => { + return idToText(character + num); + } + return inner; + } + const addCharacters = character1 => character2 => num => charRange(character1, character2); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d19fc4705e4af65c3e688.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d19fc4705e4af65c3e688.md new file mode 100644 index 00000000000..9b47d29ec54 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d19fc4705e4af65c3e688.md @@ -0,0 +1,126 @@ +--- +id: 646d19fc4705e4af65c3e688 +title: Step 49 +challengeType: 0 +dashedName: step-49 +--- + +# --description-- + +Your `addCharacters` function ultimately returns a range of characters. You want it to return an array of cell ids. Chain the `.map()` method to your `charRange()` call. Do not pass a callback function yet. + +# --hints-- + +You should chain `.map()` to your `charRange()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(/); +``` + +You should not pass anything to your `.map()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1b96dd7ea4b0061458bc.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1b96dd7ea4b0061458bc.md new file mode 100644 index 00000000000..0be2bf866f9 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1b96dd7ea4b0061458bc.md @@ -0,0 +1,136 @@ +--- +id: 646d1b96dd7ea4b0061458bc +title: Step 50 +challengeType: 0 +dashedName: step-50 +--- + +# --description-- + +You can pass a function reference as a callback parameter. A function reference is a function name without the parentheses. For example: + +```js +const myFunc = (val) => `value: ${val}`; +const array = [1, 2, 3]; +const newArray = array.map(myFunc); +``` + +The `.map()` method here will call the `myFunc` function, passing the same arguments that a `.map()` callback takes. The first argument is the value of the array at the current iteration, so `newArray` would be `[value: 1, value: 2, value: 3]`. + +Pass a reference to your `elemValue` function as the callback to your `.map()` method. + +# --hints-- + +You should not call your `elemValue` function. + +```js +assert.notMatch(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\)\s*\)/); +``` + +You should pass a reference to `elemValue` as the callback to your `.map()` method. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1cadf0d96ab0b7e12da4.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1cadf0d96ab0b7e12da4.md new file mode 100644 index 00000000000..b051ce72f9d --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1cadf0d96ab0b7e12da4.md @@ -0,0 +1,128 @@ +--- +id: 646d1cadf0d96ab0b7e12da4 +title: Step 51 +challengeType: 0 +dashedName: step-51 +--- + +# --description-- + +Because `elemValue` returns a function, your `addChars` function ultimately returns an array of function references. You want the `.map()` method to run the inner function of your `elemValue` function, which means you need to call `elemValue` instead of reference it. Pass `num` as the argument to your `elemValue` function. + + + +# --hints-- + +You should call `elemValue()` in your `.map()` method. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(/); +``` + +You should pass `num` to your `elemValue()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1d67f9261fb15a795588.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1d67f9261fb15a795588.md new file mode 100644 index 00000000000..545bcf46f72 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1d67f9261fb15a795588.md @@ -0,0 +1,139 @@ +--- +id: 646d1d67f9261fb15a795588 +title: Step 52 +challengeType: 0 +dashedName: step-52 +--- + +# --description-- + +Declare a `rangeExpanded` variable and assign it the result of calling the `.replace()` method of your `x` parameter. Pass the `rangeRegex` variable as the argument. + +# --hints-- + +You should declare a `rangeExpanded` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*(?:let|var|const)\s+rangeExpanded/); +``` + +You should use `const` to declare your `rangeExpanded` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded/); +``` + +You should assign the result of calling `.replace()` on `x` to your `rangeExpanded` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(/); +``` + +You should pass `rangeRegex` as the argument to `.replace()`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1e531042dfb24da1f032.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1e531042dfb24da1f032.md new file mode 100644 index 00000000000..7eaca45c1ad --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d1e531042dfb24da1f032.md @@ -0,0 +1,129 @@ +--- +id: 646d1e531042dfb24da1f032 +title: Step 53 +challengeType: 0 +dashedName: step-53 +--- + +# --description-- + +The second argument to the `.replace()` method does not have to be a string. You can instead pass a callback function to run more complex logic on the matched string. + +The callback function takes a few parameters. The first is the matched string. Pass an empty callback function to your `.replace()` call, and give it a `match` parameter. + +# --hints-- + +You should pass an arrow function as the second argument to your `.replace()` method. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(.*\)\s*=>\s*\{\s*\}\)/); +``` + +Your arrow function should take a `match` parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*\)\s*=>\s*\{\s*\}\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3141790b3cb337dd611a.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3141790b3cb337dd611a.md new file mode 100644 index 00000000000..e729cc223ff --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3141790b3cb337dd611a.md @@ -0,0 +1,141 @@ +--- +id: 646d3141790b3cb337dd611a +title: Step 54 +challengeType: 0 +dashedName: step-54 +--- + +# --description-- + +The callback function then has a parameter for each capture group in the regular expression. In your case, `rangeRegex` has four capture groups: the first letter, the first numbers, the second letter, and the second numbers. + +Give your callback function four more parameters to match those capture groups: `char1`, `num1`, `char2`, and `num2`. `char` will be short for `character`. + +# --hints-- + +You should pass `char1` as the second argument to your callback. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1/); +``` + +You should pass `num1` as the third argument to your callback. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1/); +``` + +You should pass `char2` as the fourth argument to your callback. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2/); +``` + +You should pass `num2` as the fifth argument to your callback. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (match) => {}); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d382c4d70ceb3dba1e830.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d382c4d70ceb3dba1e830.md new file mode 100644 index 00000000000..76c1950e846 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d382c4d70ceb3dba1e830.md @@ -0,0 +1,139 @@ +--- +id: 646d382c4d70ceb3dba1e830 +title: Step 55 +challengeType: 0 +dashedName: step-55 +--- + +# --description-- + +Have your callback implicitly return the result of calling `rangeFromString()` with `num1` and `num2` as the arguments. + +# --hints-- + +Your callback should use an implicit return. + +```js +assert.notMatch(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*\{/); +``` + +Your callback should return the result of calling `rangeFromString()`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(/); +``` + +You should pass `num1` as the first argument to your `rangeFromString()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1/); +``` + +You should pass `num2` as the second argument to your `rangeFromString()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (match, char1, num1, char2, num2) => {}); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d386a685620b49db4be76.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d386a685620b49db4be76.md new file mode 100644 index 00000000000..ac10f535130 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d386a685620b49db4be76.md @@ -0,0 +1,127 @@ +--- +id: 646d386a685620b49db4be76 +title: Step 56 +challengeType: 0 +dashedName: step-56 +--- + +# --description-- + +Call the `.map()` method on your `rangeFromString()` call, passing a reference to `addCharacters` as the callback function. + +# --hints-- + +You should call the `.map()` method on your `rangeFromString()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(/); +``` + +You should pass a reference to `addCharacters` as the callback to your `.map()` method. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (match, char1, num1, char2, num2) => rangeFromString(num1, num2)); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d38c326f3c8b54023de38.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d38c326f3c8b54023de38.md new file mode 100644 index 00000000000..993479b22a3 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d38c326f3c8b54023de38.md @@ -0,0 +1,127 @@ +--- +id: 646d38c326f3c8b54023de38 +title: Step 57 +challengeType: 0 +dashedName: step-57 +--- + +# --description-- + +`addCharacters` returns a function, so you'll want to call it. Pass `char1` as the argument. + +# --hints-- + +You should call your `addCharacters()` function in your `.map()` method. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*/); +``` + +You should pass `char1` as the argument to your `addCharacters()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters)); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d38f906b94cb5fe6ce7de.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d38f906b94cb5fe6ce7de.md new file mode 100644 index 00000000000..40d2718012d --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d38f906b94cb5fe6ce7de.md @@ -0,0 +1,133 @@ +--- +id: 646d38f906b94cb5fe6ce7de +title: Step 58 +challengeType: 0 +dashedName: step-58 +--- + +# --description-- + +Your `addCharacters(char1)` is also returning a function, which returns another function. You need to make another function call to access that innermost function reference for the `.map()` callback. JavaScript allows you to chain function calls: + +```js +myFunc(1)("hi"); +``` + +Chain a function call to your `addCharacters(char1)` call, and pass `char2` as the argument. + +# --hints-- + +You should chain a function call to your `addCharacters(char1)` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(/); +``` + +You should pass `char2` as the argument to your chained function call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1))); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3952f6af37b6a1c241c2.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3952f6af37b6a1c241c2.md new file mode 100644 index 00000000000..d2893b1aaaf --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3952f6af37b6a1c241c2.md @@ -0,0 +1,125 @@ +--- +id: 646d3952f6af37b6a1c241c2 +title: Step 59 +challengeType: 0 +dashedName: step-59 +--- + +# --description-- + +Now that your `.map()` function is receiving the innermost function reference from `addCharacters`, it will properly iterate over the elements and pass each element as `n` to that function. + +You'll notice that you are not using your `match` parameter. In JavaScript, it is common convention to prefix an unused parameter with an underscore `_`. You could also leave the parameter empty like so: `(, char1)` but it is often clearer to name the parameter for future readability. + +Prefix your `match` parameter with an underscore. + +# --hints-- + +You should prefix your `match` parameter with an underscore. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d39c156fe94b7482c3ab6.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d39c156fe94b7482c3ab6.md new file mode 100644 index 00000000000..62616ff4ed8 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d39c156fe94b7482c3ab6.md @@ -0,0 +1,164 @@ +--- +id: 646d39c156fe94b7482c3ab6 +title: Step 60 +challengeType: 0 +dashedName: step-60 +--- + +# --description-- + +Declare a variable `cellRegex` to match cell references. It should match a letter from `A` to `J`, followed by a digit from `1` to `9`, and an optional digit from `0` to `9`. Make the regular expression case-insensitive and global. + +# --hints-- + +You should declare a `cellRegex` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*(?:var|let|const)\s+cellRegex/); +``` + +You should use `const` to declare your `cellRegex` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex/); +``` + +You should assign a regular expression to your `cellRegex` variables. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\//); +``` + +Your regular expression should use a character class to match the characters from `A` to `J`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]/); +``` + +Your regular expression should use a character class to match the digits from `1` to `9`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]/); +``` + +Your regular expression should use a character class to match the digits from `0` to `9`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]/); +``` + +Your third character class should be optional. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?/); +``` + +Your regular expression should be case-insensitive and global. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3b27cd3c56b875256301.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3b27cd3c56b875256301.md new file mode 100644 index 00000000000..b2e33396e30 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3b27cd3c56b875256301.md @@ -0,0 +1,159 @@ +--- +id: 646d3b27cd3c56b875256301 +title: Step 61 +challengeType: 0 +dashedName: step-61 +--- + +# --description-- + +Declare a `cellExpanded` variable and assign it the value of calling `.replace()` on your `rangeExpanded` variable. Pass it your `cellRegex` and an empty callback function. The callback function should take a `match` parameter. + +# --hints-- + +You should declare a `cellExpanded` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*(var|let|const)\s+cellExpanded/); +``` + +You should use `const` to declare your `cellExpanded` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded/); +``` + +You should assign `cellExpanded` the result of calling the `.replace()` method of `rangeExpanded`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(/); +``` + +You should pass `cellRegex` as the first argument to your `.replace()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex/); +``` + +You should pass a callback function using arrow syntax as the second argument to your `.replace()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*(?:match)?\s*\)?\s*=>/); +``` + +Your callback function should have a `match` parameter. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>/); +``` + +Your callback function should be empty. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*\{\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3bc75fe0c9b972da3323.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3bc75fe0c9b972da3323.md new file mode 100644 index 00000000000..ad4c210898c --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3bc75fe0c9b972da3323.md @@ -0,0 +1,141 @@ +--- +id: 646d3bc75fe0c9b972da3323 +title: Step 62 +challengeType: 0 +dashedName: step-62 +--- + +# --description-- + +Update your callback function to return the result of calling `idToText()` with `match` as the argument. Remember that your regular expression is case-insensitive, so you will need to call `toUpperCase()` on `match` before passing it to `idToText()`. + +# --hints-- + +Your callback function should use an implicit return. + +```js +assert.notMatch(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*\{/); +``` + +Your callback function should call `idToText()`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(/); +``` + +You should pass `match` to your `idToText()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\s*/); +``` + +You should call the `.toUpperCase()` method of `match` as you pass it to `idToText()`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => {}) +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3c146e10b0ba222bb2a7.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3c146e10b0ba222bb2a7.md new file mode 100644 index 00000000000..b3816a73b01 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3c146e10b0ba222bb2a7.md @@ -0,0 +1,145 @@ +--- +id: 646d3c146e10b0ba222bb2a7 +title: Step 63 +challengeType: 0 +dashedName: step-63 +--- + +# --description-- + +In mathematics, an infix is a mathematical operator that appears between its two operands. For example, `1 + 2` is an infix expression. + +To parse these expressions, you will need to map the symbols to relevant functions. Declare an `infixToFunction` variable, and assign it an empty object. + +# --hints-- + +You should declare an `infixToFunction` variable. + +```js +assert.match(code, /(?:const|let|var)\s+infixToFunction/); +``` + +You should use `const` to declare your `infixToFunction` variable. + +```js +assert.match(code, /const\s+infixToFunction/); +``` + +Your `infixToFunction` variable should be an object. + +```js +assert.isObject(infixToFunction); +``` + +Your `infixToFunction` object should be empty. + +```js +assert.lengthOf(Object.keys(infixToFunction), 0); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- + +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d037872fbbae0a8ec0e.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d037872fbbae0a8ec0e.md new file mode 100644 index 00000000000..837aebe275a --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d037872fbbae0a8ec0e.md @@ -0,0 +1,167 @@ +--- +id: 646d3d037872fbbae0a8ec0e +title: Step 64 +challengeType: 0 +dashedName: step-64 +--- + +# --description-- + +Object values do not have to be primitive types, like a string or a number. They can also be functions. + +Give your `infixToFunction` object a `+` property. That property should be a function that takes an `x` and `y` parameter and implicitly returns the sum of those two parameters. + +Because `+` is not alphanumeric, you'll need to wrap it in quotes for your property. + +# --hints-- + +Your `infixToFunction` object should have a `+` property. + +```js +assert.property(infixToFunction, '+'); +``` + +Your `+` property should be a function. + +```js +assert.isFunction(infixToFunction['+']); +``` + +Your `+` function should use arrow syntax. + +```js +assert.match(code, /const\s+infixToFunction\s*=\s*\{\s*('|"|`)\+\1\s*:\s*\(/); +``` + +Your `+` function should have `x` as its first parameter. + +```js +assert.match(code, /const\s+infixToFunction\s*=\s*\{\s*('|"|`)\+\1\s*:\s*\(\s*x/); +``` + +Your `+` function should have `y` as its second parameter. + +```js +assert.match(code, /const\s+infixToFunction\s*=\s*\{\s*('|"|`)\+\1\s*:\s*\(\s*x\s*,\s*y\s*\)/); +``` + +Your `+` function should use an implicit return. + +```js +assert.notMatch(code, /const\s+infixToFunction\s*=\s*\{\s*('|"|`)\+\1\s*:\s*\(\s*x\s*,\s*y\s*\)\s*\{/); +``` + +Your `+` function should return the sum of `x` and `y`. + +```js +assert.equal(infixToFunction['+'](1, 2), 3); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- +const infixToFunction = { + +} +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d65be79c8bb9c7df9ff.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d65be79c8bb9c7df9ff.md new file mode 100644 index 00000000000..a525cab6136 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d65be79c8bb9c7df9ff.md @@ -0,0 +1,164 @@ +--- +id: 646d3d65be79c8bb9c7df9ff +title: Step 65 +challengeType: 0 +dashedName: step-65 +--- + +# --description-- + +Now create a `-` property that is a function that takes an `x` and `y` parameter and implicitly returns the result of subtracting `y` from `x`. + +# --hints-- + +Your `infixToFunction` object should have a `-` property. + +```js +assert.property(infixToFunction, '-'); +``` + +Your `-` property should be a function. + +```js +assert.isFunction(infixToFunction['-']); +``` + +Your `-` function should use arrow syntax. + +```js +assert.match(code, /('|"|`)-\1\s*:\s*\(/); +``` + +Your `-` function should have `x` as its first parameter. + +```js +assert.match(code, /('|"|`)-\1\s*:\s*\(\s*x/); +``` + +Your `-` function should have `y` as its second parameter. + +```js +assert.match(code, /('|"|`)-\1\s*:\s*\(\s*x\s*,\s*y\s*\)/); +``` + +Your `-` function should use an implicit return. + +```js +assert.notMatch(code, /('|"|`)-\1\s*:\s*\(\s*x\s*,\s*y\s*\)\s*\{/); +``` + +Your `-` function should return the result of subtracting `y` from `x`. + +```js +assert.equal(infixToFunction['-'](1, 2), -1); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- +const infixToFunction = { + "+": (x, y) => x + y, + +} +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d80c3b4aebc4103618e.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d80c3b4aebc4103618e.md new file mode 100644 index 00000000000..16e5f6e6860 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3d80c3b4aebc4103618e.md @@ -0,0 +1,207 @@ +--- +id: 646d3d80c3b4aebc4103618e +title: Step 66 +challengeType: 0 +dashedName: step-66 +--- + +# --description-- + +Following the same pattern, add a property for multiplication `*` and division `/` with the appropriate functions. + +# --hints-- + +Your `infixToFunction` object should have a `*` property. + +```js +assert.property(infixToFunction, '*'); +``` + +Your `*` property should be a function. + +```js +assert.isFunction(infixToFunction['*']); +``` + +Your `*` function should use arrow syntax. + +```js +assert.match(code, /('|"|`)\*\1\s*:\s*\(/); +``` + +Your `*` function should have `x` as its first parameter. + +```js +assert.match(code, /('|"|`)\*\1\s*:\s*\(\s*x/); +``` + +Your `*` function should have `y` as its second parameter. + +```js +assert.match(code, /('|"|`)\*\1\s*:\s*\(\s*x\s*,\s*y\s*\)/); +``` + +Your `*` function should use an implicit return. + +```js +assert.notMatch(code, /('|"|`)\*\1\s*:\s*\(\s*x\s*,\s*y\s*\)\s*\{/); +``` + +Your `*` function should return the result of multiplying `x` by `y`. + +```js +assert.equal(infixToFunction['*'](2, 5), 10); +``` + +Your `infixToFunction` object should have a `/` property. + +```js +assert.property(infixToFunction, '/'); +``` + +Your `/` property should be a function. + +```js +assert.isFunction(infixToFunction['/']); +``` + +Your `/` function should use arrow syntax. + +```js +assert.match(code, /('|"|`)\/\1\s*:\s*\(/); +``` + +Your `/` function should have `x` as its first parameter. + +```js +assert.match(code, /('|"|`)\/\1\s*:\s*\(\s*x/); +``` + +Your `/` function should have `y` as its second parameter. + +```js +assert.match(code, /('|"|`)\/\1\s*:\s*\(\s*x\s*,\s*y\s*\)/); +``` + +Your `/` function should use an implicit return. + +```js +assert.notMatch(code, /('|"|`)\/\1\s*:\s*\(\s*x\s*,\s*y\s*\)\s*\{/); +``` + +Your `/` function should return the result of dividing `x` by `y`. + +```js +assert.equal(infixToFunction['/'](10, 2), 5); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +--fcc-editable-region-- +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + +} +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3da8501e15bcd355ba1d.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3da8501e15bcd355ba1d.md new file mode 100644 index 00000000000..cc013f1dae7 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3da8501e15bcd355ba1d.md @@ -0,0 +1,186 @@ +--- +id: 646d3da8501e15bcd355ba1d +title: Step 67 +challengeType: 0 +dashedName: step-67 +--- + +# --description-- + +Now that you have your infix functions, you need a way to evaluate them. Declare an `infixEval` function which takes two parameters, `str` and `regex`. It should implicitly return the `.replace()` method of `str`, with `regex` and an empty callback as the arguments. + +# --hints-- + +You should declare an `infixEval` variable. + +```js +assert.match(code, /(?:var|let|const)\s+infixEval\s*=/); +``` + +You should use `const` to declare your `infixEval` variable. + +```js +assert.match(code, /const\s+infixEval\s*=/); +``` + +Your `infixEval` variable should be a function. + +```js +assert.isFunction(infixEval); +``` + +Your `infixEval` function should use arrow syntax. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(/); +``` + +Your `infixEval` function should have `str` as its first parameter. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str/); +``` + +Your `infixEval` function should have `regex` as its second parameter. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)/); +``` + +Your `infixEval` function should use an implicit return. + +```js +assert.notMatch(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*\{/); +``` + +Your `infixEval` function should return the result of calling the `.replace()` method on `str`. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(/); +``` + +You should pass `regex` as the first argument to the `.replace()` method. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex/); +``` + +You should pass an empty arrow function as the second argument to the `.replace()` method. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*\)\s*=>\s*\{\s*\}\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3e135ab3abbdbfe5c899.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3e135ab3abbdbfe5c899.md new file mode 100644 index 00000000000..a96beee9c4f --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3e135ab3abbdbfe5c899.md @@ -0,0 +1,164 @@ +--- +id: 646d3e135ab3abbdbfe5c899 +title: Step 68 +challengeType: 0 +dashedName: step-68 +--- + +# --description-- + +Your callback needs four parameters. `match`, `arg1`, `operator`, and `arg2`. + +You will not be using the `match` parameter, so remember to prefix it. + +# --hints-- + +Your callback function should have `match` as the first parameter. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_?match/); +``` + +Your `match` parameter should be prefixed with an underscore. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match/); +``` + +Your callback function should have `arg1` as the second parameter. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1/); +``` + +Your callback function should have `operator` as the third parameter. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator/); +``` + +Your callback function should have `arg2` as the fourth parameter. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator\s*,\s*arg2\s*\)/); +``` + +Your callback function should still be empty. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator\s*,\s*arg2\s*\)\s*=>\s*\{\s*\}\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +--fcc-editable-region-- +const infixEval = (str, regex) => str.replace(regex, () => {}); +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3e64b15f92be6e61704e.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3e64b15f92be6e61704e.md new file mode 100644 index 00000000000..935e885b98a --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3e64b15f92be6e61704e.md @@ -0,0 +1,146 @@ +--- +id: 646d3e64b15f92be6e61704e +title: Step 69 +challengeType: 0 +dashedName: step-69 +--- + +# --description-- + +The `regex` you will be passing to your `infixEval` function will match two numbers with an operator between them. The first number will be assigned to `arg1` in the callback, the second to `arg2`, and the operator to `operator`. + +Have your callback function implicitly return the `operator` property of your `infixToFunction` object. Remember that `operator` is a variable which holds the property name, not the actual property name. + +# --hints-- + +Your callback should use an implicit return. + +```js +assert.notMatch(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator\s*,\s*arg2\s*\)\s*=>\s*\{/); +``` + +Your callback function should access the `infixToFunction` object. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator\s*,\s*arg2\s*\)\s*=>\s*infixToFunction/); +``` + +Your callback function should use bracket notation to access the property of the `infixToFunction` object that matches the value of the `operator` argument. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator\s*,\s*arg2\s*\)\s*=>\s*infixToFunction\[\s*operator\s*\]\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +--fcc-editable-region-- +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => {}); +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3ee7b17ae3bf48610033.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3ee7b17ae3bf48610033.md new file mode 100644 index 00000000000..70bf445b5cf --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3ee7b17ae3bf48610033.md @@ -0,0 +1,144 @@ +--- +id: 646d3ee7b17ae3bf48610033 +title: Step 70 +challengeType: 0 +dashedName: step-70 +--- + +# --description-- + +`infixToFunction[operator]` returns a function. Call that function directly, passing `arg1` and `arg2` as the arguments. + +# --hints-- + +Your callback function should return the result of calling `infixToFunction[operator]`. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator\s*,\s*arg2\s*\)\s*=>\s*infixToFunction\[\s*operator\s*\]\(/); +``` + +You should pass `arg1` as the first argument to your `infixToFunction[operator]` call. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator\s*,\s*arg2\s*\)\s*=>\s*infixToFunction\[\s*operator\s*\]\(\s*arg1/); +``` + +You should pass `arg2` as the second argument to your `infixToFunction[operator]` call. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator\s*,\s*arg2\s*\)\s*=>\s*infixToFunction\[\s*operator\s*\]\(\s*arg1\s*,\s*arg2\s*\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +--fcc-editable-region-- +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator]); +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3f1fd12f76c02c823bb8.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3f1fd12f76c02c823bb8.md new file mode 100644 index 00000000000..27f21057126 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3f1fd12f76c02c823bb8.md @@ -0,0 +1,140 @@ +--- +id: 646d3f1fd12f76c02c823bb8 +title: Step 71 +challengeType: 0 +dashedName: step-71 +--- + +# --description-- + +You have a slight bug. `arg1` and `arg2` are strings, not numbers. `infixToFunction['+']("1", "2")` would return `12`, which is not mathematically correct. + +Wrap each of your `infixToFunction[operator]` arguments in a `parseFloat()` call. + +# --hints-- + +You should wrap `arg1` in a `parseFloat()` call. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator\s*,\s*arg2\s*\)\s*=>\s*infixToFunction\[\s*operator\s*\]\(\s*parseFloat\(\s*arg1\s*\)\s*,/); +``` + +You should wrap `arg2` in a `parseFloat()` call. + +```js +assert.match(code, /const\s+infixEval\s*=\s*\(\s*str\s*,\s*regex\s*\)\s*=>\s*str\.replace\(\s*regex\s*,\s*\(\s*_match\s*,\s*arg1\s*,\s*operator\s*,\s*arg2\s*\)\s*=>\s*infixToFunction\[\s*operator\s*\]\(\s*parseFloat\(\s*arg1\s*\)\s*,\s*parseFloat\(\s*arg2\s*\)\s*\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +--fcc-editable-region-- +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](arg1, arg2)); +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3f718b5f8dc102cd528e.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3f718b5f8dc102cd528e.md new file mode 100644 index 00000000000..e8de07b79d4 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d3f718b5f8dc102cd528e.md @@ -0,0 +1,164 @@ +--- +id: 646d3f718b5f8dc102cd528e +title: Step 72 +challengeType: 0 +dashedName: step-72 +--- + +# --description-- + +Now that you can evaluate mathematical expressions, you need to account for order of operations. Declare a `highPrecedence` function that takes a `str` parameter. + +# --hints-- + +You should declare a `highPrecedence` variable. + +```js +assert.match(code, /(?:var|let|const)\s+highPrecedence/); +``` + +You should use `const` to declare your `highPrecedence` variable. + +```js +assert.match(code, /const\s+highPrecedence/); +``` + +Your `highPrecedence` variable should be a function. + +```js +assert.isFunction(highPrecedence); +``` + +Your `highPrecedence` function should use arrow syntax. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*(?:str)?\s*\)?\s*=>/); +``` + +Your `highPrecedence` function should have a `str` parameter. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>/); +``` + +Your `highPrecedence` function should be empty. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +--fcc-editable-region-- + +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d404259f512c1a9e86ac1.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d404259f512c1a9e86ac1.md new file mode 100644 index 00000000000..4e80c7f3964 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d404259f512c1a9e86ac1.md @@ -0,0 +1,198 @@ +--- +id: 646d404259f512c1a9e86ac1 +title: Step 73 +challengeType: 0 +dashedName: step-73 +--- + +# --description-- + +In your `highPrecedence` function, declare a `regex` variable. Assign it a regular expression that matches a number (including decimal numbers) followed by a `*` or `/` operator followed by another number. + +Each number, and the operator, should be in separate capture groups. + +# --hints-- + +You should declare a `regex` variable in your `highPrecedence` function. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*(?:const|let|var)\s+regex/); +``` + +You should use `const` to declare your `regex` variable. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex/); +``` + +Your `regex` variable should be a regular expression. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\//); +``` + +Your `regex` should use a capture group. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(/); +``` + +Your first capture group should use a character class. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[/); +``` + +Your first capture group should match any digit or a period. Use the special `\d` character class. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]/); +``` + +Your first capture group should match the character class one or more times. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)/); +``` + +Your `regex` should use a second capture group. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(/); +``` + +Your second capture group should match a `*` or `/` operator. Use a character class in the capture group. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)/); +``` + +Your `regex` should use a third capture group. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(/); +``` + +Your third capture group should be the same as your first capture group. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +--fcc-editable-region-- +const highPrecedence = str => { + +} +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d40c543943ec250039682.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d40c543943ec250039682.md new file mode 100644 index 00000000000..4973e069b9c --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d40c543943ec250039682.md @@ -0,0 +1,163 @@ +--- +id: 646d40c543943ec250039682 +title: Step 74 +challengeType: 0 +dashedName: step-74 +--- + +# --description-- + +Now that you have a regular expression to match multiplication or division, you can evaluate that expression. + +Declare a `str2` variable and assign it the result of calling `infixEval` with `str` and `regex` as arguments. + +# --hints-- + +You should declare a `str2` variable. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*(?:const|let|var)\s+str2/); +``` + +You should use `const` to declare your `str2` variable. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2/); +``` + +You should assign `str2` the result of calling your `infixEval` function. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(/); +``` + +You should pass `str` as the first argument to your `infixEval` call. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*str/); +``` + +You should pass `regex` as the second argument to your `infixEval` call. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +--fcc-editable-region-- +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + +} +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d40fe4b7b50c30c2b4cd8.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d40fe4b7b50c30c2b4cd8.md new file mode 100644 index 00000000000..01767a99e03 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d40fe4b7b50c30c2b4cd8.md @@ -0,0 +1,170 @@ +--- +id: 646d40fe4b7b50c30c2b4cd8 +title: Step 75 +challengeType: 0 +dashedName: step-75 +--- + +# --description-- + +Your `infixEval` function will only evaluate the first multiplication or division operation, because `regex` isn't global. This means you'll want to use a recursive approach to evaluate the entire string. + +If `infixEval` does not find any matches, it will return the `str` value as-is. Using a ternary expression, check if `str2` is equal to `str`. If it is, return `str`, otherwise return the result of calling `highPrecedence()` on `str2`. + +# --hints-- + +Your `infixEval` function should use the `return` keyword. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\);?\s*return/); +``` + +You should use the `return` keyword with a condition to check if `str` is equal to `str2`. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\);?\s*return\s+(?:str\s*===\s*str2|str2\s*===\s*str)/); +``` + +You should use ternary syntax with your `return` statement. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\);?\s*return\s+(?:str\s*===\s*str2|str2\s*===\s*str)\s*\?/); +``` + +If the ternary condition is true, you should return `str`. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\);?\s*return\s+(?:str\s*===\s*str2|str2\s*===\s*str)\s*\?\s*str/); +``` + +If the ternary condition is false, you should return the result of calling `highPrecedence()`. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\);?\s*return\s+(?:str\s*===\s*str2|str2\s*===\s*str)\s*\?\s*str\s*:\s*highPrecedence\(/); +``` + +You should pass `str2` to your `highPrecedence()` call. + +```js +assert.match(code, /const\s+highPrecedence\s*=\s*\(?\s*str\s*\)?\s*=>\s*{\s*const\s+regex\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\*\\\/|\\\/*)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*str\s*,\s*regex\s*\);?\s*return\s+(?:str\s*===\s*str2|str2\s*===\s*str)\s*\?\s*str\s*:\s*highPrecedence\(\s*str2\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +--fcc-editable-region-- +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + +} +--fcc-editable-region-- + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d41e23b583fc3b8cc4579.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d41e23b583fc3b8cc4579.md new file mode 100644 index 00000000000..7fe83fcacfb --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d41e23b583fc3b8cc4579.md @@ -0,0 +1,170 @@ +--- +id: 646d41e23b583fc3b8cc4579 +title: Step 76 +challengeType: 0 +dashedName: step-76 +--- + +# --description-- + +Now you can start applying your function parsing logic to a string. Declare a function called `applyFunction`, which takes a `str` parameter. + +# --hints-- + +You should declare an `applyFunction` variable. + +```js +assert.match(code, /(?:var|let|const)\s+applyFunction\s*=/); +``` + +You should use `const` to declare your `applyFunction` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=/); +``` + +Your `applyFunction` variable should be a function. + +```js +assert.isFunction(applyFunction); +``` + +Your `applyFunction` function should use arrow syntax. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*(?:str)?\s*\)?\s*=>/); +``` + +Your `applyFunction` function should have a `str` parameter. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>/); +``` + +Your `applyFunction` should be empty. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- + +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d423fade4a9c4636acd13.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d423fade4a9c4636acd13.md new file mode 100644 index 00000000000..cbd2f59f0dc --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d423fade4a9c4636acd13.md @@ -0,0 +1,160 @@ +--- +id: 646d423fade4a9c4636acd13 +title: Step 77 +challengeType: 0 +dashedName: step-77 +--- + +# --description-- + +First you need to handle the higher precedence operators. Declare a `noHigh` variable, and assign it the result of calling `highPrecedence()` with `str` as an argument. + +# --hints-- + +You should declare a `noHigh` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*(?:var|let|const)\s+noHigh\s*=/); +``` + +You should use `const` to declare your `noHigh` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=/); +``` + +You should assign `noHigh` the result of calling `highPrecedence()`. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(/); +``` + +You should pass `str` as the argument to your `highPrecedence()` call. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d42f58deb2fc52adc6611.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d42f58deb2fc52adc6611.md new file mode 100644 index 00000000000..862ff6ebe14 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d42f58deb2fc52adc6611.md @@ -0,0 +1,205 @@ +--- +id: 646d42f58deb2fc52adc6611 +title: Step 78 +challengeType: 0 +dashedName: step-78 +--- + +# --description-- + +Now that you've parsed and evaluated the multiplication and division operators, you need to do the same with the addition and subtraction operators. + +Declare an `infix` variable, and assign it a regular expression that matches a number (including decimal numbers) followed by a `+` or `-` operator followed by another number. + +# --hints-- + +You should declare an `infix` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*(?:const|let|var)\s+infix\s*=/); +``` + +You should use `const` to declare your `infix` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=/); +``` + +Your `infix` variable should be a regular expression. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\//); +``` + +Your `infix` regex should use a capture group. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(/); +``` + +Your first capture group should use a character class. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[/); +``` + +Your first capture group should match one or more digits or decimal points. Use the `\d` character class. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)/); +``` + +Your `infix` regex should use a second capture group. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(/); +``` + +Your second capture group should use a character class. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[/); +``` + +Your second capture group should match either the `+` or `-` operator. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)/); +``` + +Your `infix` regex should use a third capture group. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(/); +``` + +Your third capture group should be the same as your first capture group. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + const noHigh = highPrecedence(str); + +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d43587d926bc5b6cb2e50.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d43587d926bc5b6cb2e50.md new file mode 100644 index 00000000000..b9387c25525 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d43587d926bc5b6cb2e50.md @@ -0,0 +1,168 @@ +--- +id: 646d43587d926bc5b6cb2e50 +title: Step 79 +challengeType: 0 +dashedName: step-79 +--- + +# --description-- + +Declare a `str2` variable, and assign it the result of calling `infixEval()` with `noHigh` and `infix` as arguments. + +# --hints-- + +You should declare a `str2` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*(?:let|var|const)\s+str2/); +``` + +You should use `const` to declare your `str2` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2/); +``` + +You should assign `str2` the result of calling `infixEval()`. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(/); +``` + +You should pass `noHigh` as the first argument to `infixEval()`. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh/); +``` + +You should pass `infix` as the second argument to `infixEval()`. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d448479c8fdc8dcec868c.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d448479c8fdc8dcec868c.md new file mode 100644 index 00000000000..521cb0a4b09 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d448479c8fdc8dcec868c.md @@ -0,0 +1,159 @@ +--- +id: 646d448479c8fdc8dcec868c +title: Step 80 +challengeType: 0 +dashedName: step-80 +--- + +# --description-- + +Declare a `functionCall` variable, and assign it this regular expression: `/([a-z]*)\(([0-9., ]*)\)(?!.*\()/i` + +This expression will look for function calls like `sum(1, 4)`. + +# --hints-- + +You should declare a `functionCall` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*(?:const|let|var)\s+functionCall\s*=/); +``` + +You should use `const` to declare your `functionCall` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=/); +``` + +You should assign `functionCall` the provided regular expression. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d44da986f2bc9b72f5fe2.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d44da986f2bc9b72f5fe2.md new file mode 100644 index 00000000000..7a4d6806f2b --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d44da986f2bc9b72f5fe2.md @@ -0,0 +1,195 @@ +--- +id: 646d44da986f2bc9b72f5fe2 +title: Step 81 +challengeType: 0 +dashedName: step-81 +--- + +# --description-- + +Declare a `toNumberList` function which takes an `args` parameter, and returns the result of splitting the `args` by commas, and mapping the resulting array to `parseFloat`. + +# --hints-- + +You should declare a `toNumberList` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*(?:const|let|var)\s+toNumberList\s*=/); +``` + +You should use `const` to declare your `toNumberList` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=/); +``` + +Your `toNumberList` variable should be an arrow function. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*(?:args)?\s*\)?\s*=>/); +``` + +Your `toNumberList` function should have an `args` parameter. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>/); +``` + +Your `toNumberList` function should use an implicit return. + +```js +assert.notMatch(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*\{/); +``` + +Your `toNumberList` function should return the result of calling the `.split()` method of `args`. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(/); +``` + +You should split `args` on the `,` character. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)/); +``` + +You should chain the `.map()` method to the `.split()` method. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(/); +``` + +You should pass a reference to `parseFloat` as the callback to `.map()`. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?/); +``` + + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d451c2e44afca71b67818.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d451c2e44afca71b67818.md new file mode 100644 index 00000000000..b2ee3df825b --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d451c2e44afca71b67818.md @@ -0,0 +1,177 @@ +--- +id: 646d451c2e44afca71b67818 +title: Step 82 +challengeType: 0 +dashedName: step-82 +--- + +# --description-- + +Declare an `apply` function that takes a `fn` and `args` parameter. + +# --hints-- + +You should declare an `apply` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*(?:var|let|const)\s+apply\s*=/); +``` + +You should use `const` to declare your `apply` variable. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=/); +``` + +Your `apply` variable should be assigned an arrow function. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(/); +``` + +Your `apply` function should have `fn` as its first parameter. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn/); +``` + +Your `apply` function should have `args` as its second parameter. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)/); +``` + +Your `apply` function should be empty. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*\{\s*\}/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4554721d43cb19a68bc4.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4554721d43cb19a68bc4.md new file mode 100644 index 00000000000..5900d07b82b --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4554721d43cb19a68bc4.md @@ -0,0 +1,169 @@ +--- +id: 646d4554721d43cb19a68bc4 +title: Step 83 +challengeType: 0 +dashedName: step-83 +--- + +# --description-- + +The `fn` parameter will be the name of a function, such as `SUM`. Update `apply` to implicitly return the function found at the `fn` property of your `spreadsheetFunctions` object. + +Remember that `fn` might not be lowercase, so you'll need to convert it to a lowercase string. + +# --hints-- + +Your `apply` function should use an implicit return. + +```js +assert.notMatch(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*\{/); +``` + +Your `apply` function should access the `spreadsheetFunctions` object. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions/); +``` + +Your `apply` function should access the property of the `spreadsheetFunctions` object that matches the `fn` value. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn/); +``` + +Your `apply` function should call the `.toLowerCase()` method on `fn` in the property access. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]/); +``` + + + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => {} +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d45b739da5ecbf830c108.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d45b739da5ecbf830c108.md new file mode 100644 index 00000000000..26b5d4cc9f9 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d45b739da5ecbf830c108.md @@ -0,0 +1,159 @@ +--- +id: 646d45b739da5ecbf830c108 +title: Step 84 +challengeType: 0 +dashedName: step-84 +--- + +# --description-- + +Your `apply` function is returning the spreadsheet function, but not actually applying it. Update `apply` to call the function. Pass in the result of calling `toNumberList` with `args` as an argument. + +# --hints-- + +Your `apply` function should call the `spreadsheetFunctions[fn.toLowerCase()]` function. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(/); +``` + +You should pass a `toNumberList()` call to your `spreadsheetFunctions[fn.toLowerCase()]` call. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(/); +``` + +You should pass `args` to your `toNumberList()` call. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()]; +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d45ee725632cca2555146.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d45ee725632cca2555146.md new file mode 100644 index 00000000000..b44378895e2 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d45ee725632cca2555146.md @@ -0,0 +1,161 @@ +--- +id: 646d45ee725632cca2555146 +title: Step 85 +challengeType: 0 +dashedName: step-85 +--- + +# --description-- + +Now your `applyFunction` needs to return a result. Return the result of calling the `.replace()` method on `str2`. Pass your `functionCall` regex and an empty callback. + +# --hints-- + +Your `applyFunction` function should return the result of calling the `.replace()` method on `str2`. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(/); +``` + +You should pass `functionCall` as the first argument to your `.replace()` call. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall/); +``` + +You should pass an empty arrow function as the second argument to your `.replace()` call. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*\)\s*=>\s*\{\s*\}/); +``` + + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4626420eeecd51f241c2.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4626420eeecd51f241c2.md new file mode 100644 index 00000000000..07688aaca12 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4626420eeecd51f241c2.md @@ -0,0 +1,186 @@ +--- +id: 646d4626420eeecd51f241c2 +title: Step 86 +challengeType: 0 +dashedName: step-86 +--- + +# --description-- + +Update the callback function to take `match`, `fn`, and `args` as parameters. It should implicitly return the result of checking whether `spreadsheetFunctions` has its own property of `fn`. + +Remember to make `fn` lower case. + +# --hints-- + +Your callback function should have `match` as the first parameter. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match/); +``` + +Your callback function should have `fn` as the second parameter. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn/); +``` + +Your callback function should have `args` as the third parameter. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn\s*,\s*args\s*\)\s*=>/); +``` + +Your callback function should use an implicit return. + +```js +assert.notMatch(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn\s*,\s*args\s*\)\s*=>\s*\{/); +``` + +Your callback function should return the result of calling the `.hasOwnProperty()` method on the `spreadsheetFunctions` object. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\.hasOwnProperty\(/); +``` + +You should pass `fn` to the .`hasOwnProperty()` method. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\.hasOwnProperty\(fn/); +``` + +You should call the `.toLowerCase()` method on `fn`. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\.hasOwnProperty\(fn\.toLowerCase\(\s*\)\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, () => {}) +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d467c6994f4ce0dc416a4.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d467c6994f4ce0dc416a4.md new file mode 100644 index 00000000000..8d640506e46 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d467c6994f4ce0dc416a4.md @@ -0,0 +1,172 @@ +--- +id: 646d467c6994f4ce0dc416a4 +title: Step 87 +challengeType: 0 +dashedName: step-87 +--- + +# --description-- + +Use the ternary operator to turn your `.hasOwnProperty()` call into the condition. If the object has the property, return the result of calling `apply` with `fn` and `args` as arguments. Otherwise, return `match`. + +# --hints-- + +Your callback function should use ternary syntax. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\.hasOwnProperty\(fn\.toLowerCase\(\s*\)\s*\)\s*\?/); +``` + +If the ternary condition is true, your callback function should return the result of calling `apply()`. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\.hasOwnProperty\(fn\.toLowerCase\(\s*\)\s*\)\s*\?\s*apply\(/); +``` + +You should pass `fn` as the first argument to your `apply()` call. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\.hasOwnProperty\(fn\.toLowerCase\(\s*\)\s*\)\s*\?\s*apply\(\s*fn/); +``` + +You should pass `args` as the second argument to your `apply()` call. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\.hasOwnProperty\(fn\.toLowerCase\(\s*\)\s*\)\s*\?\s*apply\(\s*fn\s*,\s*args\s*\)/); +``` + +If the ternary is false, you should return `match`. + +```js +assert.match(code, /const\s+applyFunction\s*=\s*\(?\s*str\s*\)?\s*=>\s*\{\s*const\s+noHigh\s*=\s*highPrecedence\(\s*str\s*\);?\s*const\s+infix\s*=\s*\/\(\[(?:\\d\.|\.\\d)\]\+\)\(\[(?:\+-|-\+)\]\)\(\[(?:\\d\.|\.\\d)\]\+\)\/;?\s*const\s+str2\s*=\s*infixEval\(\s*noHigh\s*\,\s*infix\s*\);?\s*const\s+functionCall\s*=\s*\/\(\[a-z\]\*\)\\\(\(\[0-9\., \]\*\)\\\)\(\?!\.\*\\\(\)\/i;?\s*const\s+toNumberList\s*=\s*\(?\s*args\s*\)?\s*=>\s*args\.split\(\s*('|"|`),\1\s*\)\.map\(\s*parseFloat\s*\);?\s*const\s+apply\s*=\s*\(\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\[fn\.toLowerCase\(\)\]\(\s*toNumberList\(\s*args\s*\)\);?\s*return\s+str2\.replace\(\s*functionCall\s*,\s*\(\s*match\s*,\s*fn\s*,\s*args\s*\)\s*=>\s*spreadsheetFunctions\.hasOwnProperty\(fn\.toLowerCase\(\s*\)\s*\)\s*\?\s*apply\(\s*fn\s*,\s*args\s*\)\s*:\s*match/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +--fcc-editable-region-- +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ); +} +--fcc-editable-region-- + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d46c03e7d02cecb30f021.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d46c03e7d02cecb30f021.md new file mode 100644 index 00000000000..a01fe855aed --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d46c03e7d02cecb30f021.md @@ -0,0 +1,167 @@ +--- +id: 646d46c03e7d02cecb30f021 +title: Step 88 +challengeType: 0 +dashedName: step-88 +--- + +# --description-- + +Now you can start applying your function parser to your `evalFormula` logic. Declare a `functionExpanded` variable, and assign it the result of calling `applyFunction` with your `cellExpanded` string. + +# --hints-- + +You should declare a `functionExpanded` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*(?:const|let|var)\s+functionExpanded\s*=\s*/); +``` + +You should use `const` to declare your `functionExpanded` variable. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*const\s+functionExpanded\s*=\s*/); +``` + +You should assign the `functionExpanded` variable the result of calling your `applyFunction` function. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*(?:const|let|var)\s+functionExpanded\s*=\s*applyFunction\(/); +``` + +You should pass `cellExpanded` to your `applyFunction` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*(?:const|let|var)\s+functionExpanded\s*=\s*applyFunction\(\s*cellExpanded\s*\);?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4717a689e1cfa232e357.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4717a689e1cfa232e357.md new file mode 100644 index 00000000000..50e56cc4486 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4717a689e1cfa232e357.md @@ -0,0 +1,188 @@ +--- +id: 646d4717a689e1cfa232e357 +title: Step 89 +challengeType: 0 +dashedName: step-89 +--- + +# --description-- + +Like you did with your `highPrecedence()` function, your `evalFormula()` function needs to ensure it has evaluated and replaced everything. + +Use a ternary to check if `functionExpanded` is equal to the original string `x`. If it is, return `functionExpanded`, otherwise return the result of calling `evalFormula()` again with `functionExpanded` and `cells` as arguments. + +# --hints-- + +Your `evalFormula` function should use the `return` keyword. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*(?:const|let|var)\s+functionExpanded\s*=\s*applyFunction\(\s*cellExpanded\s*\);?\s*return/); +``` + +Your `return` statement should check if `functionExpanded` is equal to `x`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*(?:const|let|var)\s+functionExpanded\s*=\s*applyFunction\(\s*cellExpanded\s*\);?\s*return\s*(?:functionExpanded\s*===\s*x|x\s*===\s*functionExpanded)/); +``` + +Your `return` statement should use a ternary operator. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*(?:const|let|var)\s+functionExpanded\s*=\s*applyFunction\(\s*cellExpanded\s*\);?\s*return\s*(?:functionExpanded\s*===\s*x|x\s*===\s*functionExpanded)\s*\?/); +``` + +If the ternary condition is true, your `evalFormula()` should return `functionExpanded`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*(?:const|let|var)\s+functionExpanded\s*=\s*applyFunction\(\s*cellExpanded\s*\);?\s*return\s*(?:functionExpanded\s*===\s*x|x\s*===\s*functionExpanded)\s*\?\s*functionExpanded/); +``` + +If the ternary condition is false, your `evalFormula()` should return the result of calling `evalFormula()`. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*(?:const|let|var)\s+functionExpanded\s*=\s*applyFunction\(\s*cellExpanded\s*\);?\s*return\s*(?:functionExpanded\s*===\s*x|x\s*===\s*functionExpanded)\s*\?\s*functionExpanded\s*:\s*evalFormula\(/); +``` + +You should pass `functionExpanded` as the first argument to your `evalFormula()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*(?:const|let|var)\s+functionExpanded\s*=\s*applyFunction\(\s*cellExpanded\s*\);?\s*return\s*(?:functionExpanded\s*===\s*x|x\s*===\s*functionExpanded)\s*\?\s*functionExpanded\s*:\s*evalFormula\(\s*functionExpanded/); +``` + +You should pass `cells` as the second argument to your `evalFormula()` call. + +```js +assert.match(code, /const\s*evalFormula\s*=\s*\(\s*x\s*,\s*cells\s*\)\s*=>\s*{\s*const\s+idToText\s*=\s*\(?\s*id\s*\)?\s*=>\s*cells\.find\(\s*\(?\s*cell\s*\)?\s*=>\s*(?:cell\.id\s*===\s*id|id\s*===\s*cell\.id)\s*\)\.value;?\s*const\s+rangeRegex\s*=\s*\/\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\):\(\[A-J\]\)\(\[1-9\]\[0-9\]\?\)\/(gi|ig);?\s*const\s+rangeFromString\s*=\s*\(\s*num1\s*,\s*num2\s*\)\s*=>\s*range\(\s*parseInt\(\s*num1\s*\)\s*,\s*parseInt\(\s*num2\s*\)\s*\);?\s*const\s+elemValue\s*=\s*\(?\s*num\s*\)?\s*=>\s*\(?\s*character\s*\)?\s*=>\s*idToText\(\s*character\s*\+\s*num\s*\);?\s*const\s+addCharacters\s*=\s*\(?\s*character1\s*\)?\s*=>\s*\(?\s*character2\s*\)?\s*=>\s*\(?\s*num\s*\)?\s*=>\s*charRange\(\s*character1\s*,\s*character2\s*\)\.map\(\s*elemValue\(\s*num\s*\)\s*\);?\s*const\s+rangeExpanded\s*=\s*x\.replace\(\s*rangeRegex\s*,\s*\(\s*_match\s*,\s*char1\s*,\s*num1\s*,\s*char2\s*,\s*num2\s*\)\s*=>\s*rangeFromString\(\s*num1\s*,\s*num2\s*\)\.map\(\s*addCharacters\s*\(\s*char1\s*\)\(\s*char2\s*\)\s*\)\s*\);?\s*const\s+cellRegex\s*=\s*\/\[A-J\]\[1-9\]\[0-9\]\?\/(gi|ig);?\s*const\s+cellExpanded\s*=\s*rangeExpanded\.replace\(\s*cellRegex\s*,\s*\(?\s*match\s*\)?\s*=>\s*idToText\(\s*match\.toUpperCase\(\)\s*\)\);?\s*(?:const|let|var)\s+functionExpanded\s*=\s*applyFunction\(\s*cellExpanded\s*\);?\s*return\s*(?:functionExpanded\s*===\s*x|x\s*===\s*functionExpanded)\s*\?\s*functionExpanded\s*:\s*evalFormula\(\s*functionExpanded\s*,\s*cells\s*\);?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +--fcc-editable-region-- +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + +} +--fcc-editable-region-- + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4769ba65f1d05ef6b634.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4769ba65f1d05ef6b634.md new file mode 100644 index 00000000000..c9b3155ab77 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4769ba65f1d05ef6b634.md @@ -0,0 +1,164 @@ +--- +id: 646d4769ba65f1d05ef6b634 +title: Step 90 +challengeType: 0 +dashedName: step-90 +--- + +# --description-- + +Now your `update()` function can actually evaluate formulas. Remember that you wrote the `if` condition to check that a function was called. + +Inside your `if` statement, set the `value` of the `element` to be the result of your `evalFormula()` function. Do not pass any arguments yet. + +# --hints-- + +You should update the `value` property of `element` in your `if` block. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value/); +``` + +You should assign the `value` property the result of calling your `evalFormula()` function. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(/); +``` + +You should not pass any arguments to your `evalFormula()` call. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(\s*\)/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +--fcc-editable-region-- +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + + } +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d47c8f58107d10f1e5106.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d47c8f58107d10f1e5106.md new file mode 100644 index 00000000000..2b8ba01ca6f --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d47c8f58107d10f1e5106.md @@ -0,0 +1,162 @@ +--- +id: 646d47c8f58107d10f1e5106 +title: Step 91 +challengeType: 0 +dashedName: step-91 +--- + +# --description-- + +The first argument for your `evalFormula` call needs to be the contents of the cell (which you stored in `value`). However, the contents start with an `=` character to trigger the function, so you need to pass the substring of `value` starting at index `1`. + +# --hints-- + +You should pass `value` as the first argument to your `evalFormula()` call. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(\s*value/); +``` + +You should call the `.slice()` method on the `value` argument. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(\s*value\.slice\(/); +``` + +You should pass the number `1` as the argument to your `.slice()` call. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(\s*value\.slice\(\s*1\s*\)\s*\);?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +--fcc-editable-region-- +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(); + } +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4813c17b37d1e261a566.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4813c17b37d1e261a566.md new file mode 100644 index 00000000000..bfc7354c9b4 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4813c17b37d1e261a566.md @@ -0,0 +1,162 @@ +--- +id: 646d4813c17b37d1e261a566 +title: Step 92 +challengeType: 0 +dashedName: step-92 +--- + +# --description-- + +You can quickly get all cells from your page by getting the `#container` element by it's `id` and accessing the `children` property of the result. Pass that to your `evalFormula()` call as the second parameter. + +# --hints-- + +For the second parameter of your `evalFormula()` call, you should call the `.getElementById()` method of the `document` object. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(\s*value\.slice\(\s*1\s*\)\s*,\s*document\.getElementById\(/); +``` + +You should pass `container` as the argument to your `.getElementById()` call. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(\s*value\.slice\(\s*1\s*\)\s*,\s*document\.getElementById\(\s*('|"|`)container\9\s*\)/); +``` + +You should access the `children` property of the result of your `.getElementById()` call. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(\s*value\.slice\(\s*1\s*\)\s*,\s*document\.getElementById\(\s*('|"|`)container\9\s*\)\.children\s*\);?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +--fcc-editable-region-- +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1)); + } +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d486aec20f7d2a581cc36.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d486aec20f7d2a581cc36.md new file mode 100644 index 00000000000..42ac008ff41 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d486aec20f7d2a581cc36.md @@ -0,0 +1,150 @@ +--- +id: 646d486aec20f7d2a581cc36 +title: Step 93 +challengeType: 0 +dashedName: step-93 +--- + +# --description-- + +Unfortunately, that `children` property is returning a collection of elements, which is array-like but not an array. Wrap your second argument in `Array.from()` to convert it to an array. + +# --hints-- + +You should wrap your `document.getElementById('container').children` in `Array.from()`. + +```js +assert.match(code, /const\s+update\s*=\s*\(?\s*event\s*\)?\s*=>\s*\{\s*const\s+element\s*=\s*event\.target;?\s*const\s+value\s*=\s*element\.value\.replace\(\s*\/\\s\/g\s*,\s*('|"|`)\1\s*\);?\s*if\s*\(\s*(!value\.includes\(\s*element\.id\s*\)\s*&&\s*(?:value\[0\]\s*===\s*('|"|`)=\3|value\.charAt\(0\)\s*===\s*('|"|`)=\4|value\.startsWith\(('|"|`)=\5\))|(?:value\[0\]\s*===\s*('|"|`)=\6|value\.charAt\(0\)\s*===\s*('|"|`)=\7|value\.startsWith\(('|"|`)=\8\))\s*\|\|\s*!value\.includes\(\s*element\.id\s*\))\s*\)\s*\{\s*element\.value\s*=\s*evalFormula\(\s*value\.slice\(\s*1\s*\)\s*,\s*Array\.from\(\s*document\.getElementById\(\s*('|"|`)container\9\s*\)\.children\s*\)\s*\);?/); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + sum, + average, + median +} + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +--fcc-editable-region-- +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), document.getElementById("container").children); + } +} +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d48b936802fd34c3f05af.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d48b936802fd34c3f05af.md new file mode 100644 index 00000000000..255197e54a6 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d48b936802fd34c3f05af.md @@ -0,0 +1,189 @@ +--- +id: 646d48b936802fd34c3f05af +title: Step 94 +challengeType: 0 +dashedName: step-94 +--- + +# --description-- + +Your spreadsheet is now functional. However, you don't have support for very many formulas. + +Add an `even` property to your `spreadsheetFunctions`. It should take a `nums` parameter, and return the result of filtering the `nums` array to only include even numbers. Use a reference to your `isEven` function to help. + +# --hints-- + +Your `spreadsheetFunctions` object should have an `even` property. + +```js +assert.property(spreadsheetFunctions, "even"); +``` + +Your `even` property should be a function. + +```js +assert.isFunction(spreadsheetFunctions.even); +``` + +Your `even` function should take a `nums` parameter. + +```js +assert.match(code, /even\s*:\s*\(?\s*nums\s*\)?\s*=>/) +``` + +Your `even` function should use an implicit return. + +```js +assert.notMatch(code, /even\s*:\s*\(?\s*nums\s*\)?\s*=>\s*\{/) +``` + +Your `even` function should return the result of calling the `.filter()` method on `nums`. + +```js +assert.match(code, /even\s*:\s*\(?\s*nums\s*\)?\s*=>\s*nums\s*\.\s*filter/) +``` + +You should pass a reference to your `isEven()` function as the callback for the `.filter()` method. + +```js +assert.match(code, /even\s*:\s*\(?\s*nums\s*\)?\s*=>\s*nums\s*\.\s*filter\s*\(\s*isEven\s*\)/) +``` + +Your `even` function should return an array of even numbers. + +```js +assert.deepEqual(spreadsheetFunctions.even([1, 2, 3, 4, 5, 6]), [2, 4, 6]); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +--fcc-editable-region-- +const spreadsheetFunctions = { + sum, + average, + median, + +} +--fcc-editable-region-- + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), Array.from(document.getElementById("container").children)); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d498c8ebc31d3f753b22e.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d498c8ebc31d3f753b22e.md new file mode 100644 index 00000000000..0dd57f1224b --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d498c8ebc31d3f753b22e.md @@ -0,0 +1,182 @@ +--- +id: 646d498c8ebc31d3f753b22e +title: Step 95 +challengeType: 0 +dashedName: step-95 +--- + +# --description-- + +Add a `firsttwo` property which takes a `nums` parameter and returns the first two elements of the `nums` array. Then add a `lasttwo` property which returns the last two elements of the `nums` array. + +# --hints-- + +Your `spreadsheetFunctions` object should have a `firsttwo` property. + +```js +assert.property(spreadsheetFunctions, "firsttwo"); +``` + +Your `firsttwo` property should be a function. + +```js +assert.isFunction(spreadsheetFunctions.firsttwo); +``` + +Your `firsttwo` function should return the first two numbers of the array. + +```js +assert.deepEqual(spreadsheetFunctions.firsttwo([1, 2, 3, 4, 5, 6]), [1, 2]); +``` + +Your `spreadsheetFunctions` object should have a `lasttwo` property. + +```js +assert.property(spreadsheetFunctions, "lasttwo"); +``` + +Your `lasttwo` property should be a function. + +```js +assert.isFunction(spreadsheetFunctions.lasttwo); +``` + +Your `lasttwo` function should return the last two numbers of the array. + +```js +assert.deepEqual(spreadsheetFunctions.lasttwo([1, 2, 3, 4, 5, 6]), [5, 6]); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +--fcc-editable-region-- +const spreadsheetFunctions = { + sum, + average, + median, + even: nums => nums.filter(isEven), + +} +--fcc-editable-region-- + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), Array.from(document.getElementById("container").children)); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d49bfff9079d4b38df115.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d49bfff9079d4b38df115.md new file mode 100644 index 00000000000..2a2788f4b10 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d49bfff9079d4b38df115.md @@ -0,0 +1,190 @@ +--- +id: 646d49bfff9079d4b38df115 +title: Step 96 +challengeType: 0 +dashedName: step-96 +--- + +# --description-- + +Add a `has2` property which returns whether the `nums` array has `2` in the values, and an `increment` property which returns `nums` with every value incremented by one. + +# --hints-- + +Your `spreadsheetFunctions` object should have a `has2` property. + +```js +assert.property(spreadsheetFunctions, "has2"); +``` + +Your `has2` property should be a function. + +```js +assert.isFunction(spreadsheetFunctions.has2); +``` + +Your `has2` function should return `true` if the array has `2` in it. + +```js +assert.isTrue(spreadsheetFunctions.has2([1, 2, 3])); +``` + +Your `has2` function should return `false` if the array does not have `2` in it. + +```js +assert.isFalse(spreadsheetFunctions.has2([1, 3, 4])); +``` + +Your `spreadsheetFunctions` object should have an `increment` property. + +```js +assert.property(spreadsheetFunctions, "increment"); +``` + +Your `increment` property should be a function. + +```js +assert.isFunction(spreadsheetFunctions.increment); +``` + +Your `increment` function should return an array of numbers incremented by one. + +```js +assert.deepEqual(spreadsheetFunctions.increment([1, 2, 3]), [2, 3, 4]); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +--fcc-editable-region-- +const spreadsheetFunctions = { + sum, + average, + median, + even: nums => nums.filter(isEven), + firsttwo: nums => nums.slice(0, 2), + lasttwo: nums => nums.slice(-2), + +} +--fcc-editable-region-- + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), Array.from(document.getElementById("container").children)); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a07a8fb14d55cd70e09.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a07a8fb14d55cd70e09.md new file mode 100644 index 00000000000..12c4eb6bf15 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a07a8fb14d55cd70e09.md @@ -0,0 +1,183 @@ +--- +id: 646d4a07a8fb14d55cd70e09 +title: Step 97 +challengeType: 0 +dashedName: step-97 +--- + +# --description-- + +Arrays have a `.some()` method. Like the `.filter()` method, `.some()` accepts a callback function which should take an element of the array as the argument. The `.some()` method will return `true` if the callback function returns `true` for at least one element in the array. + +Here is an example of a `.some()` method call to check if any element in the array is an uppercase letter. + +```js +const arr = ["A", "b", "C"]; +arr.some(letter => letter === letter.toUpperCase()); +``` + +Add a `someeven` property to your `spreadsheetFunctions` - use the `.some()` method to check if any element in the array is even. + +# --hints-- + +Your `spreadsheetFunctions` object should have a `someeven` property. + +```js +assert.property(spreadsheetFunctions, "someeven"); +``` + +Your `someeven` property should be a function. + +```js +assert.isFunction(spreadsheetFunctions.someeven); +``` + +Your `someeven` function should return `true` if some of the elements in the array are even. + +```js +assert.isTrue(spreadsheetFunctions.someeven([1, 2, 3])); +``` + +Your `someeven` function should return `false` if none of the elements in the array are even. + +```js +assert.isFalse(spreadsheetFunctions.someeven([1, 3, 5])); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +--fcc-editable-region-- +const spreadsheetFunctions = { + sum, + average, + median, + even: nums => nums.filter(isEven), + + firsttwo: nums => nums.slice(0, 2), + lasttwo: nums => nums.slice(-2), + has2: nums => nums.includes(2), + increment: nums => nums.map(num => num + 1), +} +--fcc-editable-region-- + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), Array.from(document.getElementById("container").children)); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a5b32a1cad6165df286.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a5b32a1cad6165df286.md new file mode 100644 index 00000000000..7c43db10dd0 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a5b32a1cad6165df286.md @@ -0,0 +1,178 @@ +--- +id: 646d4a5b32a1cad6165df286 +title: Step 99 +challengeType: 0 +dashedName: step-99 +--- + +# --description-- + +Add a `random` property which takes the first two numbers from an array and returns a random number between them. Use the `Math.random()` function to help. + +# --hints-- + +Your `spreadsheetFunctions` object should have a `random` property. + +```js +assert.property(spreadsheetFunctions, "random"); +``` + +Your `random` property should be a function. + +```js +assert.isFunction(spreadsheetFunctions.random); +``` + +Your `random` function should return a random number between the first two numbers in the array. + +```js +assert.isAtLeast(spreadsheetFunctions.random([1, 2, 3]), 1); +assert.isAtMost(spreadsheetFunctions.random([1, 2, 3]), 2); +``` + +Your `random` function should return a whole number (integer). + +```js +const result = spreadsheetFunctions.random([1, 10]); +assert.equal(result, Math.floor(result)); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +--fcc-editable-region-- +const spreadsheetFunctions = { + sum, + average, + median, + even: nums => nums.filter(isEven), + someeven: nums => nums.some(isEven), + everyeven: nums => nums.every(isEven), + firsttwo: nums => nums.slice(0, 2), + lasttwo: nums => nums.slice(-2), + has2: nums => nums.includes(2), + increment: nums => nums.map(num => num + 1), + +} +--fcc-editable-region-- + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), Array.from(document.getElementById("container").children)); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a8dbc04c6d6bb0001f8.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a8dbc04c6d6bb0001f8.md new file mode 100644 index 00000000000..1123c7fe781 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4a8dbc04c6d6bb0001f8.md @@ -0,0 +1,171 @@ +--- +id: 646d4a8dbc04c6d6bb0001f8 +title: Step 100 +challengeType: 0 +dashedName: step-100 +--- + +# --description-- + +Add a `range` property which generates a range from `nums`. Remember that you have a `range` function you can reuse here. + +# --hints-- + +Your `spreadsheetFunctions` object should have a `range` property. + +```js +assert.property(spreadsheetFunctions, "range"); +``` + +Your `range` property should be a function. + +```js +assert.isFunction(spreadsheetFunctions.range); +``` + +Your `range` function should return an array of consecutive numbers from the first number in the argument to the second number in the argument. + +```js +assert.deepEqual(spreadsheetFunctions.range([1, 5, 10]), [1, 2, 3, 4, 5]); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +--fcc-editable-region-- +const spreadsheetFunctions = { + sum, + average, + median, + even: nums => nums.filter(isEven), + someeven: nums => nums.some(isEven), + everyeven: nums => nums.every(isEven), + firsttwo: nums => nums.slice(0, 2), + lasttwo: nums => nums.slice(-2), + has2: nums => nums.includes(2), + increment: nums => nums.map(num => num + 1), + random: ([x, y]) => Math.floor(Math.random() * y + x), + +} +--fcc-editable-region-- + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), Array.from(document.getElementById("container").children)); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4ab9b3b4c5d74fdd2154.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4ab9b3b4c5d74fdd2154.md new file mode 100644 index 00000000000..d89f6df3612 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4ab9b3b4c5d74fdd2154.md @@ -0,0 +1,175 @@ +--- +id: 646d4ab9b3b4c5d74fdd2154 +title: Step 101 +challengeType: 0 +dashedName: step-101 +--- + +# --description-- + +The last function has a few approaches to implement, and you are free to choose whichever approach you would like. + +Add a `nodupes` property which returns `nums` with all duplicate values removed. For example, `[2, 1, 2, 5, 3, 2, 7]` should return `[2, 1, 5, 3, 7]`. + +# --hints-- + +Your `spreadsheetFunctions` object should have a `nodupes` property. + +```js +assert.property(spreadsheetFunctions, "nodupes"); +``` + +Your `nodupes` property should be a function. + +```js +assert.isFunction(spreadsheetFunctions.nodupes); +``` + +Your `nodupes` function should remove all duplicate values from the array. + +```js +assert.deepEqual(spreadsheetFunctions.nodupes([2, 1, 2, 5, 3, 2, 7]), [2, 1, 5, 3, 7]); +assert.deepEqual(spreadsheetFunctions.nodupes([1, 2, 3]), [1, 2, 3]); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +--fcc-editable-region-- +const spreadsheetFunctions = { + sum, + average, + median, + even: nums => nums.filter(isEven), + someeven: nums => nums.some(isEven), + everyeven: nums => nums.every(isEven), + firsttwo: nums => nums.slice(0, 2), + lasttwo: nums => nums.slice(-2), + has2: nums => nums.includes(2), + increment: nums => nums.map(num => num + 1), + random: ([x, y]) => Math.floor(Math.random() * y + x), + range: nums => range(...nums), + +} +--fcc-editable-region-- + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), Array.from(document.getElementById("container").children)); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4b3d80ea98d824c8a4f9.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4b3d80ea98d824c8a4f9.md new file mode 100644 index 00000000000..7897240eb29 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/646d4b3d80ea98d824c8a4f9.md @@ -0,0 +1,314 @@ +--- +id: 646d4b3d80ea98d824c8a4f9 +title: Step 102 +challengeType: 0 +dashedName: step-102 +--- + +# --description-- + +Finally, to handle potential edge cases, add an empty string property (you will need to use quotes) which is a function that takes a single argument and returns that argument. + +With that, your spreadsheet project is now complete. You are welcome to experiment with adding support for even more functions. + +# --hints-- + +Your `spreadsheetFunctions` object should have an empty string property. + +```js +assert.property(spreadsheetFunctions, ""); +``` + +Your empty string property should be a function. + +```js +assert.isFunction(spreadsheetFunctions[""]); +``` + +Your empty string property function should return the argument. + +```js +assert.deepEqual(spreadsheetFunctions[""]([1,2,3]), [1,2,3]); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +--fcc-editable-region-- +const spreadsheetFunctions = { + + sum, + average, + median, + even: nums => nums.filter(isEven), + someeven: nums => nums.some(isEven), + everyeven: nums => nums.every(isEven), + firsttwo: nums => nums.slice(0, 2), + lasttwo: nums => nums.slice(-2), + has2: nums => nums.includes(2), + increment: nums => nums.map(num => num + 1), + random: ([x, y]) => Math.floor(Math.random() * y + x), + range: nums => range(...nums), + nodupes: nums => [...new Set(nums).values()] +} +--fcc-editable-region-- + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), Array.from(document.getElementById("container").children)); + } +} +``` + +# --solutions-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +const spreadsheetFunctions = { + "": x => x, + sum, + average, + median, + even: nums => nums.filter(isEven), + someeven: nums => nums.some(isEven), + everyeven: nums => nums.every(isEven), + firsttwo: nums => nums.slice(0, 2), + lasttwo: nums => nums.slice(-2), + has2: nums => nums.includes(2), + increment: nums => nums.map(num => num + 1), + random: ([x, y]) => Math.floor(Math.random() * y + x), + range: nums => range(...nums), + nodupes: nums => [...new Set(nums).values()] +} + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), Array.from(document.getElementById("container").children)); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6491d38f5b09a021c4b5d5fe.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6491d38f5b09a021c4b5d5fe.md new file mode 100644 index 00000000000..ec55d6b9819 --- /dev/null +++ b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/6491d38f5b09a021c4b5d5fe.md @@ -0,0 +1,184 @@ +--- +id: 6491d38f5b09a021c4b5d5fe +title: Step 98 +challengeType: 0 +dashedName: step-98 +--- + +# --description-- + +Arrays have an `.every()` method. Like the `.some()` method, `.every()` accepts a callback function which should take an element of the array as the argument. The `.every()` method will return `true` if the callback function returns `true` for all elements in the array. + +Here is an example of a `.every()` method call to check if all elements in the array are uppercase letters. + +```js +const arr = ["A", "b", "C"]; +arr.every(letter => letter === letter.toUpperCase()); +``` + +Add an `everyeven` property to your `spreadsheetFunctions` - use the `.every()` method to check if any element in the array is even. + +# --hints-- + +Your `spreadsheetFunctions` object should have an `everyeven` property. + +```js +assert.property(spreadsheetFunctions, "everyeven"); +``` + +Your `everyeven` property should be a function. + +```js +assert.isFunction(spreadsheetFunctions.everyeven); +``` + +Your `everyeven` function should return `true` if every element in the array is even. + +```js +assert.isTrue(spreadsheetFunctions.everyeven([2, 4, 6])); +``` + +Your `everyeven` function should return `false` if some of the elements in the array are not even. + +```js +assert.isFalse(spreadsheetFunctions.everyeven([1, 2, 3])); +``` + +# --seed-- + +## --seed-contents-- + +```html + + + + + + + Functional Programming Spreadsheet + + +
+
+
+ + + +``` + +```css +#container { + display: grid; + grid-template-columns: 50px repeat(10, 200px); + grid-template-rows: repeat(11, 30px); +} + +.label { + background-color: lightgray; + text-align: center; + vertical-align: middle; + line-height: 30px; +} +``` + +```js +const infixToFunction = { + "+": (x, y) => x + y, + "-": (x, y) => x - y, + "*": (x, y) => x * y, + "/": (x, y) => x / y, +} + +const infixEval = (str, regex) => str.replace(regex, (_match, arg1, operator, arg2) => infixToFunction[operator](parseFloat(arg1), parseFloat(arg2))); + +const highPrecedence = str => { + const regex = /([\d.]+)([*\/])([\d.]+)/; + const str2 = infixEval(str, regex); + return str === str2 ? str : highPrecedence(str2); +} + +const isEven = num => num % 2 === 0; +const sum = nums => nums.reduce((acc, el) => acc + el, 0); +const average = nums => sum(nums) / nums.length; + +const median = nums => { + const sorted = nums.slice().sort((a, b) => a - b); + const length = sorted.length; + const middle = length / 2 - 1; + return isEven(length) + ? average([sorted[middle], sorted[middle + 1]]) + : sorted[Math.ceil(middle)]; +} + +--fcc-editable-region-- +const spreadsheetFunctions = { + sum, + average, + median, + even: nums => nums.filter(isEven), + someeven: nums => nums.some(isEven), + + firsttwo: nums => nums.slice(0, 2), + lasttwo: nums => nums.slice(-2), + has2: nums => nums.includes(2), + increment: nums => nums.map(num => num + 1), +} +--fcc-editable-region-- + +const applyFunction = str => { + const noHigh = highPrecedence(str); + const infix = /([\d.]+)([+-])([\d.]+)/; + const str2 = infixEval(noHigh, infix); + const functionCall = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i; + const toNumberList = args => args.split(",").map(parseFloat); + const apply = (fn, args) => spreadsheetFunctions[fn.toLowerCase()](toNumberList(args)); + return str2.replace(functionCall, (match, fn, args) => spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? apply(fn, args) : match); +} + +const range = (start, end) => Array(end - start + 1).fill(start).map((element, index) => element + index); +const charRange = (start, end) => range(start.charCodeAt(0), end.charCodeAt(0)).map(code => String.fromCharCode(code)); + +const evalFormula = (x, cells) => { + const idToText = id => cells.find(cell => cell.id === id).value; + const rangeRegex = /([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi; + const rangeFromString = (num1, num2) => range(parseInt(num1), parseInt(num2)); + const elemValue = num => character => idToText(character + num); + const addCharacters = character1 => character2 => num => charRange(character1, character2).map(elemValue(num)); + const rangeExpanded = x.replace(rangeRegex, (_match, char1, num1, char2, num2) => rangeFromString(num1, num2).map(addCharacters(char1)(char2))); + const cellRegex = /[A-J][1-9][0-9]?/gi; + const cellExpanded = rangeExpanded.replace(cellRegex, match => idToText(match.toUpperCase())); + const functionExpanded = applyFunction(cellExpanded); + return functionExpanded === x ? functionExpanded : evalFormula(functionExpanded, cells); +} + +window.onload = () => { + const container = document.getElementById("container"); + const createLabel = (name) => { + const label = document.createElement("div"); + label.className = "label"; + label.textContent = name; + container.appendChild(label); + } + const letters = charRange("A", "J"); + letters.forEach(createLabel); + range(1, 99).forEach(number => { + createLabel(number); + letters.forEach(letter => { + const input = document.createElement("input"); + input.type = "text"; + input.id = letter + number; + input.ariaLabel = letter + number; + input.onchange = update; + container.appendChild(input); + }) + }) +} + +const update = event => { + const element = event.target; + const value = element.value.replace(/\s/g, ""); + if (!value.includes(element.id) && value.startsWith('=')) { + element.value = evalFormula(value.slice(1), Array.from(document.getElementById("container").children)); + } +} +``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-001.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-001.md deleted file mode 100644 index 08bc2a4aa43..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-001.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -id: 5d79253297c0ebb149ea9fed -title: Step 1 -challengeType: 0 -dashedName: step-1 ---- - -# --description-- - -In functional programming, we prefer immutable values over mutable values. - -Mutable values (declared with `var` or `let`) can lead to unexpected behaviors and bugs. Values declared with `const` cannot be reassigned, which makes using them easier because you don't have to keep track of their values. - -Start by creating an empty `infixToFunction` object using `const`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('constinfixToFunction={}')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-002.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-002.md deleted file mode 100644 index 3159f1d2410..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-002.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -id: 5d7925323be8848dbc58a07a -title: Step 2 -challengeType: 0 -dashedName: step-2 ---- - -# --description-- - -Above `infixToFunction`, define an empty function `add` using the `function` keyword. It should accept two parameters, `x` and `y`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('functionadd(x,y){}')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-003.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-003.md deleted file mode 100644 index c5dbbab705c..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-003.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -id: 5d792532f631702ae6d23e11 -title: Step 3 -challengeType: 0 -dashedName: step-3 ---- - -# --description-- - -Now return the sum of `x` and `y` using the `return` keyword. - -# --hints-- - -See description above for instructions. - -```js -assert(add(1, 2) === 3 && add(100, 2000) === 2100); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-004.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-004.md deleted file mode 100644 index 0a9d327d798..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-004.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -id: 5d7925329445167ecc2ac9c9 -title: Step 4 -challengeType: 0 -dashedName: step-4 ---- - -# --description-- - -In JavaScript, functions are first class. This means that they can be used like any other values - for example, they can be assigned to variables. - -Assign `add` to a new variable `addVar`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('constaddVar=add')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-005.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-005.md deleted file mode 100644 index 4e85d64fbe2..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-005.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -id: 5d792532b07918c3a5904913 -title: Step 5 -challengeType: 0 -dashedName: step-5 ---- - -# --description-- - -Anonymous functions are functions without names - they are used only once and then forgotten. The syntax is the same as for normal functions but without the name: - -```js -function(x) { - return x -} -``` - -First, remove the `addVar` definition. - -# --hints-- - -See description above for instructions. - -```js -assert(!code.replace(/\s/g, '').includes('constaddVar=add')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-006.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-006.md deleted file mode 100644 index a9aa387addd..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-006.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -id: 5d792533cc8b18b6c133edc7 -title: Step 6 -challengeType: 0 -dashedName: step-6 ---- - -# --description-- - -Anonymous functions are often passed as arguments to other functions, but what if you want to call one later? You can assign anonymous functions to variables and call them with the variable's name: - -```js -const fn = function(x) { - return x; -} - -fn(); -``` - -Assign the anonymous function to the variable `addVar`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('constaddVar=function(x,y){returnx+y')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-007.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-007.md deleted file mode 100644 index 68c44b16619..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-007.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -id: 5d7925337954ed57a565a135 -title: Step 7 -challengeType: 0 -dashedName: step-7 ---- - -# --description-- - -This is possible because the anonymous function has been immediately assigned to a value - this is effectively the same as using a named function. - -Rewrite `addVar` using ES6's arrow syntax: - -```js -const fn = (x, y) => x; -``` - -Note that the value is returned implicitly. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('constaddVar=(x,y)=>x+y')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-008.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-008.md deleted file mode 100644 index 676f6c6f4ff..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-008.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: 5d79253352e33dd59ec2f6de -title: Step 8 -challengeType: 0 -dashedName: step-8 ---- - -# --description-- - -Add the key `+` to `infixToFunction` and assign it the value `addVar`. - -# --hints-- - -See description above for instructions. - -```js -assert(infixToFunction['+'].toString() === addVar.toString()); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-009.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-009.md deleted file mode 100644 index c44846417a5..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-009.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -id: 5d792533d31e4f7fad33011d -title: Step 9 -challengeType: 0 -dashedName: step-9 ---- - -# --description-- - -In `infixToFunction`, replace `addVar` with `(x, y) => x + y`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').match(/\+["']:\(x,y\)=>x\+y/)); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-010.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-010.md deleted file mode 100644 index 2096072d738..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-010.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: 5d792533e7707b9645d7b540 -title: Step 10 -challengeType: 0 -dashedName: step-10 ---- - -# --description-- - -Remove the now redundant `addVar` definition. - -# --hints-- - -See description above for instructions. - -```js -assert(typeof addVar === 'undefined'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-011.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-011.md deleted file mode 100644 index 526e706eb08..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-011.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -id: 5d79253378595ec568f70ab6 -title: Step 11 -challengeType: 0 -dashedName: step-11 ---- - -# --description-- - -Add similar definitions for `-`, `*` and `/` in `infixToFunction`. - -# --hints-- - -See description above for instructions. - -```js -assert( - infixToFunction['-'](10, 2) === 8 && - infixToFunction['*'](10, 10) === 100 && - infixToFunction['/'](100, 10) === 10 -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-012.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-012.md deleted file mode 100644 index 37432637ac6..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-012.md +++ /dev/null @@ -1,92 +0,0 @@ ---- -id: 5d7925330918ae4a2f282e7e -title: Step 12 -challengeType: 0 -dashedName: step-12 ---- - -# --description-- - -Use arrow function syntax to define a function `infixEval` which takes `str` and `regex` as arguments and returns `str.replace(regex, "")`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constinfixEval=\(str,regex\)=>str\.replace\(regex,['"]{2}\)/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-013.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-013.md deleted file mode 100644 index 3d09b3967f2..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-013.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: 5d792533ed00e75d129e1b18 -title: Step 13 -challengeType: 0 -dashedName: step-13 ---- - -# --description-- - -`replace` is a higher order function because it can take a function as argument (higher order functions can also return functions). - -Pass the `+` function from `infixToFunction` to the `replace` method as the second argument. - -This is how you would pass the `-` function: - -```js -str.replace(regex, infixToFunction["-"]) -``` - -# --hints-- - -See description above for instructions. - -```js -assert(infixEval('ab', /(a)b/) === 'aba'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-014.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-014.md deleted file mode 100644 index 0926459ef14..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-014.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: 5d792533a5c42fb4d1a4b70d -title: Step 14 -challengeType: 0 -dashedName: step-14 ---- - -# --description-- - -Replace the second argument of `str.replace` with an anonymous function, which takes `match`, `arg1`, `fn`, and `arg2`, and returns `infixToFunction["+"]`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes('str.replace(regex,(match,arg1,fn,arg2)=>infixToFunction["+"])') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-015.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-015.md deleted file mode 100644 index 23968d2e070..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-015.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -id: 5d79253358e8f646cbeb2bb0 -title: Step 15 -challengeType: 0 -dashedName: step-15 ---- - -# --description-- - -Change the `"+"` in the call to `infixToFunction` to `fn`. - -`fn` is the operator that the user inputs (`+`, `-`, `*` or `/`) - we use `infixToFunction` to get the function that corresponds to it. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes('str.replace(regex,(match,arg1,fn,arg2)=>infixToFunction[fn])') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-016.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-016.md deleted file mode 100644 index f3dd1211e6a..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-016.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -id: 5d792533bb38fab70b27f527 -title: Step 16 -challengeType: 0 -dashedName: step-16 ---- - -# --description-- - -`arg1` and `arg2` are the numbers input by the user in a string such as "1+3". - -Pass `parseFloat(arg1)` and `parseFloat(arg2)` as the arguments to `infixToFunction[fn]` (remember `infixToFunction[fn]` is a function). - -# --hints-- - -See description above for instructions. - -```js -const regex = /([0-9.]+)([+-\/*])([0-9.]+)/; -assert( - infixEval('23+35', regex) === '58' && - infixEval('100-20', regex) === '80' && - infixEval('10*10', regex) === '100' && - infixEval('120/6', regex) === '20' -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-017.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-017.md deleted file mode 100644 index e295114e777..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-017.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: 5d79253386060ed9eb04a070 -title: Step 17 -challengeType: 0 -dashedName: step-17 ---- - -# --description-- - -The `match` parameter is currently unused, which can lead to unused variable warnings in some linters. - -To fix this, prefix or replace it with an underscore (`_`) - both ways signal to the reader and linter that you're aware you don't need this. - -Note that a single underscore can only be used once in a function and may conflict with some libraries (Lodash, Underscore.js). - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('str.replace(regex,(_')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-018.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-018.md deleted file mode 100644 index 1af15a10b8e..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-018.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -id: 5d792533717672657b81aa69 -title: Step 18 -challengeType: 0 -dashedName: step-18 ---- - -# --description-- - -When defining an arrow function with a single argument, the parentheses can be omitted: - -```js -const greeting = name => `Hello !`; -``` - -Define a function `highPrecedence` which takes a single argument `str` and returns it. - -# --hints-- - -See description above for instructions. - -```js -assert(highPrecedence('a') === 'a'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-019.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-019.md deleted file mode 100644 index 5c2d8560932..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-019.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -id: 5d7925335ab63018dcec11fe -title: Step 19 -challengeType: 0 -dashedName: step-19 ---- - -# --description-- - -Arrow functions can have multiple statements: - -```js -const fn = (x, y) => { - const result = x + y; - return result; // explicit return statement required -}; -``` - -Use this syntax for the `highPrecedence` function. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('highPrecedence=str=>{returnstr')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-020.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-020.md deleted file mode 100644 index 1ddd40ce5d8..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-020.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -id: 5d7925330f300c342315066d -title: Step 20 -challengeType: 0 -dashedName: step-20 ---- - -# --description-- - -In `highPrecedence`, define `regex` to be `/([0-9.]+)([*\/])([0-9.]+)/`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('regex=/([0-9.]+)([*\\/])([0-9.]+)/')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-021.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-021.md deleted file mode 100644 index 3bfba3454a9..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-021.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -id: 5d792533aa6443215c9b16bf -title: Step 21 -challengeType: 0 -dashedName: step-21 ---- - -# --description-- - -Now, assign the result of calling `infixEval` with `str` and `regex` to `str2`. Return `str2`. - -# --hints-- - -See description above for instructions. - -```js -assert(highPrecedence('7*6') === '42' && highPrecedence('50/25') === '2'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-022.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-022.md deleted file mode 100644 index 333b8bcb122..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-022.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: 5d7925334c5e22586dd72962 -title: Step 22 -challengeType: 0 -dashedName: step-22 ---- - -# --description-- - -The ternary operator has the following syntax: - -```js -const result = condition ? valueIfTrue : valueIfFalse; -const result = 1 === 1 ? 1 : 0; // 1 -const result = 9 > 10 ? "Yes" : "No"; // "No" -``` - -Use this operator to return `str` if `str === str2`, and an empty string (`""`) otherwise. - -# --hints-- - -See description above for instructions. - -```js -assert( - highPrecedence('2*2') === '' && - highPrecedence('2+2') === '2+2' && - code.includes('?') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-023.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-023.md deleted file mode 100644 index c5f666b8a05..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-023.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -id: 5d79253307ecd49e030bdcd1 -title: Step 23 -challengeType: 0 -dashedName: step-23 ---- - -# --description-- - -Recursion is when a function calls itself. We often use it instead of `while`/`for` loops, as loops usually involve mutable state. - -Replace the empty string in `highPrecedence` with a call to `highPrecedence` with `str2` as argument. - -# --hints-- - -See description above for instructions. - -```js -assert( - highPrecedence('2*2*2') === '8' && - highPrecedence('2*2') === '4' && - highPrecedence('2+2') === '2+2' -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-024.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-024.md deleted file mode 100644 index c837d8e94e1..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-024.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -id: 5d792534257122211d3043af -title: Step 24 -challengeType: 0 -dashedName: step-24 ---- - -# --description-- - -Define an object `spreadsheetFunctions`, with a single key - an empty string (`""`). The corresponding value should be the function `x => x`. - -# --hints-- - -See description above for instructions. - -```js -assert(spreadsheetFunctions['']('x') === 'x'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-025.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-025.md deleted file mode 100644 index 58109dce7a4..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-025.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -id: 5d7925346f4f2da6df4354a6 -title: Step 25 -challengeType: 0 -dashedName: step-25 ---- - -# --description-- - -Define an empty function `applyFn` which takes an argument `str`. Use the curly brace syntax with an anonymous function. Do not wrap parentheses around the parameter. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('constapplyFn=str=>{}')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-026.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-026.md deleted file mode 100644 index 313db4427d6..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-026.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -id: 5d792534cac2dbe0a719ea7a -title: Step 26 -challengeType: 0 -dashedName: step-26 ---- - -# --description-- - -Set `noHigh` to `highPrecedence(str)` in `applyFn`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes('constapplyFn=str=>{constnoHigh=highPrecedence(str)') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-027.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-027.md deleted file mode 100644 index bc94c78c155..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-027.md +++ /dev/null @@ -1,131 +0,0 @@ ---- -id: 5d792534857332d07ccba3ad -title: Step 27 -challengeType: 0 -dashedName: step-27 ---- - -# --description-- - -Set `infix` to `/([0-9.]+)([+-])([0-9.]+)/` in `applyFn`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'constapplyFn=str=>{constnoHigh=highPrecedence(str);constinfix=/([0-9.]+)([+-])([0-9.]+)/' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-028.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-028.md deleted file mode 100644 index 7972802a8b8..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-028.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -id: 5d792534d586ef495ea9df90 -title: Step 28 -challengeType: 0 -dashedName: step-28 ---- - -# --description-- - -Set `str2` to `infixEval(noHigh, infix)`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'constapplyFn=str=>{constnoHigh=highPrecedence(str);constinfix=/([0-9.]+)([+-])([0-9.]+)/;conststr2=infixEval(noHigh,infix)' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-029.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-029.md deleted file mode 100644 index f957c47d628..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-029.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -id: 5d79253410532e13d13fe574 -title: Step 29 -challengeType: 0 -dashedName: step-29 ---- - -# --description-- - -Set `regex` to `/([a-z]*)\(([0-9., ]*)\)(?!.*\()/i` in `applyFn`. - -# --hints-- - -See description above for instructions. - -```js -assert( - applyFn - .toString() - .replace(/\s/g, '') - .includes('varregex=/([a-z]*)\\(([0-9.,]*)\\)(?!.*\\()/i') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-030.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-030.md deleted file mode 100644 index 42b80301fc6..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-030.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -id: 5d7925342415527083bd6667 -title: Step 30 -challengeType: 0 -dashedName: step-30 ---- - -# --description-- - -The `split` method returns an array of strings from a larger string by using its argument to determine where to make each split: - -```js -"a b c".split(" "); // ["a", "b", "c"]; -``` - -Add a function `toNumberList` (inside `applyFn`) which takes an argument `args` and splits it by commas. Return `toNumberList`. - -# --hints-- - -See description above for instructions. - -```js -assert(JSON.stringify(applyFn('')('foo,baz,bar')) === '["foo","baz","bar"]'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-031.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-031.md deleted file mode 100644 index 33e85a097cc..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-031.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: 5d792534c3d26890ac1484d4 -title: Step 31 -challengeType: 0 -dashedName: step-31 ---- - -# --description-- - -The `map` method takes a function and for each element of an array, it passes the element to the function and replace the element with the return value: - -```js -[1, 2, 3].map(x => x + 1); // [2, 3, 4] -``` - -In `toNumberList`, chain the `map` method to `args.split(",")` and pass it `parseFloat` to parse each element of the array into a number. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes('consttoNumberList=args=>args.split(",").map(parseFloat)') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-032.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-032.md deleted file mode 100644 index abb91060f5e..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-032.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: 5d792534b92f3d1cd4410ce3 -title: Step 32 -challengeType: 0 -dashedName: step-32 ---- - -# --description-- - -Define a new function `applyFunction` (inside `applyFn`). It should take two arguments: `fn` and `args`, and should return `spreadsheetFunctions`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'consttoNumberList=args=>args.split(",").map(parseFloat);constapplyFunction=(fn,args)=>spreadsheetFunctions' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-033.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-033.md deleted file mode 100644 index bb2f8da03a5..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-033.md +++ /dev/null @@ -1,140 +0,0 @@ ---- -id: 5d7925341193948dfe6d76b4 -title: Step 33 -challengeType: 0 -dashedName: step-33 ---- - -# --description-- - -Now, instead of returning `spreadsheetFunctions`, use bracket notation and `fn.toLowerCase()` to get a specific function from `spreadsheetFunctions`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'consttoNumberList=args=>args.split(",").map(parseFloat);constapplyFunction=(fn,args)=>spreadsheetFunctions[fn.toLowerCase()]' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-034.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-034.md deleted file mode 100644 index f32c582d3ef..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-034.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -id: 5d792534cf81365cfca58794 -title: Step 34 -challengeType: 0 -dashedName: step-34 ---- - -# --description-- - -Apply `toNumberList(args)` to `spreadsheetFunctions[fn.toLowerCase()]`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'consttoNumberList=args=>args.split(",").map(parseFloat);constapplyFunction=(fn,args)=>spreadsheetFunctions[fn.toLowerCase()](toNumberList(args))' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-035.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-035.md deleted file mode 100644 index a460b595da1..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-035.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: 5d7925348ee084278ff15556 -title: Step 35 -challengeType: 0 -dashedName: step-35 ---- - -# --description-- - -Note that `applyFunction` can access `toNumberList` from outside of itself. This is called lexical scoping - inner functions can access variables from outer functions. - -Now return `str2.replace(regex, "")` at the end of `applyFn`. - -# --hints-- - -See description above for instructions. - -```js -assert(applyFn('2*2fn(1, 2, 3.3)') === '4'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-036.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-036.md deleted file mode 100644 index 45e848ecbeb..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-036.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -id: 5d7925348a6a41c32f7a4e3e -title: Step 36 -challengeType: 0 -dashedName: step-36 ---- - -# --description-- - -Replace the `""` in `str2.replace(regex, "")` with a function which takes `match`, `fn` and `args` as arguments and returns `spreadsheetFunctions`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes('returnstr2.replace(regex,(match,fn,args)=>spreadsheetFunctions)') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-037.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-037.md deleted file mode 100644 index 7394c7c6472..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-037.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -id: 5d792534408c5be896b0a46e -title: Step 37 -challengeType: 0 -dashedName: step-37 ---- - -# --description-- - -The `hasOwnProperty` method checks if a key exists in an object. So `spreadsheetFunctions.hasOwnProperty("")` would return `true`, but replacing `""` with anything else would make it return `false`. - -Chain `hasOwnProperty` to `spreadsheetFunctions` to check if the `fn.toLowerCase()` key exists in `spreadsheetFunctions`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'returnstr2.replace(regex,(match,fn,args)=>spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()))' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-038.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-038.md deleted file mode 100644 index c86fe809104..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-038.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -id: 5d792534f0eda837510e9192 -title: Step 38 -challengeType: 0 -dashedName: step-38 ---- - -# --description-- - -Now use the ternary operator in the last line to return `applyFunction(fn, args)` if the statement is true, and `match` otherwise. - -# --hints-- - -See description above for instructions. - -```js -assert(applyFn('2+2*2') === '6' && applyFn('(2+2)*2') === '4*2'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-039.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-039.md deleted file mode 100644 index bfa91d4503f..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-039.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -id: 5d7925346b911fce161febaf -title: Step 39 -challengeType: 0 -dashedName: step-39 ---- - -# --description-- - -Now define an empty function `range` which takes `start` and `end` as arguments (define it in the global scope). - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('constrange=(start,end)=>')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-040.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-040.md deleted file mode 100644 index 24d94216931..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-040.md +++ /dev/null @@ -1,158 +0,0 @@ ---- -id: 5d79253483eada4dd69258eb -title: Step 40 -challengeType: 0 -dashedName: step-40 ---- - -# --description-- - -`range` should set `arr` to `[start]` and should then return `arr`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code.replace(/\s/g, '').includes('constarr=[start]') && - JSON.stringify(range(1)) === '[1]' -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-041.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-041.md deleted file mode 100644 index 4307ef2889a..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-041.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -id: 5d7925342b2b993ef18cd45f -title: Step 41 -challengeType: 0 -dashedName: step-41 ---- - -# --description-- - -After declaring `arr`, but before returning it, `range` should use the `push` method to add `end` onto `arr`. - -# --hints-- - -See description above for instructions. - -```js -assert(JSON.stringify(range(1, 2)) === '[1,2]' && code.includes('push')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-042.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-042.md deleted file mode 100644 index 0fa8e6fe0fb..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-042.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -id: 5d7925341747ad42b12f8e68 -title: Step 42 -challengeType: 0 -dashedName: step-42 ---- - -# --description-- - -This is still valid because we're modifying `arr` in place instead of reassigning to it (which is invalid with the `const` keyword). But doing this still modifies state, and we don't want to do that in functional programming. - -The `concat` method returns a new array instead of modifying an existing one: - -```js -[1,2,3].concat(4); // [1, 2, 3, 4] -[1,2,3].concat(4, 5); // [1, 2, 3, 4, 5] -``` - -Use `concat` instead of `push` to return the result of adding `end` to `arr`. - -# --hints-- - -See description above for instructions. - -```js -assert( - JSON.stringify(range(1, 2)) === '[1,2]' && - code.includes('concat') && - !code.includes('push') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-043.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-043.md deleted file mode 100644 index 448578598f5..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-043.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -id: 5d792535b0b3c198ee3ed6f9 -title: Step 43 -challengeType: 0 -dashedName: step-43 ---- - -# --description-- - -The `concat` method can also accept arrays: - -```js -[1,2,3].concat([4, 5]); // [1, 2, 3, 4, 5] -[1,2,3].concat([4, 5], [6, 7]); // [1, 2, 3, 4, 5, 6, 7] -``` - -Use this form of `concat` by passing an array with just `end` to it: `arr.concat([end])`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('returnarr.concat([end])')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-044.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-044.md deleted file mode 100644 index 6e89d44a236..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-044.md +++ /dev/null @@ -1,158 +0,0 @@ ---- -id: 5d7925357a0533eb221b005d -title: Step 44 -challengeType: 0 -dashedName: step-44 ---- - -# --description-- - -Replace the call to `arr` in `arr.concat([end])` with `[start]` and remove the `arr` variable and its definition. - -# --hints-- - -See description above for instructions. - -```js -assert( - !code.includes('arr') && - code.replace(/\s/g, '').includes('[start].concat([end])') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-045.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-045.md deleted file mode 100644 index 0d876da26b6..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-045.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -id: 5d792535591db67ee15b4106 -title: Step 45 -challengeType: 0 -dashedName: step-45 ---- - -# --description-- - -Use the ternary operator to return `[]` if `start > end` and `[start].concat([end])` otherwise. - -# --hints-- - -See description above for instructions. - -```js -assert( - JSON.stringify(range(3, 2)) === '[]' && - JSON.stringify(range(1, 3)) === '[1,3]' -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-046.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-046.md deleted file mode 100644 index ee94e71d4a4..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-046.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -id: 5d792535f1f7adf77de5831d -title: Step 46 -challengeType: 0 -dashedName: step-46 ---- - -# --description-- - -Replace `[end]` with a recursive call to `range`: `[start].concat(range(start + 1, end))` - -# --hints-- - -See description above for instructions. - -```js -assert(JSON.stringify(range(1, 5)) === '[1,2,3,4,5]'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-047.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-047.md deleted file mode 100644 index 497b63c634b..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-047.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: 5d7925353d2c505eafd50cd9 -title: Step 47 -challengeType: 0 -dashedName: step-47 ---- - -# --description-- - -Remove the curly braces and `return` keyword from `range`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'constrange=(start,end)=>start>end?[]:[start].concat(range(start+1,end))' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-048.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-048.md deleted file mode 100644 index 862a0002f2f..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-048.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -id: 5d79253539b5e944ba3e314c -title: Step 48 -challengeType: 0 -dashedName: step-48 ---- - -# --description-- - -Define a function `charRange` which takes `start` and `end` as arguments. It should return `start`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('constcharRange=(start,end)=>start')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-049.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-049.md deleted file mode 100644 index 9845839bbeb..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-049.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -id: 5d792535a4f1cbff7a8b9a0b -title: Step 49 -challengeType: 0 -dashedName: step-49 ---- - -# --description-- - -Make `charRange` return `range(start, end)`. - -# --hints-- - -See description above for instructions. - -```js -assert(JSON.stringify(charRange(1, 5)) === '[1,2,3,4,5]'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-050.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-050.md deleted file mode 100644 index 43167394a7b..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-050.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -id: 5d792535e3304f15a8890162 -title: Step 50 -challengeType: 0 -dashedName: step-50 ---- - -# --description-- - -Use the `charCodeAt(0)` method on `start` and `end` in `charRange`, like this: `start.charCodeAt(0)`. - -# --hints-- - -See description above for instructions. - -```js -assert(JSON.stringify(charRange('A', 'C')) === '[65,66,67]'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-051.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-051.md deleted file mode 100644 index f5bb024255e..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-051.md +++ /dev/null @@ -1,160 +0,0 @@ ---- -id: 5d792535a40ea5ac549d6804 -title: Step 51 -challengeType: 0 -dashedName: step-51 ---- - -# --description-- - -Chain `map` onto `range(start.charCodeAt(0), end.charCodeAt(0))`, with `x => x` as the argument. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes('range(start.charCodeAt(0),end.charCodeAt(0)).map(x=>x)') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-052.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-052.md deleted file mode 100644 index 8369854b752..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-052.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: 5d7925358c220e5b2998909e -title: Step 52 -challengeType: 0 -dashedName: step-52 ---- - -# --description-- - -Now, pass `x` to `String.fromCharCode` in the arrow function. - -# --hints-- - -See description above for instructions. - -```js -assert(JSON.stringify(charRange('A', 'C')) === '["A","B","C"]'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-053.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-053.md deleted file mode 100644 index 6253e20d545..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-053.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -id: 5d7925357729e183a49498aa -title: Step 53 -challengeType: 0 -dashedName: step-53 ---- - -# --description-- - -Create a new function `evalFormula` which takes a single argument, `x`. Set `/([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi` to a variable named `rangeRegex`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'constevalFormula=x=>{constrangeRegex=/([A-J])([1-9][0-9]?):([A-J])([1-9][0-9]?)/gi' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-054.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-054.md deleted file mode 100644 index 03ceaf96068..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-054.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -id: 5d79253555aa652afbb68086 -title: Step 54 -challengeType: 0 -dashedName: step-54 ---- - -# --description-- - -Define a function `rangeFromString` in `evalFormula` which takes `n1` and `n2` as arguments and returns `n1`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /evalFormula.*constrangeFromString=\(n1,n2\)=>n1/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-055.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-055.md deleted file mode 100644 index 27b4b66f7f2..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-055.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -id: 5d79253582be306d339564f6 -title: Step 55 -challengeType: 0 -dashedName: step-55 ---- - -# --description-- - -Replace the `n1` return value in `rangeFromString` with `range(n1, n2)`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /evalFormula.*constrangeFromString=\(n1,n2\)=>range\(n1,n2\)/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-056.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-056.md deleted file mode 100644 index 72223dddb2c..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-056.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -id: 5d7925352047e5c54882c436 -title: Step 56 -challengeType: 0 -dashedName: step-56 ---- - -# --description-- - -As `n1` and `n2` are actually strings, replace `n1` and `n2` with `parseInt(n1)` and `parseInt(n2)`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /evalFormula.*constrangeFromString=\(n1,n2\)=>range\(parseInt\(n1\),parseInt\(n2\)\)/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-057.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-057.md deleted file mode 100644 index 1870ab8b951..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-057.md +++ /dev/null @@ -1,177 +0,0 @@ ---- -id: 5d79253568e441c0adf9db9f -title: Step 57 -challengeType: 0 -dashedName: step-57 ---- - -# --description-- - -Now define a function `elemValue`, which takes an argument `n` and returns `n`. Use the curly brace arrow function syntax. - -# --hints-- - -See description above for instructions. - -```js -assert( - /evalFormula.*constelemValue=n=>\{returnn;?\}/.test(code.replace(/\s/g, '')) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-058.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-058.md deleted file mode 100644 index b394d603ed4..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-058.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -id: 5d7925356ab117923b80c9cd -title: Step 58 -challengeType: 0 -dashedName: step-58 ---- - -# --description-- - -Inside `elemValue`, define `fn` to be a function which takes `c` as argument and returns `document.getElementById(c + n).value`. Return `fn` instead of `n`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /elemValue.*constfn=\(?c\)?=>document\.getElementById\(c\+n\)\.value;?returnfn;?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-059.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-059.md deleted file mode 100644 index e79d2b6f857..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-059.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -id: 5d792535e54a8cd729a0d708 -title: Step 59 -challengeType: 0 -dashedName: step-59 ---- - -# --description-- - -Now define `fn` to be `elemValue("1")` (inside `evalFormula` but outside `elemValue`). As `elemValue` returns a function, `fn` is also a function. - -# --hints-- - -See description above for instructions. - -```js -assert( - /elemValue.*constfn=elemValue\(['"]1['"]\);?\}/.test(code.replace(/\s/g, '')) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-060.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-060.md deleted file mode 100644 index 3d6a5a955b7..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-060.md +++ /dev/null @@ -1,187 +0,0 @@ ---- -id: 5d7925353b307724a462b06b -title: Step 60 -challengeType: 0 -dashedName: step-60 ---- - -# --description-- - -Finally, return `fn("A")`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /elemValue.*constfn=elemValue\(['"]1['"]\);?returnfn\(['"]A['"]\);?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-061.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-061.md deleted file mode 100644 index 994e931f57f..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-061.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -id: 5d792536735f71d746ee5d99 -title: Step 61 -challengeType: 0 -dashedName: step-61 ---- - -# --description-- - -You might think that this wouldn't work because `fn` wouldn't have access to `n` after `elemValue` has finished executing. However, this works because of closures - functions have access to all variables declared at their time of creation. - -Inside `elemValue`, remove the variable `fn` and its definition, and replace `return fn` with `return c => document.getElementById(c + n).value`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes('constelemValue=n=>{returnc=>document.getElementById(c+n).value') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-062.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-062.md deleted file mode 100644 index b06f86f5495..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-062.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -id: 5d792536ad340d9dff2e4a96 -title: Step 62 -challengeType: 0 -dashedName: step-62 ---- - -# --description-- - -Now, remove the curly braces and return statement. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constelemValue=n=>\(?c=>document\.getElementById\(c\+n\)\.value/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-063.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-063.md deleted file mode 100644 index d1492aa5cbf..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-063.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -id: 5d7925369614afd92d01fed5 -title: Step 63 -challengeType: 0 -dashedName: step-63 ---- - -# --description-- - -You also don't need the parentheses in `elemValue` - it's parsed this way automatically. Remove them. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constelemValue=n=>c=>document\.getElementById\(c\+n\)\.value/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-064.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-064.md deleted file mode 100644 index 8d17549a291..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-064.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -id: 5d792536504e68254fe02236 -title: Step 64 -challengeType: 0 -dashedName: step-64 ---- - -# --description-- - -The technique we just used is called currying - instead of taking multiple arguments, a function takes a single argument and return another function, which also takes a single argument. - -Define a new curried function, `addChars`, and set it equal to `c1 => c2 => c1 + c2`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('constaddChars=c1=>c2=>c1+c2')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-065.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-065.md deleted file mode 100644 index 1c388711e2f..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-065.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -id: 5d792536c8d2f0fdfad768fe -title: Step 65 -challengeType: 0 -dashedName: step-65 ---- - -# --description-- - -You can add more arguments by simply adding another arrow with another argument name: - -```js -const manyArguments = a => b => c => d => [a, b, c, d] -``` - -Add another argument to `addChars` and add it to the sum: `c1 => c2 => n => c1 + c2 + n`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('constaddChars=c1=>c2=>n=>c1+c2+n')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-066.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-066.md deleted file mode 100644 index 45e6af501cc..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-066.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -id: 5d79253639028b8ec56afcda -title: Step 66 -challengeType: 0 -dashedName: step-66 ---- - -# --description-- - -Replace the body of `addChars`, so that instead of adding the arguments, it returns a `charRange` between the first two arguments: `c1 => c2 => n => charRange(c1, c2)`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code.replace(/\s/g, '').includes('constaddChars=c1=>c2=>n=>charRange(c1,c2)') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-067.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-067.md deleted file mode 100644 index 19bbc068cd3..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-067.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -id: 5d792536834f2fd93e84944f -title: Step 67 -challengeType: 0 -dashedName: step-67 ---- - -# --description-- - -You call curried functions like this: - -```js -const result = add(1)(2); -``` - -Use `map` on the `charRange` in `addChars`, passing in `x => elemValue(n)(x)` as the argument. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'constaddChars=c1=>c2=>n=>charRange(c1,c2).map(x=>elemValue(n)(x))' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-068.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-068.md deleted file mode 100644 index e220cf656e5..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-068.md +++ /dev/null @@ -1,186 +0,0 @@ ---- -id: 5d792536ddff9ea73c90a994 -title: Step 68 -challengeType: 0 -dashedName: step-68 ---- - -# --description-- - -However, you don't need an arrow function. As `elemValue(n)` is a function, you can pass it to `map` directly. - -Change `x => elemValue(n)(x)` to `elemValue(n)`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes('constaddChars=c1=>c2=>n=>charRange(c1,c2).map(elemValue(n))') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-069.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-069.md deleted file mode 100644 index eaff17e3511..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-069.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -id: 5d7925361596f84067904f7f -title: Step 69 -challengeType: 0 -dashedName: step-69 ---- - -# --description-- - -Remove the `fn` declaration and return statement. Set `varRangeExpanded` to the result of using the `replace` method on `x`, with `rangeRegex` as the first argument and `""` as the second argument. Then, return it. - -# --hints-- - -See description above for instructions. - -```js -assert( - !code.includes('const fn') && - code.includes('varRangeExpanded') && - evalFormula('A1:J133') === '3' -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-070.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-070.md deleted file mode 100644 index 03ec1f65ba2..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-070.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -id: 5d792536dd8a4daf255488ac -title: Step 70 -challengeType: 0 -dashedName: step-70 ---- - -# --description-- - -Replace the `""` in `varRangeExpanded` with a function, which takes `match`, `c1`, `n1`, `c2` and `n2` as arguments, and returns `n1`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'constvarRangeExpanded=x.replace(rangeRegex,(match,c1,n1,c2,n2)=>n1)' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-071.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-071.md deleted file mode 100644 index b1139d99d92..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-071.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -id: 5d792536449c73004f265fb1 -title: Step 71 -challengeType: 0 -dashedName: step-71 ---- - -# --description-- - -Replace the `n1` return value in `varRangeExpanded` with `rangeFromString(n1, n2)`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'constvarRangeExpanded=x.replace(rangeRegex,(match,c1,n1,c2,n2)=>rangeFromString(n1,n2))' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-072.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-072.md deleted file mode 100644 index a481e918c67..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-072.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -id: 5d79253685fc69b8fe60a0d2 -title: Step 72 -challengeType: 0 -dashedName: step-72 ---- - -# --description-- - -Chain the `map` method to `rangeFromString(n1, n2)` and pass it `addChars(c1)(c2)` as an argument. - -This returns an `addChars` function, which has `c1` and `c2` (the characters) preset, and only needs a number (`n`) to be passed to it (which we get from the `rangeFromString` array). - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'constvarRangeExpanded=x.replace(rangeRegex,(match,c1,n1,c2,n2)=>rangeFromString(n1,n2).map(addChars(c1)(c2)))' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-073.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-073.md deleted file mode 100644 index 64e48966f02..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-073.md +++ /dev/null @@ -1,188 +0,0 @@ ---- -id: 5d792536dc6e3ab29525de9e -title: Step 73 -challengeType: 0 -dashedName: step-73 ---- - -# --description-- - -The function in `varRangeExpanded` contains an unused argument. Replace or prefix it with an underscore. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes('constvarRangeExpanded=x.replace(rangeRegex,(_') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-074.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-074.md deleted file mode 100644 index 57da365160d..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-074.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -id: 5d792536cfd0fd893c630abb -title: Step 74 -challengeType: 0 -dashedName: step-74 ---- - -# --description-- - -Set `varRegex` to `/[A-J][1-9][0-9]?/gi`. Then set `varExpanded` to the result of replacing `varRegex` with an empty string in `varRangeExpanded`. Return `varExpanded`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code.includes('varRegex') && - code.includes('varExpanded') && - evalFormula('aC12bc') === 'abc' -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-075.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-075.md deleted file mode 100644 index 2dc9ec5c8ab..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-075.md +++ /dev/null @@ -1,197 +0,0 @@ ---- -id: 5d7925366a5ff428fb483b40 -title: Step 75 -challengeType: 0 -dashedName: step-75 ---- - -# --description-- - -Replace the `""` in `varExpanded` with `match => document.getElementById(match.toUpperCase()).value`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'constvarExpanded=varRangeExpanded.replace(varRegex,match=>document.getElementById(match.toUpperCase()).value)' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-076.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-076.md deleted file mode 100644 index 0516f1f77e6..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-076.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -id: 5d7925365d4035eeb2e395fd -title: Step 76 -challengeType: 0 -dashedName: step-76 ---- - -# --description-- - -Set `functionExpanded` to `applyFn(varExpanded)` in `evalFormula`. Return `functionExpanded`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.includes('functionExpanded') && applyFn('2+2') === '4'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-077.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-077.md deleted file mode 100644 index a1022f45c6a..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-077.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -id: 5d7925364c106e9aaf05a16f -title: Step 77 -challengeType: 0 -dashedName: step-77 ---- - -# --description-- - -`evalFormula` should return the value passed to it if this value remained unchanged. Otherwise, it should call itself with the latest value. - -Use the ternary operator in the last line of `evalFormula` to return `functionExpanded` if `x === functionExpanded` and `evalFormula(functionExpanded)` otherwise. - -# --hints-- - -See description above for instructions. - -```js -assert(evalFormula('(2+2)*2') === '8'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-078.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-078.md deleted file mode 100644 index 5617221e798..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-078.md +++ /dev/null @@ -1,208 +0,0 @@ ---- -id: 5d792536970cd8e819cc8a96 -title: Step 78 -challengeType: 0 -dashedName: step-78 ---- - -# --description-- - -You can define arrow functions without arguments: - -```js -const two = () => 2; -``` - -Define an empty arrow function without arguments and assign it to `window.onload`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('window.onload=()=>')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-079.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-079.md deleted file mode 100644 index 06b401c7e8e..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-079.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -id: 5d792536e33baeaa60129e0a -title: Step 79 -challengeType: 0 -dashedName: step-79 ---- - -# --description-- - -In `window.onload`, assign `document.getElementById("container")` to `container`. Also assign `charRange("A", "J")` to `letters`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /window\.onload=\(\)=>\{constcontainer=document\.getElementById\(["']container["']\);?constletters=charRange\(["']A["'],["']J["']\);?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-080.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-080.md deleted file mode 100644 index 59443f50dc9..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-080.md +++ /dev/null @@ -1,217 +0,0 @@ ---- -id: 5d7925379e2a488f333e2d43 -title: Step 80 -challengeType: 0 -dashedName: step-80 ---- - -# --description-- - -Now define a function `createLabel` which takes an argument `name` and has an empty body. - -# --hints-- - -See description above for instructions. - -```js -assert( - /window\.onload[\s\S]*constcreateLabel=\(?name\)?=>\{\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-081.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-081.md deleted file mode 100644 index 3a3a6f126c8..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-081.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -id: 5d7925379000785f6d8d9af3 -title: Step 81 -challengeType: 0 -dashedName: step-81 ---- - -# --description-- - -Inside `createLabel`, assign `document.createElement("div")` to `label`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /window\.onload[\s\S]*constcreateLabel=\(?name\)?=>\{constlabel=document\.createElement\(["']div["']\);?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-082.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-082.md deleted file mode 100644 index a9a1dcc5726..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-082.md +++ /dev/null @@ -1,229 +0,0 @@ ---- -id: 5d79253791391b0acddd0ac5 -title: Step 82 -challengeType: 0 -dashedName: step-82 ---- - -# --description-- - -Add the following code to `createLabel`: - -```js -label.className = "label"; -label.textContent = name; -container.appendChild(label); -``` - -# --hints-- - -See description above for instructions. - -```js -assert( - /window\.onload[\s\S]*constcreateLabel=\(?name\)?=>\{constlabel=document\.createElement\(["']div["']\);?label\.className=["']label["'];?label\.textContent=name;?container\.appendChild\(label\);?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-083.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-083.md deleted file mode 100644 index 780a9dab7fe..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-083.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -id: 5d7925373104ae5ae83f20a5 -title: Step 83 -challengeType: 0 -dashedName: step-83 ---- - -# --description-- - -The `forEach` method takes a function and calls it with each element of the array. - -Chain `forEach` to `letters` and pass it the `createLabel` function to create a label for each of the letters. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('letters.forEach(createLabel)')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-084.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-084.md deleted file mode 100644 index ccfac003142..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-084.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -id: 5d7925373b7127cfaeb50c26 -title: Step 84 -challengeType: 0 -dashedName: step-84 ---- - -# --description-- - -Add `range(1, 99)` to the end of `window.onload` (the result will be discarded for now). - -# --hints-- - -See description above for instructions. - -```js -assert(/window\.onload[\s\S]*range\(1,99\);?\}/.test(code.replace(/\s/g, ''))); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-085.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-085.md deleted file mode 100644 index 5216d89d1d9..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-085.md +++ /dev/null @@ -1,230 +0,0 @@ ---- -id: 5d792537cb3a5cd6baca5e1a -title: Step 85 -challengeType: 0 -dashedName: step-85 ---- - -# --description-- - -Chain `forEach` onto `range(1, 99)`, passing in `createLabel` as an argument. - -# --hints-- - -See description above for instructions. - -```js -assert( - /window\.onload[\s\S]*range\(1,99\)\.forEach\(createLabel\);?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-086.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-086.md deleted file mode 100644 index 544000db907..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-086.md +++ /dev/null @@ -1,232 +0,0 @@ ---- -id: 5d79253742f3313d55db981f -title: Step 86 -challengeType: 0 -dashedName: step-86 ---- - -# --description-- - -Replace `createLabel` with an arrow function with a block body. This would allow us to add more statements. The arrow function should take an argument `x`, and call `createLabel(x)`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /window\.onload[\s\S]*range\(1,99\)\.forEach\(\(?x\)?=>\{createLabel\(x\);?\}\);?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-087.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-087.md deleted file mode 100644 index bf8bee8395a..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-087.md +++ /dev/null @@ -1,237 +0,0 @@ ---- -id: 5d7925379e0180a438ce7f95 -title: Step 87 -challengeType: 0 -dashedName: step-87 ---- - -# --description-- - -Inside the `range` `forEach`, use the `forEach` method on `letters`, passing in a function with argument `x` and an empty body. - -# --hints-- - -See description above for instructions. - -```js -assert( - /window\.onload.*range\(1,99\)\.forEach\(\(?x\)?=>\{createLabel\(x\);?letters\.forEach\(\(?y\)?=>\{\}\);?\}\);?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-088.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-088.md deleted file mode 100644 index d57aa617713..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-088.md +++ /dev/null @@ -1,239 +0,0 @@ ---- -id: 5d792537c80984dfa5501b96 -title: Step 88 -challengeType: 0 -dashedName: step-88 ---- - -# --description-- - -Inside `letters.forEach`, assign `document.createElement("input")` to `input`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /window\.onload[\s\S]*range\(1,99\)\.forEach\(\(?x\)?=>\{createLabel\(x\);?letters\.forEach\(\(?y\)?=>\{constinput=document\.createElement\(["']input["']\);?\}\);?\}\);?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-089.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-089.md deleted file mode 100644 index 4568ec50b24..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-089.md +++ /dev/null @@ -1,251 +0,0 @@ ---- -id: 5d7925377b54d8a76efb5657 -title: Step 89 -challengeType: 0 -dashedName: step-89 ---- - -# --description-- - -Add the following code to `letters.forEach`: - -```js -input.type = "text"; -input.id = y + x; -input.onchange = update; -container.appendChild(input); -``` - -# --hints-- - -See description above for instructions. - -```js -assert( - /window\.onload[\s\S]*range\(1,99\)\.forEach\(\(?x\)?=>\{createLabel\(x\);?letters\.forEach\(\(?y\)?=>\{constinput=document\.createElement\(["']input["']\);?input\.type=["']text["'];?input\.id=y\+x;?input\.onchange=update;?container\.appendChild\(input\);?\}\);?\}\);?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-090.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-090.md deleted file mode 100644 index 6543d3124fb..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-090.md +++ /dev/null @@ -1,251 +0,0 @@ ---- -id: 5d7925371398513549bb6395 -title: Step 90 -challengeType: 0 -dashedName: step-90 ---- - -# --description-- - -In the global scope, define a function called `update` which takes `event` as argument. It should define a variable, `element`, setting it to `event.target`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constupdate=\(?event\)?=>\{?constelement=event\.target;?\}?/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-091.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-091.md deleted file mode 100644 index 378c01975ac..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-091.md +++ /dev/null @@ -1,257 +0,0 @@ ---- -id: 5d792537ea3eaf302bf2d359 -title: Step 91 -challengeType: 0 -dashedName: step-91 ---- - -# --description-- - -Now set `value` to `element.value.replace(/\s/g, "")`. This removes all whitespace from `element` so that we can ignore it. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constupdate=\(?event\)?=>\{constelement=event\.target;?constvalue=element\.value\.replace\(\/\\s\/g,["']{2}\);?\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-092.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-092.md deleted file mode 100644 index 93968d4e378..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-092.md +++ /dev/null @@ -1,261 +0,0 @@ ---- -id: 5d792537533b1c7843bfd029 -title: Step 92 -challengeType: 0 -dashedName: step-92 ---- - -# --description-- - -The `includes` method works on a string and checks if the argument is its substring. - -Add an empty if statement to `update` which executes if `element.id` is **not** a substring of `value`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constupdate=\(?event\)?=>\{constelement=event\.target;?constvalue=element\.value\.replace\(\/\\s\/g,["']{2}\);?if\(!\(?value\.includes\(element\.id\)\)?\)\{\}\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-093.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-093.md deleted file mode 100644 index dcc989ea328..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-093.md +++ /dev/null @@ -1,260 +0,0 @@ ---- -id: 5d792537dc0fe84345d4f19e -title: Step 93 -challengeType: 0 -dashedName: step-93 ---- - -# --description-- - -Add another condition to the if statement so that it only executes if the first character of `value` is `=`. Do this by adding `&& value[0] === "="` to the if statement. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constupdate=\(?event\)?=>\{constelement=event\.target;?constvalue=element\.value\.replace\(\/\\s\/g,["']{2}\);?if\(!\(?value\.includes\(element\.id\)\)?&&value\[0\]===["']=["']\)\{\}\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-094.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-094.md deleted file mode 100644 index ce97294c369..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-094.md +++ /dev/null @@ -1,260 +0,0 @@ ---- -id: 5d792537b6cadae0f4b0cda1 -title: Step 94 -challengeType: 0 -dashedName: step-94 ---- - -# --description-- - -The `slice` method takes two arguments. It extracts characters from the string from the index specified by the first argument up to (but not including) the second argument. The index starts at 0. - -Use the `slice` method to log the first two letters of `value` to the console. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('console.log(value.slice(0,2))')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-095.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-095.md deleted file mode 100644 index 1eaf868ad16..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-095.md +++ /dev/null @@ -1,262 +0,0 @@ ---- -id: 5d79253770083fb730c93a93 -title: Step 95 -challengeType: 0 -dashedName: step-95 ---- - -# --description-- - -You don't have to specify the second argument in `slice`. If you don't, then `slice` will extract from the first argument to the end of the string. - -Change the call to `slice` to log all characters except the first instead. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('console.log(value.slice(1))')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-096.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-096.md deleted file mode 100644 index cd6f2405a86..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-096.md +++ /dev/null @@ -1,266 +0,0 @@ ---- -id: 5d792537fef76b226b63b93b -title: Step 96 -challengeType: 0 -dashedName: step-96 ---- - -# --description-- - -Now change the if statement to set `element.value` to the result of passing `value.slice(1)` to `evalFormula`. There is no need to use `const` because we're modifying `element.value`, not declaring it. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constupdate=\(?event\)?=>\{constelement=event\.target;?constvalue=element\.value\.replace\(\/\\s\/g,["']{2}\);?if\(!\(?value\.includes\(element\.id\)\)?&&value\[0\]===["']=["']\)\{element\.value=evalFormula\(value\.slice\(1\)\);?\}\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-097.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-097.md deleted file mode 100644 index fb91f29be96..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-097.md +++ /dev/null @@ -1,273 +0,0 @@ ---- -id: 5d79253760fca25ccbbd8990 -title: Step 97 -challengeType: 0 -dashedName: step-97 ---- - -# --description-- - -The array destructuring syntax can be used to extract values from arrays: - -```js -const [x, y] = [1, 2]; // in variables -const fn = ([x, y]) => x + y // in functions -``` - -Use this syntax to define a function `random` in `spreadsheetFunctions` which takes the array `[x, y]` and returns `x`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /["']?random["']?:\(\[x,y\]\)=>x/.test(code.replace(/\s/g, '')) && - spreadsheetFunctions['random']([1, 2]) === 1 -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-098.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-098.md deleted file mode 100644 index c933b24aaac..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-098.md +++ /dev/null @@ -1,267 +0,0 @@ ---- -id: 5d7925374321824cba309875 -title: Step 98 -challengeType: 0 -dashedName: step-98 ---- - -# --description-- - -Change the `random` function so that it returns `Math.floor(Math.random() * y + x)`. It now returns a random number within a range. - -# --hints-- - -See description above for instructions. - -```js -assert( - /["']?random["']?:\(\[x,y\]\)=>Math\.floor\(Math\.random\(\)\*y\+x\)/.test( - code.replace(/\s/g, '') - ) && spreadsheetFunctions['random']([1, 1]) === 1 -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-099.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-099.md deleted file mode 100644 index 2a5ee766e3d..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-099.md +++ /dev/null @@ -1,276 +0,0 @@ ---- -id: 5d7925381e8565a5c50ba7f1 -title: Step 99 -challengeType: 0 -dashedName: step-99 ---- - -# --description-- - -In functional programming, we strive to use a type of function called "pure functions" as much as possible. The first property of pure functions is that they always return the same value for the same arguments. - -You can check if this is the case by comparing a call to a function with another call (with the same arguments): - -```js -console.log(f(2) === f(2)); // always true for pure functions -``` - -Use this technique to check if the `random` function in `spreadsheetFunctions` is pure by passing in the following array: `[1, 1000]`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /(spreadsheetFunctions\[["']random["']\]\(1,1000\))===\1/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-100.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-100.md deleted file mode 100644 index 2f419cf2876..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-100.md +++ /dev/null @@ -1,271 +0,0 @@ ---- -id: 5d7925383f1b77db7f1ff59e -title: Step 100 -challengeType: 0 -dashedName: step-100 ---- - -# --description-- - -This is (probably) false, so `random` is certainly impure. - -The second property of pure functions is that they perform no side effects, which are state and I/O modifications. If you call a function without assigning the result to a variable, and it does something, then it's an impure function. - -Call `window.onload()` in `update`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /update=\(?event\)?=>\{.*window\.onload\(\).*\}/.test(code.replace(/\s/g, '')) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-101.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-101.md deleted file mode 100644 index 176257a88b5..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-101.md +++ /dev/null @@ -1,268 +0,0 @@ ---- -id: 5d792538de9fa3f298bcd5f6 -title: Step 101 -challengeType: 0 -dashedName: step-101 ---- - -# --description-- - -Now try calling `highPrecedence` and pass it the string `"2*2"` without assigning it to a variable in `update`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /update=\(?event\)?=>\{.*highPrecedence\((['"])2\*2\1\).*\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-102.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-102.md deleted file mode 100644 index ad427105522..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-102.md +++ /dev/null @@ -1,270 +0,0 @@ ---- -id: 5d7925385b74f69642e1fea5 -title: Step 102 -challengeType: 0 -dashedName: step-102 ---- - -# --description-- - -Obviously, this was ignored, as all `highPrecedence` does is return a value and this value is ignored. - -Now compare `highPrecedence("2*2")` with `highPrecedence("2*2")`, and `console.log` the result. - -# --hints-- - -See description above for instructions. - -```js -assert( - /update=\(?event\)?=>\{.*console\.log\((highPrecedence\(['"]2\*2['"]\))===\1\).*\}/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-103.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-103.md deleted file mode 100644 index 231159b2b34..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-103.md +++ /dev/null @@ -1,265 +0,0 @@ ---- -id: 5d7925380ea76d55b2c97d7b -title: Step 103 -challengeType: 0 -dashedName: step-103 ---- - -# --description-- - -This is true, so `highPrecedence` might be a pure function. If you inspect it, you can see that it indeed performs no I/O and doesn't use functions like `Math.random()` - so it's pure. - -Remove the `console.log` statement. - -# --hints-- - -See description above for instructions. - -```js -assert(!code.includes('console.log')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-104.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-104.md deleted file mode 100644 index 36fd2f83b90..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-104.md +++ /dev/null @@ -1,267 +0,0 @@ ---- -id: 5d792538be4fe331f1a6c008 -title: Step 104 -challengeType: 0 -dashedName: step-104 ---- - -# --description-- - -Unfortunately, impure functions are necessary - if you don't use them, the application won't perform any I/O so won't do anything. - -But we have an impure function that could be pure - `evalFormula`. It calls `document.getElementById(c + n).value`, but this value can change, even if the arguments don't. - -Change these calls to `""` - the function is now pure but doesn't work. - -# --hints-- - -See description above for instructions. - -```js -const nos = code.replace(/\s/g, ''); -assert(nos.includes('elemValue=n=>c=>""') && nos.includes('match=>""')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-105.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-105.md deleted file mode 100644 index 4b9e711aae6..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-105.md +++ /dev/null @@ -1,264 +0,0 @@ ---- -id: 5d792538d169f33142175b95 -title: Step 105 -challengeType: 0 -dashedName: step-105 ---- - -# --description-- - -To make this function pure, instead of depending on application state implicitly, we can pass it down explicitly as an argument. - -Add an argument `cells` to `evalFormula`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('evalFormula=(x,cells)=>{')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-106.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-106.md deleted file mode 100644 index 39584a049ae..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-106.md +++ /dev/null @@ -1,272 +0,0 @@ ---- -id: 5d792538e48b5a2c6e5bbe12 -title: Step 106 -challengeType: 0 -dashedName: step-106 ---- - -# --description-- - -When calling `evalFormula` in `update`, pass in `Array.from(document.getElementById("container").children)` as the `cells` argument. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'evalFormula(value.slice(1),Array.from(document.getElementById("container").children))' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-107.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-107.md deleted file mode 100644 index 1ab52bf8124..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-107.md +++ /dev/null @@ -1,268 +0,0 @@ ---- -id: 5d7925387f3e9da5ec856dbe -title: Step 107 -challengeType: 0 -dashedName: step-107 ---- - -# --description-- - -Update the recursive call to `evalFormula` by passing in `cells` as the second argument. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('evalFormula(functionExpanded,cells)')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-108.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-108.md deleted file mode 100644 index 11e0b2d0bbc..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-108.md +++ /dev/null @@ -1,269 +0,0 @@ ---- -id: 5d79253824ae9b4a6e6f3108 -title: Step 108 -challengeType: 0 -dashedName: step-108 ---- - -# --description-- - -Add a function `idToText` to `evalFormula`, which takes the argument `id` and returns `cells`. - -# --hints-- - -See description above for instructions. - -```js -assert(/constidToText=\(?id\)?=>cells/.test(code.replace(/\s/g, ''))); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-109.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-109.md deleted file mode 100644 index d4c961be237..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-109.md +++ /dev/null @@ -1,275 +0,0 @@ ---- -id: 5d7925383f122a279f4c54ad -title: Step 109 -challengeType: 0 -dashedName: step-109 ---- - -# --description-- - -The `find` method returns the first element of an array that satisfies the function passed to it. - -Chain `find` onto `cells` and pass it `cell => cell === id`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constidToText=\(?id\)?=>cells\.find\(\(?cell\)?=>cell===id\)/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-110.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-110.md deleted file mode 100644 index abdc6794679..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-110.md +++ /dev/null @@ -1,272 +0,0 @@ ---- -id: 5d7925387b682e962f209269 -title: Step 110 -challengeType: 0 -dashedName: step-110 ---- - -# --description-- - -In `idToText`, use the `id` property of `cell` to make sure the argument is equal to the cell's id rather than the cell itself. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constidToText=\(?id\)?=>cells\.find\(\(?cell\)?=>cell\.id===id\)/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-111.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-111.md deleted file mode 100644 index 4baca0e6cc3..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-111.md +++ /dev/null @@ -1,272 +0,0 @@ ---- -id: 5d792538de774217b173288e -title: Step 111 -challengeType: 0 -dashedName: step-111 ---- - -# --description-- - -Use the `value` property on the result of `idToText` to return the text inside the cell, rather than the cell itself. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constidToText=\(?id\)?=>cells\.find\(\(?cell\)?=>cell\.id===id\)\.value/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-112.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-112.md deleted file mode 100644 index a2c5b9b1bef..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-112.md +++ /dev/null @@ -1,269 +0,0 @@ ---- -id: 5d79253891d93585323d1f3c -title: Step 112 -challengeType: 0 -dashedName: step-112 ---- - -# --description-- - -Change the empty string in `elemValue` to the result of calling `idToText` with `c + n`. - -# --hints-- - -See description above for instructions. - -```js -assert(code.replace(/\s/g, '').includes('elemValue=n=>c=>idToText(c+n)')); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-113.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-113.md deleted file mode 100644 index 637af181723..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-113.md +++ /dev/null @@ -1,271 +0,0 @@ ---- -id: 5d7925384e34e944ecb4612d -title: Step 113 -challengeType: 0 -dashedName: step-113 ---- - -# --description-- - -Change the empty string in `varExpanded` to the result of calling `idToText` with `match.toUpperCase()`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code.replace(/\s/g, '').includes('match=>idToText(match.toUpperCase())') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-114.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-114.md deleted file mode 100644 index d12140aa462..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-114.md +++ /dev/null @@ -1,273 +0,0 @@ ---- -id: 5d792538631844ad0bdfb4c3 -title: Step 114 -challengeType: 0 -dashedName: step-114 ---- - -# --description-- - -`evalFormula` is now pure, as it now has no external dependencies, and as before, performs no side effects. - -Now define a new function, `increment` inside `spreadsheetFunctions`, which takes `nums` as argument and uses `map` to increment each value of `nums` by 1. - -# --hints-- - -See description above for instructions. - -```js -assert(JSON.stringify(spreadsheetFunctions.increment([1, 5, 3])) === '[2,6,4]'); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-115.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-115.md deleted file mode 100644 index c966a9161ed..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-115.md +++ /dev/null @@ -1,279 +0,0 @@ ---- -id: 5d792538e2a8d20cc580d481 -title: Step 115 -challengeType: 0 -dashedName: step-115 ---- - -# --description-- - -The `slice` method can also work on arrays. - -Add a method `firsttwo` to `spreadsheetFunctions` which takes `arr` as argument and uses `slice` to return the first two elements of `arr`. - -# --hints-- - -See description above for instructions. - -```js -assert( - JSON.stringify(spreadsheetFunctions.firsttwo([2, 6, 1, 4, 3])) === '[2,6]' -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-116.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-116.md deleted file mode 100644 index 5483ee8a3e9..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-116.md +++ /dev/null @@ -1,285 +0,0 @@ ---- -id: 5d792538f5004390d6678554 -title: Step 116 -challengeType: 0 -dashedName: step-116 ---- - -# --description-- - -You can also pass in a negative argument to `slice` to specify that index from the end: - -```js -[2, 4, 6, 8, 10].slice(-3); // [6, 8, 10] -``` - -Use a negative index to add a function `lasttwo` which returns the last two elements of an array. - -# --hints-- - -See description above for instructions. - -```js -assert( - JSON.stringify(spreadsheetFunctions.lasttwo([2, 6, 1, 4, 3])) === '[4,3]' -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-117.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-117.md deleted file mode 100644 index 3e61d996f85..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-117.md +++ /dev/null @@ -1,288 +0,0 @@ ---- -id: 5d792539dd4fd4c96fd85f7e -title: Step 117 -challengeType: 0 -dashedName: step-117 ---- - -# --description-- - -The `%` operator returns the remainder: - -```js -4 % 3; // 1 -5 % 3; // 2 -6 % 3; // 0 -``` - -Add an `isEven` function (to the global scope) which returns whether the number passed to it is even. - -# --hints-- - -See description above for instructions. - -```js -assert(isEven(20) && !isEven(31)); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-118.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-118.md deleted file mode 100644 index 8c4b6a9e314..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-118.md +++ /dev/null @@ -1,292 +0,0 @@ ---- -id: 5d79253949802f8587c8bbd3 -title: Step 118 -challengeType: 0 -dashedName: step-118 ---- - -# --description-- - -The `filter` method keeps only the elements of an array that satisfy the function passed to it: - -```js -[1, 10, 8, 3, 4, 5].filter(x > 3); // [10, 8, 4, 5] -``` - -Use `filter` to add a function called `even` to `spreadsheetFunctions`, which returns all the even elements of an array, `nums`. - -# --hints-- - -See description above for instructions. - -```js -assert( - JSON.stringify(spreadsheetFunctions.even([2, 3, 5, 6, 9, 4])) === '[2,6,4]' && - code.includes('filter') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-119.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-119.md deleted file mode 100644 index c441a9459d8..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-119.md +++ /dev/null @@ -1,297 +0,0 @@ ---- -id: 5d7925395888767e9304c082 -title: Step 119 -challengeType: 0 -dashedName: step-119 ---- - -# --description-- - -The `reduce` method takes a function with an accumulator and the current value. The accumulator is initially set to the value at index 0. - -The `reduce` method then goes through each element of the array after that, passing in the element as the current value and the result of the last call as the accumulator. - -For example, here's how to multiply all the value in an array: - -```js -[2, 3, 4].reduce((a, x) => a * x); // 24 -``` - -Using `reduce`, add a function `sum` to `spreadsheetFunctions`, which sums all values in the array passed to it. - -# --hints-- - -See description above for instructions. - -```js -assert( - spreadsheetFunctions.sum([10, 5, 1, 3]) === 19 && code.includes('reduce') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-120.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-120.md deleted file mode 100644 index 787472aea1d..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-120.md +++ /dev/null @@ -1,291 +0,0 @@ ---- -id: 5d7925393b30099e37a34668 -title: Step 120 -challengeType: 0 -dashedName: step-120 ---- - -# --description-- - -The `includes` method checks if an element is in an array. - -Add a `has2` function to `spreadsheetFunctions` which checks if the inputted array has the number 2 in it. - -# --hints-- - -See description above for instructions. - -```js -assert( - spreadsheetFunctions.has2([2, 3, 5]) && !spreadsheetFunctions.has2([1, 3, 10]) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-121.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-121.md deleted file mode 100644 index f032db3ac16..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-121.md +++ /dev/null @@ -1,301 +0,0 @@ ---- -id: 5d7925398157757b23730fdd -title: Step 121 -challengeType: 0 -dashedName: step-121 ---- - -# --description-- - -The `reduce` method can take a second argument (in addition to the function), specifying the initial accumulator value. In this case, the current value starts from index 0 rather than index 1: - -```js -[1, [1, 2, 3], [3, 4, 5]].reduce((a, x) => a.concat(x), []); // [1, 1, 2, 3, 3, 4, 5] -// without the second argument, it first tries 1.concat([1, 2, 3]), but 1 is not an array -// now it first tries [].concat(1) which works -``` - -Add a function `nodups` to `spreadsheetFunctions`, with the value `arr => arr.reduce((a, x) => a.includes(x), [])`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /nodups['"]?:arr=>arr\.reduce\(\(a,x\)=>a\.includes\(x\),\[\]\)/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-122.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-122.md deleted file mode 100644 index 6b5714247b5..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-122.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -id: 5d792539de4b9ac14dd40409 -title: Step 122 -challengeType: 0 -dashedName: step-122 ---- - -# --description-- - -Use the ternary operator in `nodups` to return `a` if `a.includes(x)` and `a.concat(x)` otherwise. - -# --hints-- - -See description above for instructions. - -```js -assert( - JSON.stringify(spreadsheetFunctions.nodups([1, 3, 1, 5, 7, 7, 9, 7])) === - '[1,3,5,7,9]' -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-123.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-123.md deleted file mode 100644 index 8f15f9adfd4..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-123.md +++ /dev/null @@ -1,298 +0,0 @@ ---- -id: 5d792539534f1bf991bb987f -title: Step 123 -challengeType: 0 -dashedName: step-123 ---- - -# --description-- - -ES6 introduced a shorthand object literal syntax: - -```js -const a = 10; -const myObject = { a }; -console.log(myObject); // { a: 10 } -``` - -First, move `sum` outside of `spreadsheetFunctions`. `sum` should be a function expression similar to `isEven`. - -# --hints-- - -See description above for instructions. - -```js -assert(sum([1, 2, 3]) === 6); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-124.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-124.md deleted file mode 100644 index eef96f2d471..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-124.md +++ /dev/null @@ -1,293 +0,0 @@ ---- -id: 5d7925394089b762f93ffa52 -title: Step 124 -challengeType: 0 -dashedName: step-124 ---- - -# --description-- - -Now use the shorthand syntax to reference `sum` inside of `spreadsheetFunctions`. - -This both adds it to the functions you can use in the spreadsheet, and allows you to use it throughout your program. - -# --hints-- - -See description above for instructions. - -```js -assert(/[{,]sum[,}]/.test(code.replace(/\s/g, ''))); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-125.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-125.md deleted file mode 100644 index cb3b30d8c4f..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-125.md +++ /dev/null @@ -1,298 +0,0 @@ ---- -id: 5d792539ec758d45a6900173 -title: Step 125 -challengeType: 0 -dashedName: step-125 ---- - -# --description-- - -The `length` property returns the length of an array. Use this property with the `sum` function to define an `average` function. - -As with `sum`, add this function to both the global scope and to `spreadsheetFunctions`. - -# --hints-- - -See description above for instructions. - -```js -assert( - average([1, 5, 12]) === 6 && spreadsheetFunctions.average([1, 20, 3, 8]) === 8 -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-126.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-126.md deleted file mode 100644 index 621e4cc4fbc..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-126.md +++ /dev/null @@ -1,308 +0,0 @@ ---- -id: 5d7925398d525f61a9ff3a79 -title: Step 126 -challengeType: 0 -dashedName: step-126 ---- - -# --description-- - -The spread operator allow you to pass multiple arguments instead of an array: - -```js -const arr = [1, 2, 3]; -const sum3 = (a, b, c) => a + b + c; -sum3(...arr); // 6 -``` - -Use the spread operator to add `range` to `spreadsheetFunctions`. - -# --hints-- - -See description above for instructions. - -```js -assert( - JSON.stringify(spreadsheetFunctions.range([1, 5])) === '[1,2,3,4,5]' && - code.includes('...') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-127.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-127.md deleted file mode 100644 index 8d27ee2bf76..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-127.md +++ /dev/null @@ -1,300 +0,0 @@ ---- -id: 5d792539a222f385c5c17d2b -title: Step 127 -challengeType: 0 -dashedName: step-127 ---- - -# --description-- - -Now define a `median` function which takes an argument `nums` (in the global scope). - -# --hints-- - -See description above for instructions. - -```js -assert(/constmedian=\(?nums\)?=>/.test(code.replace(/\s/g, ''))); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-128.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-128.md deleted file mode 100644 index 08ffbd94e4a..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-128.md +++ /dev/null @@ -1,312 +0,0 @@ ---- -id: 5d7925398a7184b41b12a0e0 -title: Step 128 -challengeType: 0 -dashedName: step-128 ---- - -# --description-- - -The `sort` method sorts an array alphabetically: - -```js -["B", "C", "A"].sort(); // ["A", "B", "C"] -``` - -Assign the sorted `nums` to `sorted` in `median`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code.replace(/\s/g, '').includes('constmedian=nums=>{constsorted=nums.sort()') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-129.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-129.md deleted file mode 100644 index 49b025f4b1e..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-129.md +++ /dev/null @@ -1,318 +0,0 @@ ---- -id: 5d7925399afb905c34730a75 -title: Step 129 -challengeType: 0 -dashedName: step-129 ---- - -# --description-- - -But our function takes an array of numbers, not strings. Luckily, you can pass a function `fn` as argument to sort: - -```js -[2, 9, 10, 15].sort((a, b) => b - a); // [10, 9, 5, 2] -``` - -If `b - a` is less than 0, then `a` will be placed before `b`. As a result, this sorts the array in descending order. - -Use `sort` to sort `nums` in ascending order. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constmedian=nums=>\{constsorted=nums\.sort\(\((.+),(.+)\)=>\1-\2\)/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-130.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-130.md deleted file mode 100644 index cad2f5aa466..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-130.md +++ /dev/null @@ -1,312 +0,0 @@ ---- -id: 5d792539728d1aa7788e2c9b -title: Step 130 -challengeType: 0 -dashedName: step-130 ---- - -# --description-- - -Unfortunately, `sort` not only returns a new array, but also modifies the existing one. So our function also modifies the array passed to it - it is impure. - -You can fix this by adding `.slice()` between `nums` and `sort` - this creates a new array, that is equivalent to `nums`, but is immediately discarded, so it doesn't matter if it changes. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constmedian=nums=>\{constsorted=nums\.slice\(\)\.sort\(\((.+),(.+)\)=>\1-\2\)/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-131.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-131.md deleted file mode 100644 index df39b579f78..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-131.md +++ /dev/null @@ -1,312 +0,0 @@ ---- -id: 5d79253939434a2724c0ec41 -title: Step 131 -challengeType: 0 -dashedName: step-131 ---- - -# --description-- - -Now define two variable: `length` which is `sorted.length` and `middle` which is `length / 2 - 1`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constmedian=nums=>\{constsorted=nums\.slice\(\)\.sort\(\((.+),(.+)\)=>\1-\2\);?constlength=sorted\.length;?constmiddle=length\/2-1/.test( - code.replace(/\s/g, '') - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-132.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-132.md deleted file mode 100644 index 1e4f1aca372..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-132.md +++ /dev/null @@ -1,311 +0,0 @@ ---- -id: 5d792539b9e1d3c54d8fe94a -title: Step 132 -challengeType: 0 -dashedName: step-132 ---- - -# --description-- - -Add a return statement to `median` so that it returns `isEven(length)`. - -# --hints-- - -See description above for instructions. - -```js -assert(median([1, 2, 3, 4]) && !median([1, 2, 3])); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-133.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-133.md deleted file mode 100644 index 4cf66a6dd6a..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-133.md +++ /dev/null @@ -1,316 +0,0 @@ ---- -id: 5d792539b2e0bd8f9e8213e4 -title: Step 133 -challengeType: 0 -dashedName: step-133 ---- - -# --description-- - -Use the ternary operator to return `average([sorted[middle], sorted[middle + 1]])` if `length` is even, and `sorted[middle + 0.5]` otherwise. - -Note that the `middle` variable is close to the middle but is not actually the middle. - -# --hints-- - -See description above for instructions. - -```js -assert(median([1, 20, 3]) === 3 && median([27, 7, 20, 10]) === 15); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-134.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-134.md deleted file mode 100644 index 2428ff3a79d..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-134.md +++ /dev/null @@ -1,320 +0,0 @@ ---- -id: 5d792539239148965a1a59a5 -title: Step 134 -challengeType: 0 -dashedName: step-134 ---- - -# --description-- - -Now add `median` to `spreadsheetFunctions`, just like you added `sum` and `average`. - -# --hints-- - -See description above for instructions. - -```js -assert( - spreadsheetFunctions.median([1, 20, 3]) === 3 && - spreadsheetFunctions.median([27, 7, 20, 10]) === 15 -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-135.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-135.md deleted file mode 100644 index ff91ae909fd..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-135.md +++ /dev/null @@ -1,325 +0,0 @@ ---- -id: 5d792539e1446045d0df6d28 -title: Step 135 -challengeType: 0 -dashedName: step-135 ---- - -# --description-- - -The `some` method checks if any element of the array satisfies the provided testing function. - -Add `someeven` to `spreadsheetFunctions`, which checks if any of the items passed in are even. - -# --hints-- - -See description above for instructions. - -```js -assert( - spreadsheetFunctions.someeven([1, 5, 4, 3]) && - !spreadsheetFunctions.someeven([3, 5, 9]) && - code.includes('.some') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-136.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-136.md deleted file mode 100644 index ddede0016d6..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-136.md +++ /dev/null @@ -1,327 +0,0 @@ ---- -id: 5d79253a2febbb77098730b9 -title: Step 136 -challengeType: 0 -dashedName: step-136 ---- - -# --description-- - -The `every` method checks if all elements of an array satisfy the provided testing function. - -Use it to add an `everyeven` function to `spreadsheetFunctions` which checks if all values passed in are even`spreadsheetFunctions` which checks if all values passed in are even. - -# --hints-- - -See description above for instructions. - -```js -assert( - spreadsheetFunctions.everyeven([2, 6, 4, 0, 20]) && - !spreadsheetFunctions.everyeven([10, 0, 9, 2]) && - code.includes('.every') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-137.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-137.md deleted file mode 100644 index c475cf8ba22..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-137.md +++ /dev/null @@ -1,328 +0,0 @@ ---- -id: 5d79253a98bd9fdf7ce68d0a -title: Step 137 -challengeType: 0 -dashedName: step-137 ---- - -# --description-- - -We've used recursion in `range`, but recursion can have performance issues in JavaScript. If performance is an issue, you should try to use a higher order function like `reduce`, and if you can't do that, you'll probably have to use a for/while loop. - -While we don't expect the user to enter particularly large numbers so that performance is an issue, we're going to refactor `range` as an exercise. - -Replace the body of `range` with `start`. - -# --hints-- - -See description above for instructions. - -```js -assert( - /constrange=\(start,end\)=>start(;|const)/.test(code.replace(/\s/g, '')) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-138.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-138.md deleted file mode 100644 index 52e294c3655..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-138.md +++ /dev/null @@ -1,324 +0,0 @@ ---- -id: 5d79253a1e9abf29de64c177 -title: Step 138 -challengeType: 0 -dashedName: step-138 ---- - -# --description-- - -The `Array` function takes an argument `x` and creates an array of size `x` filled with `undefined`. - -Make `range` return an array of `undefined` with size `end - start + 1`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code.replace(/\s/g, '').includes('constrange=(start,end)=>Array(end-start+1)') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-139.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-139.md deleted file mode 100644 index ce1e1c87c73..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-139.md +++ /dev/null @@ -1,327 +0,0 @@ ---- -id: 5d79253a8b29d78984369e4b -title: Step 139 -challengeType: 0 -dashedName: step-139 ---- - -# --description-- - -The `fill` method takes an argument and replaces all elements of the array with that argument. - -Use it on the array in `range` to replace everything with `start`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes('constrange=(start,end)=>Array(end-start+1).fill(start)') -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-140.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-140.md deleted file mode 100644 index 9630c3210b7..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-140.md +++ /dev/null @@ -1,330 +0,0 @@ ---- -id: 5d79253ad297a31cbe073718 -title: Step 140 -challengeType: 0 -dashedName: step-140 ---- - -# --description-- - -The function in the `map` method can actually take a second argument: the index of the element. - -This is why you need an arrow function in `charRange` - if you don't use one, then the index will be passed to `String.fromCharCode` as the second argument, leading to unexpected results. However, it is safe for functions like `parseFloat` which take only one argument (but not for `parseInt`). - -Chain `.map((x, i) => x + i)` to `.fill(start)` to add its index to every element in the array in `range`. - -# --hints-- - -See description above for instructions. - -```js -assert( - code - .replace(/\s/g, '') - .includes( - 'constrange=(start,end)=>Array(end-start+1).fill(start).map((x,i)=>x+i)' - ) -); -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -``` diff --git a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-141.md b/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-141.md deleted file mode 100644 index 7531f12a5a3..00000000000 --- a/curriculum/challenges/english/15-javascript-algorithms-and-data-structures-22/learn-functional-programming-by-building-a-spreadsheet/step-141.md +++ /dev/null @@ -1,316 +0,0 @@ ---- -id: 5dc10b8b93704f41d279eb5b -title: Step 141 -challengeType: 0 -dashedName: step-141 ---- - -# --description-- - -Congratulations, you've finished your functional programming spreadsheet! Now test it out by crunching some numbers. - -# --hints-- - -See description above for instructions. - -```js - -``` - -# --seed-- - -## --before-user-code-- - -```html - - - - - Spreadsheet - - - -
-
-
-``` - -## --after-user-code-- - -```html - - -``` - -## --seed-contents-- - -```html - -``` - -# --solutions-- - -```html - -```