Problem Solving-3

Optimal Assignments Have the function OptimalAssignments(strArr) read strArr which will represent an NxN matrix and it w

Views 179 Downloads 3 File size 130KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Optimal Assignments Have the function OptimalAssignments(strArr) read strArr which will represent an NxN matrix and it will be in the following format: ["(n,n,n...)","(...)",...] where the n's represent integers. This matrix represents a machine at row i performing task at column j. The cost for this is matrix[i][j]. Your program should determine what machine should perform what task so as to minimize the whole cost and it should return the pairings of machines to tasks in the following format: (i-j)(...)... Only one machine can perform one task. For example: if strArr is ["(5,4,2)","(12,4,3)","(3,4,13)"] then your program should return (1-3)(2-2)(3-1) because assigning the machines to these tasks gives the least cost. The matrix will range from 2x2 to 6x6, there will be no negative costs in the matrix, and there will always be a unique answer. Hard challenges are worth 15 points and you are not timed for them.

Examples Input: ["(1,2,1)","(4,1,5)","(5,2,1)"] Output: (1-1)(2-2)(3-3) Input: ["(13,4,7,6)","(1,11,5,4)","(6,7,2,8)","(1,3,5,9)"] Output: (1-2)(2-4)(3-3)(4-1) function OptimalAssignments(strArr) { var len = strArr.length; //1. get list of permutations var cmdLines = orderStrings(len); //2. convert the array of strings to an array of number arrays. var workArray = convertArray(strArr); //3.

attach to each item in the cmdLine permutation a score var cmdLinesScores = cmdLines.map(function(val){ return [val, scoreMaker(val)]; })

//4. sort the scores from greatest to least, and return the most efficient //in string form cmdLinesScores.sort(function(a, b) {return(b[1] - a[1])}); var rawAnswer = cmdLinesScores.pop()[0]; //5. convert the answer into the required format, and return return (ansConvert(rawAnswer));

//---------------------helper functions-------------------function orderStrings(num){ var numArr = []; for (var i = 0; i < num; i++){ numArr[i] = i + 1; } var result = allPerms(numArr).map(function(val) { return val.join('');

}); return result; } function allPerms(inputArray) { var data = inputArray; var resultArray = []; var len = data.length; if (len === 0) { return [[]]; } else { var first = data.shift(); var words = allPerms(data); words.forEach(function(word) { for (var i = 0; i < len; ++i) { var tmp = word.slice(); tmp.splice(i, 0, first) resultArray.push(tmp); } }); } return resultArray; } function convertArray(arr) { pattern = /(d+)/g; newArr = []; var newArr = arr.map(function(val, ind){ pattern = /(d+)/g; holdArr = []; do { var test = pattern.exec(val); if (test) { holdArr.push(parseInt(test[1])); } } while (pattern.lastIndex > 0); return holdArr; }); return newArr; } function scoreMaker(orderString) { var orderArr = orderString.split(''); var holdArr = workArray.map(function(val, ind) { return val[orderArr[ind] - 1]; }); var score = holdArr.reduce(function(first, last){ return first + last; }); return score; } function ansConvert(str) {

var res = ''; for (var i = 0; i < len; i++) { res = res + '(' + (i+1) + '-' + rawAnswer[i] + ')'; } return res; } } // keep this function call here // to see how to enter arguments in JavaScript scroll down OptimalAssignments(readline()); Transitivity Relations Have the function TransitivityRelations(strArr) read the strArr parameter being passed which will make up an NxN matrix where the rows are separated by each pair of parentheses (the matrix will range from 2x2 to 5x5). The matrix represents connections between nodes in a graph where each node corresponds to the Nth element in the matrix (with 0 being the first node). If a connection exists from one node to another, it will be represented by a  1, if not it will be represented by a 0. For example: suppose strArr were a 3x3 matrix with input ["(1,1,1)","(1,0,0)","(0,1,0)"], this means that there is a connection from node 0->0, 0->1, and 0->2. For node 1 the connections are 1->0, and for node 2 the connections are 2->1. This can be interpreted as a connection existing from node X to node Y if there is a  1 in the Xth row and Yth column. Note: a connection from X->Y does not imply a connection from Y->X. What your program should determine is whether or not the matrix, which represents connections among the nodes, is transitive. A  transitive relation  means that if the connections 0->1 and 1->2 exist for example, then there must exist the connection 0->2. More generally, if there is a relation xRy and yRz, then xRz should exist within the matrix. If a matrix is completely transitive, return the string  transitive. If it isn't, your program should return the connections needed, in the following format, in order for the matrix to be transitive: (N1,N2)-(N3,N4)-(...). So for the example above, your program should return (1,2)-(2,0). You can ignore the reflexive property of nodes in your answers. Return the connections needed in lexicographical order  [e.g. (0,1)-(0,4)-(1,4)-(2,3)-(4,1)]. Hard challenges are worth 15 points and you are not timed for them.

Examples Input: ["(1,1,1)","(0,1,1)","(0,1,1)"] Output: transitive Input: ["(0,1,0,0)","(0,0,1,0)","(0,0,1,1)","(0,0,0,1)"] Output: (0,2)-(0,3)-(1,3) function TransitivityRelations(strArr) { var len = strArr.length; var paths = groupings(len, len); var newArr = prepArr(strArr); var mark1Arr = endMark(newArr, paths); var mark2Arr = markUp(newArr, mark1Arr); mark2Arr = mark2Arr.map(function(val) { return val + val[0]; }); var tests = mark2Arr.filter(function(val) { return /-d-/.test(val); }); var searchResArray = []; tests.forEach(function(val) { var test3 = val.match(/d-d-d/g) || []; console.log('3', test3); var test4 = val.match(/d-d-d-d/g) || [];

console.log('4', test4); var test5 = val.match(/d-d-d-d-d/g) || []; console.log('5', test5); searchResArray.push(...test3, ...test4, ...test5); }); var res = []; searchResArray.forEach(function(val) { var first = val.slice(0,1); var second = val.slice(-1); if (!parseInt(newArr[first][second], 10)) { res.push('(' + first + ',' + second + ')'); } }); if (!res.length) return 'transitive'; res = uniq(res).sort(); return res.join('-'); } //---------------------Helper Functions--------------------------function uniq(arr) { var obj = {}; arr.forEach(function(val) { obj[val] = true; }); return Object.keys(obj); } //take the original ["(1,1,1,1)"] form and conver to [['1','1','1','1'], etc ] form function prepArr(arr) { //convert the string array to an array of four arrays newInput = arr.map(function(val) { nums = val.match(/d/g); return nums; }); return newInput; } //puts an - at the end if the first element is connected to the last //puts an * at the end if the first element is not connected to the last function endMark(newArr, paths) { var arr = paths.map(function(val) { var begin = val[0]; var end = val[val.length - 1]; if (parseInt(newArr[begin][end], 10)) { return val.concat('-'); } else { return val.concat('*'); } });

return arr; } //takes the 1/0 array and uses it to place hyphens between nodes with connections function markUp(arr, pathArr) { var len = arr.length; var copyArr = []; pathArr.forEach(function(val, ind) { var str = pathArr[ind][0]; for (var i = 0; i < len - 1; i++) { var begin = pathArr[ind][i]; console.log('begin', begin); var end = pathArr[ind][i + 1]; console.log('end', end); if (parseInt(arr[begin][end])) { str += ('-' + end); } else { str += ('*' + end) } } copyArr.push(str); }); return copyArr; } /*this function finds all the distinct groupings of strLen objects out an array n objects long. It works a bit messily, taking the array of all permutations of all array elements, chopping off the last unwanted length - n objects, then taking every (length - n)! of that list. */ function groupings(arrLen) { var theArray = []; for(var i = 0; i < arrLen; i++) { theArray.push(i.toString()); } var skipper = 1 //factorial(arrLen - arrLen); var newArr = permutations(theArray); newArr = newArr.map(function(val){ return val.slice(0, arrLen); }); holdArr = []; newArr.forEach(function(val, ind) { if(ind % skipper === 0) { holdArr.push(val); } }); return newArr; // return holdArr; }

//the permutations function delivers all the possible arrangements of n distinct letters. function permutations(arr) { //create an array of form ['str', [arr]] var newArr = ['', arr]; return (reduction(rollover(newArr))); } /*the rollover function takes an array in the form ['',[a, b, c, . . .]] and returns a nested array containing all the permutations containing n items, using each item only once. However, to use, one must use the reduction()function to get back to a single level array. */ function rollover (arr) { if (arr[1].length === 1) { arr[0] += arr[1]; return arr[0]; } else { var itemArr = arr[1]; var holdArr = []; var len = itemArr.length; for (var i = 0; i < len; i++) { forArr = itemArr.map(function(val) { return val; }); forArr.splice(i, 1); var cons = arr[0] + arr[1][i]; holdArr.push(rollover([cons,forArr])); }; return holdArr; } } /* The reduction function takes an array nested several levels and flattens it by concatenation. */ function reduction(arr) { if (Array.isArray(arr[0])) { var holdArr = arr.reduce(function(first, last) { return first.concat(last); }); return reduction(holdArr); } else { return arr; } } function factorial(num) { var intNum = parseInt(num, 10); if (num < 0) return null; if(num === 0) { return 1;

} else if(num === 1) { return 1; } else { return num * factorial(num - 1); } } // keep this function call here TransitivityRelations(readline()); Shortest Path Have the function ShortestPath(strArr) take strArr which will be an array of strings which models a non-looping Graph. The structure of the array will be as follows: The first element in the array will be the number of nodes N (points) in the array as a string. The next N elements will be the nodes which can be anything (A, B, C .. Brick Street, Main Street .. etc.). Then after the Nth element, the rest of the elements in the array will be the connections between all of the nodes. They will look like this: (A-B, B-C .. Brick Street-Main Street .. etc.). Although, there may exist no connections at all. An example of strArr may be: ["4","A","B","C","D","A-B","B-D","B-C","C-D"]. Your program should return the shortest path from the  first Node to the last Node in the array separated by dashes. So in the example above the output should be A-B-D. Here is another example with strArr being ["7","A","B","C","D","E","F","G","A-B","A-E","B-C","CD","D-F","E-D","F-G"]. The output for this array should be A-E-D-F-G. There will only ever be one shortest path for the array. If no path between the first and last node exists, return -1. The array will at minimum have two nodes. Also, the connection A-B for example, means that A can get to B and B can get to A. Hard challenges are worth 15 points and you are not timed for them.

Examples Input: ["5","A","B","C","D","F","A-B","A-C","B-C","C-D","D-F"] Output: A-C-D-F Polynomial Expansion Have the function PolynomialExpansion(str) take str which will be a string representing a polynomial containing only (+/-) integers, a letter, parenthesis, and the symbol "^", and return it in expanded form. For example: if str is "(2x^2+4)(6x^3+3)", then the output should be "12x^5+24x^3+6x^2+12". Both the input and output should contain no spaces. The input will only contain one letter, such as "x", "y", "b", etc. There will only be four parenthesis in the input and your output should contain no parenthesis. The output should be returned with the highest exponential element first down to the lowest. More generally, the form of str will be: ([+/-]{num}[{letter}[{^}[+/-]{num}]]...[[+/-]{num}]...)(copy) where "[]" represents optional features, "{}" represents mandatory features, "num" represents integers and "letter" represents letters such as "x". Hard challenges are worth 15 points and you are not timed for them.

Examples Input: "(1x)(2x^-2+1)" Output: x+2x^-1 Input: "(-1x^3)(3x^3+2)" Output: -3x^6-2x^3 function PolynomialExpansion(str) {

//first, put the string into an array of polynomial values to be multiplied, clean //up, and standardize so values are consistent format (e.g., 5x^1, 4x^0); var letter = str.match(/[A-Za-z]/)[0]; var modifiedStr = str.replace(/[a-zA-Z]/g, 'x') .replace(/-/g, '+-') .replace(/^+-/g, '^-'); var termArray = modifiedStr.split(')'); termArray.pop(); termArray = termArray.map(function(val) { newVal = val.replace(/(/g, '') .replace(/d+x(?!^)/g, '$&^1') .replace(/+-?d+(?!x)/g, '$&x^0') .replace(/^d+$/, '$&x^0') .split('+').filter(function(val) { return val; }); i newVal = newVal.map(function(val2) { var parts = val2.match(/^(-?d+)x^(-?d+)$/); newObj = { coefficient: parseInt(parts[1], 10), power: parseInt(parts[2], 10) } return newObj; }) return newVal; }); //second, iterate over the array using the reduce funtion to send them down to the //polyMultiply method var solution = termArray.reduce(function(val1, val2) { return polyMultiply(val1, val2); }) //third, sort by power

solution.sort(function(a, b) {return b.power - a.power});

//fourth, reduce common powers newSolArray = []; for (var i = 0; i < solution.length - 1; i++) { if (solution[i].power !== solution[i + 1].power) { newSolArray.push(solution[i]); } else { solution[i + 1].coefficient = solution[i].coefficient + solution[i+1].coefficient; } } newSolArray.push(solution.pop()); //fifth, build the new string

var newString = ''; newSolArray.forEach(function(val) { if (val.power !== 1 && val.power !== 0) { newString += '+' + val.coefficient.toString() + letter + '^' + val.power.toString(); } else if (val.power === 1) { newString += '+' + val.coefficient.toString() + letter; } else { newString += '+' + val.coefficient.toString(); } });

var formattedString = newString.replace(/+-/g, '-') .replace (/^+/,'') .replace (/([-+])1([a-zA-Z])/, '$1$2') .replace (/^1([a-zA-Z])/, '$1') return(formattedString); }

//-------------------------------Helper Functions-------------------------------function polyMultiply(arr1, arr2) { resultsArray = []; arr1.forEach(function(val) { arr2.forEach(function(val2) { resultsArray.push(termMultiply(val, val2)) }) }) return resultsArray; }

function termMultiply(obj1, obj2) { returnObj = {}; returnObj.coefficient = obj1.coefficient * obj2.coefficient; returnObj.power = obj1.power + obj2.power; return returnObj; }

// keep this function call here PolynomialExpansion(readline());

 Calculator Have the function Calculator(str) take the str parameter being passed and evaluate the mathematical expression within in. For example, if  str were "2+(3-1)*3" the output should be 8. Another example: if str were "(2-0)(6/2)" the output should be 6. There can be parenthesis within the string so you must evaluate it properly according to the rules of arithmetic. The string will contain the operators: +, -, /, *, (, and ). If you have a string like this: #/#*# or #+#(#)/#, then evaluate from left to right. So divide then multiply, and for the second one multiply, divide, then add. The evaluations will be such that there will not be any decimal operations, so you do not need to account for rounding and whatnot. Hard challenges are worth 15 points and you are not timed for them.

Examples Input: "6*(4/2)+3*1" Output: 15 Input: "6/3-1" Output: 1

function Calculator(str) { const newStr = str.replace(/([\d)])\(/g, '$1*(') .replace(/\)([(\d])/g, ')*$1') .replace(/\*\*/g, '*'); return global.eval(newStr); } // keep this function call here Calculator(readline()); Pattern Chaser Have the function PatternChaser(str) take str which will be a string and return the longest pattern within the string. A pattern for this challenge will be defined as: if at least 2 or more adjacent characters within the string repeat at least twice. So for example "aabecaa" contains the pattern aa, on the other hand "abbbaac" doesn't contain any pattern. Your program should return yes/no pattern/null. So if str were "aabejiabkfabed" the output should be yes abe. If str were "123224" the output should return no null. The string may either contain all characters (a through z only), integers, or both. But the parameter will always be a string type. The maximum length for the string being passed in will be 20 characters. If a string for example is "aa2bbbaacbbb" the pattern is "bbb" and not "aa". You must always return the longest pattern possible. Hard challenges are worth 15 points and you are not timed for them.

Examples Input: "da2kr32a2" Output: yes a2 Input: "sskfssbbb9bbb" Output: yes bbb function PatternChaser(str) { var len = str.length; var halfLen = Math.floor(str.length / 2);

for (var i = halfLen; i > 1; i--) { for(var j = 0; j 1) { return 'yes ' + txt; } } } return 'no ' + null; } // keep this function call here // to see how to enter arguments in JavaScript scroll down PatternChaser(readline()); Weighted Path Have the function WeightedPath(strArr) take strArr which will be an array of strings which models a non-looping weighted  Graph. The structure of the array will be as follows: The first element in the array will be the number of nodes N (points) in the array as a string. The next N elements will be the nodes which can be anything (A, B, C .. Brick Street, Main Street .. etc.). Then after the Nth element, the rest of the elements in the array will be the connections between all of the nodes along with their weights (integers) separated by the pipe symbol (|). They will look like this: (A|B|3, B|C|12 .. Brick Street|Main Street|14 .. etc.). Although, there may exist no connections at all. An example of strArr may be: ["4","A","B","C","D","A|B|1","B|D|9","B|C|3","C|D|4"]. Your program should return the shortest path when the weights are added up from node to node from the first Node to the last Node in the array separated by dashes. So in the example above the output should be  A-B-C-D. Here is another example with strArr being ["7","A","B","C","D","E","F","G","A|B|1","A|E|9","B|C|2","C|D|1","D|F|2","E|D|6","F|G|2"]. The output for this array should be  A-B-C-D-F-G. There will only ever be one shortest path for the array. If no path between the first and last node exists, return  -1. The array will at minimum have two nodes. Also, the connection A-B for example, means that A can get to B and B can get to A. A path may not go through any Node more than once. Hard challenges are worth 15 points and you are not timed for them.

Examples Input: ["4","A","B","C","D", "A|B|2", "C|B|11", "C|D|3", "B|D|2"] Output: A-B-D Input: ["4","x","y","z","w","x|y|2","y|z|14", "z|y|31"] Output: -1 function WeightedPath(strArr) { //get the number of nodes var nodeNum = parseInt(strArr.shift()); //create Apple copy of the array argument, rather than a pointer to it. var newArr = strArr.map(function(val){return val}); //replace the proper names with letters, for simplicity var modArr = convertArray(newArr); //=>[ 'A', 'B', 'C', 'D', 'A|B|1', 'B|D|9', 'B|C|3', 'C|D|4' ]

//get an array, containing an object of nodes, and for each an array of connections var connections = createObject(modArr); //=>{ A: [], B: [], C: [], D: [] } [ 'A|B|1', 'B|D|9', 'B|C|3', 'C|D|4' ] //then convert to an object of key-values (node: [connections]) var connectionsObject = makeObject(connections); //=>{ A: [ [ 'B', 1 ] ], B: [ [ 'A', 1 ], [ 'D', 9 ], [ 'C', 3 ] ], C: [ [ 'B', 3 ], [ 'D', 4 ] ], D: [ [ 'B', 9 ], [ 'C', 4 ] ] } var fullPaths = paths(connectionsObject); //=>[ [ 'ABD', 10 ], [ 'ABCD', 8 ] ]

if (fullPaths.length) { var winner = fullPaths.sort(function(b,a) {return(a[1] - b[1])}).pop(); return finalForm(winner[0]); } else { return -1; } //--------------------------------helper functions----------------------------

/*convertArray takes i) the nodeNum and an array of the nodes and paths, and converts each node name to a letter character, just to make it easier to work with. */ function convertArray (arr) { arr = arr.map(function(val) { return val.toLowerCase() }); for (var i = 0; i < nodeNum; i++) { var patt = new RegExp(arr[i]); arr = arr.map(function(val) { return val.replace(patt, String.fromCharCode(i + 65)); }); } return arr; } function createObject(arr) { var obj = {}; arr.forEach(function(val) { if(/^w$/.test(val)) { obj[val] = []; } }); arr.splice(0, nodeNum); return[obj, arr]; } function makeObject(arr) { var connObj = arr[0];

var connArr = arr[1]; for (var char in connObj) { var patt = new RegExp('(?:(?:' + char + '\|(\w))|(?:(\w)\|' + char + '))\|(\d+)'); connArr.forEach(function(val) { var result = patt.exec(val); if (result) { resFiltered = result.filter(function(val) { return val; }) connObj[char].push([resFiltered[1], parseInt(resFiltered[2])]); } }); } return connObj } function paths(obj) { var endNode = String.fromCharCode(65 + nodeNum - 1); var resultArr = [['A', 0]]; while(resultArr.some(function(val){return val[0].slice(-1) !== endNode})) { var hotChar = resultArr[0][0].slice(-1); if (hotChar === endNode) { resultArr.push(resultArr.shift()); } else { holdArr = obj[hotChar]; holdArr = holdArr.filter(function(val) { return resultArr[0][0].indexOf(val[0]) === -1; }); var oldStr = resultArr.splice(0, 1)[0]; holdArr.forEach(function(val) { resultArr.push([oldStr[0] + val[0], oldStr[1] + val[1]]); }); } } return resultArr; } function finalForm(str) { var truePathArr = str.split(''); truePathArr = truePathArr.map(function(val){ return strArr[val.charCodeAt(0) - 65]; }) return truePathArr.join('-'); } } // keep this function call here // to see how to enter arguments in JavaScript scroll down WeightedPath(readline());

RREF Matrix Have the function RREFMatrix(strArr) take strArr which will be an array of integers represented as strings. Within the array there will also be "" elements which represent break points. The array will make up a matrix where the (number of break points + 1) represents the number of rows. Here is an example of how strArr may look: ["5","7","8","","1","1","2"]. There is one "", so 1 + 1 = 2. Therefore there will be two rows in the array and the contents will be row1=[5 7 8] and row2=[1 1 2]. Your program should take the given array of elements, create the proper matrix, and then through the process of Gaussian elimination create a reduced row echelon form matrix (RREF matrix). For the array above, the resulting RREF matrix would be: row1=[1 0 3], row2=[0 1 -1]. Your program should return that resulting RREF matrix in string form combining all the integers, like so: "10301-1". The matrix can have any number of rows and columns (max=6x6 matrix and min=1x1 matrix). The matrix will not necessarily be a square matrix. If the matrix is an nx1 matrix it will not contain the "" element. The integers in the array will be such that the resulting RREF matrix will not contain any fractional numbers. Hard challenges are worth 15 points and you are not timed for them.

Examples Input: ["2","4","8","","6","12","14"] Output: 120001 Input: ["2","2","4","","1","1","8","","7","6","5"] Output: 100010001 function RREFMatrix(strArr) { //convert number strings into numbers strArr = strArr.map(function(val) { var temp = parseInt(val, 10); return (temp || temp - 1) ? parseInt(val, 10) : val; }); //transform input string into an array of rows var matrixArr = transform(strArr); var len = matrixArr.length; //sort by leading zeroes, if any; orderRows(matrixArr); for(var i = 0; i < len - 1; i++) { rows = leadEliminate(matrixArr[i], matrixArr[i + 1]); if (rows === null) { orderRows(matrixArr); console.log(matrixArr); //i--; continue; } matrixArr[i] = rows[0]; matrixArr[i + 1] = rows[1]; var checker = matrixArr.slice(); orderRows(matrixArr); if (!checker.every(function(val, ind) { return val === matrixArr[ind]; })) { i--; continue; } }

var redPivotArr = []; matrixArr.forEach(function(row) { var divisor = row.find(function(val) { val = parseFloat(val.toFixed(4), 10); return val !== 0; }); if (divisor) { row = row.map(function(item){ return item / divisor }); redPivotArr.push(row); } else { redPivotArr.push(row); } }); for (var i = len - 1; i > 0; i--) { var index = redPivotArr[i].findIndex(function(val) { posVal = parseFloat(val.toFixed(4), 10); return posVal !== 0; }); for (var j = 0; j < i; j++) { if (redPivotArr[j][index]) { var ratio = redPivotArr[j][index]; redPivotArr[j] = redPivotArr[j].map(function(item, index) { return item -= redPivotArr[i][index] * ratio; }) } } } var resStr = ''; redPivotArr.forEach(function(row) { row.forEach(function(item) { resStr += item.toFixed(); }); }); return resStr; } //-------------------------helpers---------------------function transform(arr) { var resArr = []; var tempArr = []; arr.forEach(function(val, ind) { if (typeof val === 'number') { tempArr.push(val); } else { resArr.push(tempArr.slice()); tempArr = []; } }); resArr.push(tempArr); return resArr }

function qualified(arr) { } function leadEliminate(arr1, arr2) { var pivotPos = arr1.findIndex(function(val) { val = parseFloat(val.toFixed(4), 10); return val !== 0; }); if (pivotPos === -1) { return null; } if (arr2[pivotPos]) { var ratio = arr1[pivotPos] / arr2[pivotPos]; var adjustedRow1 = arr1.map(function(val) { return val / ratio; }); var adjustedRow2 = arr2.map(function(val, ind) { return val - adjustedRow1[ind]; }) return [adjustedRow1, adjustedRow2]; } else { return [arr1, arr2]; } } function orderRows(arr) { arr.sort(function(a, b) { var aIndex = a.findIndex(function(val) {return val !== 0}); var bIndex = b.findIndex(function(val) {return val !== 0}); aIndex = aIndex === -1 ? Infinity : aIndex; bIndex = bIndex === -1 ? Infinity : bIndex; return aIndex - bIndex; }) return; // } }

// keep this function call here RREFMatrix(readline()); Intersecting Lines Have the function IntersectingLines(strArr) take strArr which will be an array of 4 coordinates in the form: (x,y). Your program should take these points where the first 2 form a line and the last 2 form a line, and determine whether the lines intersect, and if they do, at what point. For example: if  strArr is ["(3,0)","(1,4)","(0,-3)","(2,3)"], then the line created by (3,0) and (1,4) and the line created by (0,-3) (2,3) intersect at (9/5,12/5). Your output should therefore be the 2 points in fraction form in the following format: (9/5,12/5). If there is no denominator for the resulting points, then the output should just be the integers like so:  (12,3). If any of the resulting points is negative, add the negative sign to the numerator like so:  (-491/63,-491/67). If there is no intersection, your output should return the string "no intersection". The input points and the resulting points can be positive or negative integers. Hard challenges are worth 15 points and you are not timed for them.

Examples Input: ["(9,-2)","(-2,9)","(3,4)","(10,11)"] Output: (3,4) Input: ["(1,2)","(3,4)","(-5,-6)","(-7,-8)"] Output: no intersection function IntersectingLines(strArr) { var ObjArr = formatCheck(strArr); var numStringArr = ObjArr.map(function(val) { return stringIt(val); }); line1Points = [numStringArr[0], numStringArr[1]]; line2Points = [numStringArr[2], numStringArr[3]];

line1 = fullFormat(line1Points); line2 = fullFormat(line2Points);

if (line1[4] === line2[4]) { return line1[5] === line2[5] ? "These are the same line!" : "no intersection" }

var bigRes = interPoint([line1, line2]); bigRes = bigRes.map(function(val){ return mrClean(val); }) return '(' + bigRes[0] + ',' + bigRes[1] + ')'; }

//---------------------------helper functions-------------------------/* formatCheck(): first, it checks to make certain there are four points. checks the format of each point. Returns true if all are okay, false if not. */ function formatCheck (arr) { if (arr.length != 4) {

Then it

return false; } arr = arr.map(function(val) { val = val.trim(); while (/ss/.test(val)) { val = val.replace(/ss/, ' '); } val = val.replace(/(s+/, '('); val = val.replace(/,s+/, ','); return val; }); patt = /^((?:(-?d*)(?=s|,))?s?(?:(-?d*)/(?=-?d))?(-?d*),(?:(-?d*)(?=s|)))?s? (?:(-?d*)/(?=-?d))?(-?d*))$/ newArr = arr.map(function(val) { return patt.exec(val); }); if (newArr.some(function(val) {return val === null;})) { return false; } else { newObj = newArr.map(function(val) { return initFracPrep(val); }); } return (newObj); } /* initFracPrep takes a pair of numbers in fraction form (can have an integer part, separated by a space), and puts out each number as an object, numsObj, with numer(ator) and denom(inator) parts. */ function initFracPrep(arr) { var num1 = { I: arr[1] || 0, N: arr[2] || 0, D: arr[3] || 1 } var num2 = { I: arr[4] || 0, N: arr[5] || 0, D: arr[6] || 1 } var numsObj = {}; numsObj.numer1 = num1.I * num1.D + parseInt(num1.N); numsObj.denom1 = parseInt(num1.D); numsObj.numer2 = num2.I * num2.D + parseInt(num2.N); numsObj.denom2 = parseInt(num2.D); return numsObj; }

/* stringIt takes an object composed of two points in fraction form, and returns them as an array of strings. ex: { numer1: -12, denom1: 15, numer2: 2, denom2: -6 } => ['-12/15', '2/-6'] */ function stringIt(obj) { var strArr = ([obj.numer1.toString() +'/'+ obj.denom1.toString(), obj.numer2.toString() + '/' + obj.denom2.toString()]); var strArr = strArr.map(function(val){ return fractionReduce(val); }) return strArr; } /* this is the function that takes a fraction string, reduces it, and returns a fraction string, with all the common factors removed. It requires dependency function primeFactors() and objectify(); */ function fractionReduce (str) { patt = /-?d+/g; var numArr = str.match(patt); var numerator = parseInt(numArr[0]); var denominator = parseInt(numArr[1]);

var numFactorObj = objectify(primeFactors(numerator)); var denFactorObj = objectify(primeFactors(denominator)); for (var x in numFactorObj) { if (x in denFactorObj) { var min = Math.min(denFactorObj[x], numFactorObj[x]); denFactorObj[x] -= min; numFactorObj[x] -= min; } } var num1 = 1; for (var x in numFactorObj) { num1 *= Math.pow(parseInt(x), numFactorObj[x]); } var num2 = 1; for (var x in denFactorObj) { num2 *= Math.pow(parseInt(x), denFactorObj[x]); } return (num1.toString() + '/' + num2.toString()); } /* primeFactors takes a number, and return an array, being the list of prime factors of the number (closeFunc is just a closure wrapper to get holdArr out of the global space).

*/ function primeFactors (num) { var flag = 1; if (num < 0) { num = Math.abs(num); var flag = -1; } var factors = closeFunc(); var res = factors(num); res.push(flag); return res; } function closeFunc() { var holdArr = []; function nextFactor(num) { var pivot = Math.floor(Math.sqrt(num)) var flag = false; for (var i = 2; i