Matrix arrangement issues in php

前端 未结 6 1087
闹比i
闹比i 2021-02-20 13:07

I would like to know some solutions to such a problem.

It is given a number lets say 16 and you have to arrange a matrix this way

1  2  3  4
12 13 14 5
         


        
6条回答
  •  北海茫月
    2021-02-20 14:03

    OK, I'm just posting this answer for fun.

    The other solutions use variables to accumulate information iteratively. I wanted to try a functional solution, where the number of any table cell (or alternatively, the table cell for any number) could be known without iterating through any others.

    Here it is in javascript. I know, it's not pure functional programming, nor is it extremely elegant, but the computation of the number for each table cell is done without reference to prior iterations. So it's multi-core friendly.

    Now we just need somebody to do it in haskell. ;-)

    BTW this was written before the comment that the 1 should end up in a certain location that is not necessarily the northwest corner (still unspecified as of now).

    Since somebody mentioned the Ulam spiral, just for kicks I added code to put a red border around the primes (even though the spiral is inside out). Interestingly enough, there do seem to be diagonal streaks of primes, though I don't know if it's significantly different from the streaks you'd get with random odd numbers.

    The code:

    // http://stackoverflow.com/questions/3584557/logical-problem
    
    /* Return a square array initialized to the numbers 1...n2, arranged in a spiral */
    function spiralArray(n2) {
       var n = Math.round(Math.sqrt(n2));
       if (n * n != n2) {
          alert('' + n2 + ' is not a square.');
          return 0;
       }
       var h = n / 2;
       var arr = new Array(n);
       var i, j;
    
       for (i = 0; i < n; i++) {
          arr[i] = new Array(n);
          for (j = 0; j < n; j++) {
             // upper rows and lower rows of spiral already completed
             var ur = Math.min(i, n - i, j + 1, n - j, h),
                lr = Math.min(i, n - i - 1, j + 1, n - j - 1, h);
             // count of cells in completed rows
             // n + n-2 + n-4 ... n - 2*(ur-1) = ur*n - (ur*2*(ur - 1)/2) = ur * (n - ur + 1)
             // n-1 + n-3 + ... n-1 - 2*(lr-1) = lr*(n-1) - (lr*2*(lr - 1)/2) = lr * (n - 1 - lr + 1)
             var compr = ur * (n - ur + 1) + lr * (n - lr);
             // e.g. ur = 2, cr = 2*(5 - 2 + 1) = 2*4 = 8
             // left columns and right columns of spiral already completed
             var rc = Math.min(n - j - 1, i, n - i, j + 1, h),
                lc = Math.min(n - j - 1, i, n - i - 1, j, h);
             // count of cells in completed columns
             var compc = rc * (n - rc) + lc * (n - lc - 1);
             // offset along current row/column
             var offset;
             // Which direction are we going?
             if (ur > rc) {
                // going south
                offset = i - (n - j) + 1;
             } else if (rc > lr) {
                // going west
                offset = i - j;
             } else if (lr > lc) {
                // going north
                offset = n - i - 1 - j;
             } else {
                // going east
                offset = j - i + 1;
             }
    
             arr[i][j] = compr + compc + offset;
          }
       }
       return arr;
    }
    
    function isPrime(n) {
        // no fancy sieve... we're not going to be testing large primes.
        var lim = Math.floor(Math.sqrt(n));
        var i;
        if (n == 2) return true;
        else if (n == 1 || n % 2 == 0) return false;
        for (i = 3; i <= lim; i += 2) {
            if (n % i == 0) return false;
        }
        return true;
    }
    
    // display the given array as a table, with fancy background shading
    function writeArray(arr, tableId, m, n) {
       var tableElt = document.getElementById(tableId);
       var s = '';
       var scale = 1 / (m * n);
       var i, j;
       for (i = 0; i < m; i++) {
          s += '';
          for (j = 0; j < n; j++) {
             var border = isPrime(arr[i][j]) ? "border: solid red 1px;" : "";
             s += '';
          }
          s += '';
       }
       s += '
    ' + arr[i][j] + '
    '; tableElt.innerHTML = s; } function tryIt(tableId) { var sizeElt = document.getElementById('size'); var size = parseInt(sizeElt.value); writeArray(spiralArray(size * size), 'spiral', size, size); }

    The HTML page to exercise it:

    
        
            
            
        
        
            
    Size of spiral:

提交回复
热议问题