SomeDer 2fbafda167 feat: functional programming spreadsheet (#36873)
* Add meta.json for spreadsheet

* Add spreadsheet files

* Close code tags for tests in 2 files

* Add solution section

* Add index file

* Add javascript-spreadsheet to stringifier

* Move index to step

* Rename steps in meta.json

* Rename step numbers in files

* Add index file to proper location

* Remove inappropriate files from spreadsheet dir

* Fix typo in first step

* Fix test sections

* Rename files to correct step

* Fix broken tests

* Add newline between sections

* Change challengeType from 1 to 0

* Add missng ) in step-079.md

* test -> tests in step-079

* Simplify test in step-103

* Fix step-137 test

* Remove last step

* Added solutions and adjusted some tests

* Fix some challenges

* Remove wrong spaces

* Fix more tests

* Add missing semicolon

* Fix more tests

* Fix type: lastttwo

* Fix all remaining tests
2020-09-16 11:53:59 +05:30

3.8 KiB

id, title, challengeType, isBeta
id title challengeType isBeta
5d7925341747ad42b12f8e68 Step 042 0 true

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:

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

Instructions

Tests

tests:
  - text: See description above for instructions.
    testString: assert(JSON.stringify(range(1,2)) === "[1,2]" && code.includes("concat") && !(code.includes("push")));

Challenge Seed

<script>

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, (_, arg1, fn, arg2) =>
    infixToFunction[fn](parseFloat(arg1), parseFloat(arg2))
  );

const highPrecedence = str => {
  const regex = /([0-9.]+)([*\/])([0-9.]+)/;
  const str2 = infixEval(str, regex);
  return str === str2 ? str : highPrecedence(str2);
};

const spreadsheetFunctions = {
  "": x => x
};

const applyFn = str => {
  const noHigh = highPrecedence(str);
  const infix = /([0-9.]+)([+-])([0-9.]+)/;
  const str2 = infixEval(noHigh, infix);
  const regex = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i;
  const toNumberList = args => args.split(",").map(parseFloat);
  const applyFunction = (fn, args) =>
    spreadsheetFunctions[fn.toLowerCase()](toNumberList(args));
  return str2.replace(
    regex,
    (match, fn, args) =>
      spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? applyFunction(fn, args) : match
  );
};

const range = (start, end) => {
  const arr = [start];
  arr.push(end);
  return arr;
}


</script>

Before Test

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Spreadsheet</title>
  <style>
    #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;
    }
  </style>
</head>
<body>
<div id="container">
  <div></div>
</div>

After Test

</body>
</html>

Solution

<script>
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, (_, arg1, fn, arg2) =>
    infixToFunction[fn](parseFloat(arg1), parseFloat(arg2))
  );

const highPrecedence = str => {
  const regex = /([0-9.]+)([*\/])([0-9.]+)/;
  const str2 = infixEval(str, regex);
  return str === str2 ? str : highPrecedence(str2);
};

const spreadsheetFunctions = {
  "": x => x
};

const applyFn = str => {
  const noHigh = highPrecedence(str);
  const infix = /([0-9.]+)([+-])([0-9.]+)/;
  const str2 = infixEval(noHigh, infix);
  const regex = /([a-z]*)\(([0-9., ]*)\)(?!.*\()/i;
  const toNumberList = args => args.split(",").map(parseFloat);
  const applyFunction = (fn, args) =>
    spreadsheetFunctions[fn.toLowerCase()](toNumberList(args));
  return str2.replace(
    regex,
    (match, fn, args) =>
      spreadsheetFunctions.hasOwnProperty(fn.toLowerCase()) ? applyFunction(fn, args) : match
  );
};

const range = (start, end) => {
  const arr = [start];
  return arr.concat(end);
}
</script>