网格锁

For a coding challenge that I did recently, I wrote a function that took in an input of a matrix of size N x N and output whether or not it was valid. In order for the matrix to be valid, it had to have each of the numbers up until N in both the columns and the rows. For example, this is one possible grid, which would be submitted as an array of arrays: [[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]].

对于我最近进行的编码挑战,我编写了一个函数,该函数接受大小为N x N的矩阵的输入,并输出它是否有效。 为了使矩阵有效,必须在列和行中使每个数字一直到N。 例如,这是一个可能的网格,将作为数组的数组提交:[[1、2、3、4],[2、3、4、1],[3、4、1、2], [4,1,2,3]。

Since this satisfies the conditions, the function would return “VALID”.

由于这满足条件,因此该函数将返回“ VALID”。

数独 (Sudoku)

Though I have never played it before, this problem was supposed to be designed to check sub-grids in a Sudoku game. Here are a couple of resources about Sudoku in case you would like to learn more.

尽管我以前从未玩过,但该问题应该被设计为检查Sudoku游戏中的子网格。 如果您想了解更多,这里有一些关于Sudoku的资源。

(Solution)

This is my solution to the problem, which I will explain below!

这是我对问题的解决方案,我将在下面解释!

function checkSubSudoku(matrix) {let lengthOfMatrix = matrix.length;let i;let n;let theIntegers = [];let copyOfMatrix = [];let areTheRowsValid;let areArraysInMatrixSameSize;let flattenedMatrix = matrix.flat();let allAreIntegers;//check to see whether all of the items in the arrays are positive integersfor(let a = 0; a < flattenedMatrix.length; a++){if (Math.sign(flattenedMatrix[a])===1){if (!allAreIntegers || allAreIntegers === true){allAreIntegers = true;}else {allAreIntegers = false;}}else {allAreIntegers = false;}}if(!allAreIntegers){return "INVALID"}else{//check that the length of each of the arrays within the array are the same sizefor(let w = 0; w < lengthOfMatrix; w++){if(matrix[w].length === lengthOfMatrix){if(!areArraysInMatrixSameSize || areArraysInMatrixSameSize === true){areArraysInMatrixSameSize = true;}else{areArraysInMatrixSameSize = false;}}else{areArraysInMatrixSameSize = false;}}if(!areArraysInMatrixSameSize){return "INVALID"}else{//set the variable theIntegers to see what numbers must be in each row and column of the matrixfor(n = 0; n < lengthOfMatrix; n++){theIntegers.push(n+1);}theIntegers = parseInt(theIntegers.join(""))//create a copy of the matrix in order to be able to sort without modifying the original arrayfor(let i = 0; i < lengthOfMatrix; i++){let sliceOfMatrix = matrix.slice(i, i+1).flat();let sortedSlice = sliceOfMatrix.sort((a, b)=>{return a-b})copyOfMatrix.push(sortedSlice);}//check each row of the copy to make sure it includes each numberfor(let h = 0; h < lengthOfMatrix; h++){if(parseInt(copyOfMatrix[h].join(""))===theIntegers){if(!areTheRowsValid || areTheRowsValid === true){areTheRowsValid = true;}else{areTheRowsValid = false;}}else{areTheRowsValid = false;}}//create an array of the columnslet copyForColumns = [];for(let g = 0; g < lengthOfMatrix; g++){let arrayToPush = [];for (h = 0; h < lengthOfMatrix; h++){arrayToPush.push(matrix[h][g])}copyForColumns.push(arrayToPush.sort((a, b)=> {return a-b}))}//check each column to make sure it includes all of the numberslet areTheColumnsValid;for(let d = 0; d < lengthOfMatrix; d++){if(parseInt(copyForColumns[d].join(""))===theIntegers){if(!areTheColumnsValid || areTheColumnsValid === true){areTheColumnsValid = true;}else{areTheColumnsValid = false;}}else{areTheColumnsValid = false;}}//   return either "VALID" or "INVALID"if(areTheRowsValid && areTheColumnsValid){return "VALID";}else{return "INVALID";}}}}

损害控制 (Damage Control)

In the first couple of steps, I am doing damage control, anticipating edge cases. First, I check to see whether all of the items in the arrays are positive integers. I flatten the nested array to make one long array of items; then I check each of these items and use Math.sign() to determine whether they are positive integers. Math.sign() returns 1 if what is put in between the parentheses is a positive integer, -1 if what is placed there is a negative number, 0 if 0 is put there, and NaN if the value is anything else put in between quotation marks, for example “,”.

在前几步中,我将进行损害控制,以预见边缘情况。 首先,我检查一下数组中的所有项目是否都是正整数。 我将嵌套数组弄平,以形成一长串项目。 然后我检查所有这些项目,并使用Math.sign()确定它们是否为正整数。 如果放在括号之间的是正整数,则Math.sign()返回1;如果放在其中为负数,则返回-1;如果放在其中是0,则返回0;如果在中间还有其他值,则返回NaN。引号,例如“,”。

Fun fact: whether you put a number such as 91 in between quotation marks or not, like this: Math.sign(“91”) or this: Math.sign(91), it will return 1. The same goes for negative numbers, which will cause Math.sign to return -1. However, Math.sign(,) will throw an error, while Math.sign(“,”) will return NaN.

有趣的事实:无论您是否在引号之间插入诸如91之类的数字,例如:Math.sign(“ 91”)或this:Math.sign(91),都会返回1。对于负数也是如此。 ,这将导致Math.sign返回-1。 但是,Math.sign(,)将引发错误,而Math.sign(“,”)将返回NaN。

One of many example of why coding is a good time!

为什么编码是美好时光的众多示例之一!

If the current item in the loop through the flattened matrix passes the test, and if the variable areAllIntegers either has not been set yet or has been set to true, then it remains true, being set to true again. If areAllIntegers has been set to false, though, it remains false, since one non-positive integer or other value like a punctuation mark means that the whole grid is invalid. If the current item in the for loop does not pass the test of Math.sign(), then whether areAllIntegers has not been set yet, has been set to true, or has already been set to false, it will be set to false. Another way I could have done this would have been to use a while loop, so that once the variable is set to false, the loop exits, as none of the other values need to be checked.

如果循环中经过展平矩阵的当前项通过测试,并且变量areAllIntegers尚未设置或已设置为true,则它保持为true,然后再次设置为true。 但是,如果将areAllIntegers设置为false,则它将保持为false,因为一个非正整数或其他值(如标点符号)表示整个网格均无效。 如果for循环中的当前项未通过Math.sign()的测试,则areareInIntegers尚未设置,已设置为true或已设置为false,则将其设置为false。 我可以做到的另一种方式是使用while循环,这样一旦将变量设置为false,则循环将退出,因为不需要检查其他任何值。

Next, I see whether the input arrays within the matrix are all the same size. This follows a similar pattern to the first test, though it is on the non-flattened matrix. We don’t have to check the values within the arrays at this point; we just want to take the length of them. This follows the same pattern as the one above as far as setting the variable areArraysInMatrixSameSize to true or false goes.

接下来,我看看矩阵内的输入数组的大小是否都相同。 尽管它在未展平的矩阵上,但遵循与第一次测试类似的模式。 此时,我们不必检查数组中的值。 我们只想花点时间。 只要将变量areArraysInMatrixSameSize设置为true或false,就遵循与上述相同的模式。

If either of those tests fail (if either areArraysInMatrixSameSize or areAllIntegers have a value of false), the function exits, returning “INVALID”. Otherwise, it goes on to the next step.

如果这些测试中的任何一个失败(如果areArraysInMatrixSameSize或areAllIntegers的值为false),则该函数将退出,并返回“ INVALID”。 否则,将继续进行下一步。

下一步:检查行 (The Next Step: Checking the Rows)

After that, I set the value of theIntegers by running a for loop that goes through the length of the input matrix starting from the counter of n = 0 and pushes n+1 into an array that is then joined and parsed into a number with parseInt. The result of this is that if the input matrix is [[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]], then theIntegers is 1234. This will be used as the point of comparison for what is in each of the rows and columns later on.

之后,我通过运行一个for循环来设置theIntegers的值,该循环从n = 0的计数器开始遍历输入矩阵的长度,然后将n + 1推入数组,然后将其连接并使用parseInt解析为一个数字。 这样的结果是,如果输入矩阵是[[1、2、3、4],[2、3、4、1],[3、4、1、2],[4、1、2、3 ]],则integers为1234。这将用作以后各行和各列中内容的比较点。

Next, I create a copy of the matrix. The reason that I do this is because I am going to be sorting each of the arrays in the matrix to check them against theIntegers to make sure that all of the numbers are included in each row. I do not want to alter the original input matrix, because I will also be checking the column in a separate step and can’t do that if the original input matrix is changed.

接下来,我创建矩阵的副本。 之所以这样做,是因为我将对矩阵中的每个数组进行排序,以对照Integers进行检查,以确保每行中都包含所有数字。 我不想更改原始输入矩阵,因为我还将在一个单独的步骤中检查列,并且如果原始输入矩阵发生了更改,则无法这样做。

To create a copy of the matrix, I implemented another for loop starting at 0 and incrementing up until the length of the matrix. At each step of the for loop, I took a slice of the matrix — one of the arrays in the wrapping array, starting from the beginning of the matrix and going until the end.* I sorted it and pushed it into copyOfMatrix. So, copyOfMatrix ended up being not an exact replica of the original input matrix but a sorted version of it. This was so that in the next step of the function, I could check each sorted array to see if it included all of the requisite numbers.

为了创建矩阵的副本,我实现了另一个for循环,该循环从0开始并递增直到矩阵的长度。 在for循环的每个步骤中,我从矩阵的开头开始一直到结尾都截取了矩阵的一个切片—包装数组中的一个数组。*我对其进行了排序并将其推入copyOfMatrix。 因此,copyOfMatrix最终不是原始输入矩阵的精确副本,而是其排序版本。 这样一来,在该函数的下一步中,我可以检查每个排序后的数组,以查看其是否包含所有必需的数字。

*To review how to make a shallow copy of the matrix, I consulted a few websites. I am not sure which of them convinced me to try using the slice method, so here are links to all of them.

*要查看如何制作矩阵的浅表副本,我查阅了一些网站。 我不确定其中有谁说服我尝试使用slice方法,因此这里是所有链接。

Because the coding challenge ended up being an exercise in my over-attachment to the for loop, I ran another for loop with a counter of zero incrementing up until the length of the matrix. Here is where I join the sorted array at the current location in the loop and parse it with parseInt before comparing it to theIntegers. If it matches theIntegers, then I go through the same true/false process of setting the variable areTheRowsValid as I did earlier in the first two conditions of the function. At the end of the loop, if areTheRowsValid is false, I could (and should) exit and return “INVALID”.

因为编码挑战最终是我过度连接到for循环的一个练习,所以我运行了另一个for循环,其计数器为零递增直到矩阵的长度。 这是我在循环中当前位置加入已排序数组的位置,并在将其与theIntegers比较之前使用parseInt对其进行解析。 如果它与theIntegers相匹配,那么我将像在函数的前两个条件中一样,执行设置变量areTheRowsValid的正确/错误过程。 在循环结束时,如果areTheRowsValid为false,则我可以(并且应该)退出并返回“ INVALID”。

However, I did it a little less efficiently, going ahead and checking the columns before making any final determinations one way or another about the validity of this poor matrix which has already been through a lot.

但是,我这样做的效率要低一些,继续并检查各列,然后以一种或另一种方式对这个可怜的矩阵的有效性做出最后决定。

(The Columns)

So! On to the columns!

所以! 上列!

Next, I create an array of arrays of columns. This is an act of imagination, since we don’t actually have a grid and have to imagine the nested arrays stacked on top of each other.

接下来,我创建一个由列数组组成的数组。 这是一种想像的行为,因为我们实际上没有网格,必须想象嵌套在一起的嵌套数组。

I return to the friendly for loop, but unfortunately for those of you keeping track of time complexity, this time it is a nested for loop. At the first level of the for loop, I initialize an empty array called arrayToPush. Then in the inner loop, I push matrix[h][g] into arrayToPush. What that means is that with a grid that looks like this:

我回到友好的for循环,但是不幸的是,对于那些跟踪时间复杂度的人,这次是嵌套的for循环。 在for循环的第一级,我初始化了一个空数组arrayToPush。 然后在内部循环中,我将matrix [h] [g]推入arrayToPush中。 这意味着使用如下所示的网格:

Image for post

matrix[h] will be the column, and [g] will represent the row. So, on the first loop through, matrix[h][g] will be matrix[0][0], then matrix[0][1], matrix[0][2], and matrix[0][3], or [1, 2, 3, 4]. After that first nested loop through, arrayToPush is pushed into the empty array copyForColumns, though it is sorted first.

matrix [h]将成为列,[g]将代表行。 因此,在第一个循环中,矩阵[h] [g]将是矩阵[0] [0],然后是矩阵[0] [1],矩阵[0] [2]和矩阵[0] [3]或[1、2、3、4]。 在第一个嵌套循环执行之后,arrayToPush被推入空数组copyForColumns中,尽管它首先被排序。

The next nested loop through would be matrix[1][0], matrix[1][1], matrix[1][2], and matrix[1][3], or [2, 3, 4, 1]. At this point, you might notice that the rows and columns with the same index position are actually the same (e.g. row one is the same as column one, row two is the same as column two, etc.). I did not let that observation deter me, because, not being familiar with this type of problem beforehand, it was not clear to me whether that is the way it always ends up as a rule. If it is, though, then checking the columns would be unnecessary.

下一个嵌套循环将是matrix [1] [0],matrix [1] [1],matrix [1] [2]和matrix [1] [3]或[2、3、4、1] 。 此时,您可能会注意到具有相同索引位置的行和列实际上是相同的(例如,第一行与第一列相同,第二行与第二列相同,依此类推)。 我没有让这种观察阻止我,因为我事先不熟悉这种类型的问题,所以我不清楚这是否总是它通常的结局。 如果是这样,则不需要检查列。

Report back to me if you would like to discuss or tell me what is what.

如果您想讨论或告诉我什么是什么,请报告给我。

In the next step, I do the same thing that I did to check whether the rows were valid, looping through copyForColumns, joining each array, and parsing the array with parseInt before comparing that value to theIntegers.

在下一步中,我执行与检查行是否有效相同的操作,遍历copyForColumns,联接每个数组,并在将值与theIntegers比较之前使用parseInt解析该数组。

In the final step, if both areColumnsValid and areRowsValid are true, then the function returns “VALID”. Otherwise, it returns “INVALID”.

在最后一步中,如果areColumnsValid和areRowsValid均为true,则该函数返回“ VALID”。 否则,它返回“ INVALID”。

And that is the end of my story about grids.

这就是我关于网格的故事的结尾。

翻译自: https://medium.com/swlh/grid-lock-ea9246f22b8c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值