JS의 효과적인 디지털 솔루션

리코더의 도전 36은'유효 스도쿠'다.솔루션 뒷면의 논리는 매우 간단하지만 응용하기는 좀 까다롭다.
  • 줄마다 중복 항목이 있는지 검사합니다.

  • 열마다 중복항목이 있는지 검사한다.

  • 각 3x3 하위 격자에 중복 항목이 있는지 확인합니다.
  • 중복된 항목이 발견되면 되돌아오기false, 중복된 항목이 발견되지 않으면 되돌아오기true.
  • 하나의 순환에서 하나의 순환을 사용한다. 앞의 두 가지 검사는 매우 간단하지만 내가 걸려 넘어진 것은 서브 격자이다. 진일보한 순환에서 방향을 잃고 더욱 간단한 방법이 있어야 한다는 것을 안다.
    나는 모든 코드를 삭제한 후에 다시 시작했고, 마지막에 해결 방안을 찾았다. 나는 지금 토론하러 올 것이다.내가 인터넷에서 다른 사람의 해결 방안을 찾을 때 (당신의 코드를 다른 사람의 코드와 비교하는 것을 강력히 권장합니다) 특히 만약 당신이 독학으로 인재가 된다면 자바스크립트로 작성한 해결 방안의 글을 많이 찾을 수 없습니다. 이것은 당신들 중 일부에게 도움이 될 수 있다고 생각합니다.

    문제.
    스톡홀름판은 2D 배열로 표시됩니다.채워진 사각형은 숫자가 있는 문자열(예를 들어 “6”으로 그려지고 채워지지 않은 사각형은 “.”로 표시됩니다.다음 예제를 참조하십시오.
    const board = [
      [5,3",".",".","7",".",".",".","."],
      [“6",".",".","1","9","5",".",".","."],
      [.","9","8",".",".",".",".","6","."],
      [“8",".",".",".","6",".",".",".","3"],
      [4",".",".","8",".","3",".",".","1"],
      [“7",".",".",".","2",".",".",".","6"],
      [.","6",".",".",".",".","2","8","."],
      [“.",".",".","4","1","9",".",".","5"],
      [.",".",".",".","8",".",".","7","9"]
    ];
    
    지금까지 출력된 모든 항목이 유효한지, true 무효한 항목 (줄, 열, 하위 격자에 있는 중복 항목) 이 있는지, 출력해야 합니다.

    솔루션
    계획은 다음과 같습니다.
  • 어레이당 9개의 어레이로 3개 어레이 설정
  • 열의 수조로 모든 9열을 포함하는 데 사용
  • 모든 9줄을 포함하는 줄 그룹
  • 하위 격자 그룹, 모든 9 하위 격자 포함
  • 전체 회로판을 순환하고 각 단원의 값을 검사한다.셀에 값이 있으면 해당 행, 열 및 하위 격자 배열에 해당 셀을 추가합니다.
  • 모든 그룹에 중복값이 있는지 검사합니다.중복항false이 있다면, 중복항return false이 없으면.
  • 차 한잔 마셔요.

  • 설정
    3개의 어레이를 생성하는 것부터 시작하겠습니다.
    let rows = [];
    let columns = [];
    let boxes = []; 
    
    그런 다음 각 어레이에 9개의 서브어레이를 추가합니다.
    for (let i = 0; i < 9; i++) {
        rows.push([]);
        columns.push([]);
        boxes.push([]);
    }
    
    생성된 코드는 다음과 같습니다.
    rows = [[], [], [], [], [], [], [], [], []];
    columns = [[], [], [], [], [], [], [], [], []];
    boxes = [[], [], [], [], [], [], [], [], []];
    

    널빤지를 가로지르다
    그런 다음 행의 주기와 열의 내부 주기를 설정합니다.
    // ROW LOOP
    for (let i = 0; i < board.length; i++) {
        // COL LOOP
        for (let j = 0; j < board.length; j++) {
    
        }
    }
    
    주: 우리의 회로판 사이즈가 이미 알고 고정되어 있기 때문에 우리는 return trueboard.length로 바꿀 수 있습니다.
    이것은 전체 회로판을 훑어볼 수 있게 할 것이다. 그 중에서 9 는 줄 좌표의 인덱스이고, i 는 열 좌표의 인덱스이다. (예를 들어 왼쪽 위의 독립 단원에 접근하려면 좌표는 j, 오른쪽 아래의 단원 좌표는 0,0 이다.
    주기의 모드는 다음과 같습니다.
    i = 0, j = 1
    i = 0, j = 2
    i = 0, j = 3
    …
    i = 0, j = 8
    i = 1, j = 0
    i = 1, j = 1
    …
    i = 8, j = 6
    i = 8, j = 7
    i = 8, j = 8
    

    값을 확인하고 어레이에 추가
    현재 우리는 전체 독립판을 훑어보고 있습니다. 우선 모든 칸에 값이 있는지 확인하고, 만약 값이 있다면, 적당한 그룹에 추가해야 합니다.열 배열과 행 배열을 먼저 수행합니다.
    // ROW LOOP
    for (let i = 0; i < board.length; i++) {
        // COL LOOP
        for (let j = 0; j < board.length; j++) {
            if(board[i][j] !== .) {
                rows[i].push(board[i][j]);
                columns[j].push(board[i][j]);
            }
        }
    } 
    
    영어:
    모든 칸에 대해 칸이 비어 있는지 확인하십시오.셀이 비어 있지 않으면 해당 행과 열 배열에 셀 값을 추가합니다.
    순환 운행이 끝난 후에 우리는 회로판의 각 줄의 값 수조와 8,8 수조를 남겨야 한다. 이는 회로판의 각 열의 값 수조를 포함한다.
    지금은 좀 어수선해 보이기 때문에 셀 값을 저장할 변수를 추가합니다. 그러면 매번 쓸 필요가 없습니다. rows
    for (let i = 0; i < board.length; i++) {
        for (let j = 0; j < board.length; j++) {
    
            let cell = board[i][j];
    
            if(cell !== .) {
                rows[i].push(cell);
                columns[j].push(cell);
            }
        }
    } 
    

    서브넷은요?
    열과 줄의 모든 값을 가져오는 것은 간단한 과정이지만, 모든 하위 격자 인덱스를 가져오는 것은 좀 까다롭다.지금, 나는 인정해야 한다. 내가 이 문제에 대한 최초의 해결 방안은 함수를 포함한다. 이 함수는 좌표에 따라 우리가 어느 3x3 서브 격자에 있는지 검사하지만 더욱 우아한 해결 방안은 다음과 같은 공식이다.columns우리 코드에 그것을 추가합시다. 나는 줄마다 주석을 달았습니다. 그러면 우리가 무엇을 하는지 볼 수 있습니다.
    for (let i = 0; I < board.length; i++) { // ROW CO-ORDINATE
        for (let j = 0; j < board.length; j++) { // COLUMN CO-ORDINATE
    
            let cell = board[i][j]; // STORE CELL IN VARIABLE
    
            if(cell !== .) { // IF CELL NOT EMPTY
                rows[i].push(cell); // ADD VALUE TO APPROPRIATE ROWS ARRAY
                columns[j].push(cell); // ADD VALUE TO APPROPRIATE COLUMNS ARRAY
    
                let boxIndex = Math.floor((i / 3)) * 3 + Math.floor(j / 3); // GET SUB-GRID (BOX) INDEX
    
                boxes[boxIndex].push(cell); // ADD VALUE TO BOXES ARRAY
    
            }
        }
    } 
    
    요약:
  • 우리는 줄과 열 사이를 순환하고 한 단원, 한 단원으로 회로판 단원을 옮겨다닌다
  • 변수board[i][j]에 셀을 저장합니다.
  • 우리는 (row / 3) x 3 + column / 3의 값이 있는지 검사한다.
  • 우리는 상응하는 cell자수조, cell자수조와 rows자수조
  • 에 값을 첨가한다.

    확인
    지금 해야 할 일은 중복 항목이 있는지 검사하는 것이다.순환을 끝내고 모든 값을 그룹에 추가한 다음, 모든 그룹에 중복이 있는지 확인하십시오. 이것은 논리에 맞는 것일 수도 있습니다.이것은 실행할 수 있지만, 이것은 우리의 코드가 아무리 빨리 복제되더라도 매번 전체 회로판을 두루 돌아다녀야 한다는 것을 의미한다.더 간결한 방법은 우리가 새로운 값을 발견할 때마다 중복된 '내연' 을 검사하는 것이다.
    완료된 코드는 다음과 같습니다.
    function isValidSudoku(board) { 
      for (let i = 0; i < board.length; i++) { 
        for (let j = 0; j < board.length; j++) {
    
          let cell = board[i][j];
    
          if(cell !== .) {
            if (rows[i].includes(cell) {
              return false
            } else rows[i].push(cell);
    
            if (columns[j].includes(cell) {
              return false;
            } else columns[j].push(cell);
    
            let boxIndex = Math.floor((i / 3)) * 3 + Math.floor(j / 3);
    
            if (boxes[boxIndex].includes(cell) {
              return false;
            } else boxes[boxIndex].push(cell);
    
          }
        }
      } 
    
      return true;
    
    }
    
    이렇게 하면, 우리는 우선 columns 값이 있는지 검사한 다음에, 그룹에 이미 이 값이 존재하는지 검사한다.만약 중복된 코드를 발견한다면, 우리 boxes 는 나머지 코드를 실행하지 않을 것입니다. 그렇지 않으면, 우리는 계속할 것입니다.함수의 밑부분에서, 우리 cell 는 모든 테스트가 통과되었을 때만 실행됩니다.

    오트로
    나는 이것이 어느 정도에 당신이 2d 그룹을 두루 훑어보는 데 도움을 줄 수 있기를 바랍니다. 만약 그렇지 않다면, 나는 당신이 적어도 그것이 매우 재미있다고 느끼기를 바랍니다.나는 이런 도전을 좋아한다. 이것은 단지 나를 좀 화나게 하는 도전일 뿐이다.그런데, 헤헤, 그게 일어났어!

    좋은 웹페이지 즐겨찾기