Desafío de codificación de JavaScript: cuadrícula de estrellas

CorePress2024-01-24  9

Soy nuevo en JavaScript y estoy realizando algunos desafíos de codificación. Me dan una cuadrícula con una estrella. Una vez que lo encuentre, marque todo lo que hay en esa fila y columna. Por ejemplo:

A B C 
D * E 
F G H 

se convertiría en:

A * C
* * *
F * H

La cuadrícula se proporcionaría como una matriz o matrices. Entonces

[ ['A', 'B', 'C'], ['D', '*', 'E'], ['F', 'G', 'H'] ]  

debería regresar

[ ['A', '*', 'C'], ['*', '*', '*'], ['F', '*', 'H'] ]  

No puedo entender cómo hacer esto. Sé que necesitamos recorrer las matrices y encontrar la estrella. Pero no estoy seguro de cómo convertir toda la columna y fila en estrellas. Agradecería cualquier ayuda.

podrías empezar con un nivel básicoop.

- Nina Scholz

27/03/2021 a las 12:05

Piensa en el índice (fila,columna) de la estrella cuando la encuentres. ¿Cuáles son los índices de los valores que necesitas para convertirte en estrellas después de eso? (escríbelo :) )

- Alexander Katsenelenbogen

27/03/2021 a las 12:07

1

¿Cuánto esfuerzo de investigación se espera de los usuarios de Stack Overflow?

- Andreas

27/03/2021 a las 12:15



------------------------------------

let arr = [ ['A', 'B', 'C'], ['D', '*', 'E'], ['F', 'G', 'H'] ] 
let row, col;
for (let i = 0; i < arr.length; i++) {
   for(let j = 0; j < arr[i].length; j++) {
      if(arr[i][j] === "*") {
         row = i;
         col = j;
      }
   }
}

arr[row].fill("*"); // fill that row with "*"

for(let i = 0; i < arr.length; i++) { // fill that column with "*"
   arr[i][col] = "*";
}

Creo que el código anterior resolverá tu problema. En JavaScript tiene muchas funciones que facilitan tus problemas. Por lo tanto, tal vez puedas comenzar con este sorprendente documento: Tutorial de Javascript de MDN

1

Muchas gracias. ¿Cómo cambiaría esto para que funcione con múltiples estrellas y no cuadrados?rejillas? También falla y devuelve un error de tipo si no hay estrellas. (relleno de indefinido)

usuario7876451

27/03/2021 a las 17:34



------------------------------------

Como se mencionó en las publicaciones anteriores, existen muchos métodos para hacer esto. Aquí solo quería mostrar que existe básicamente una solución de 1 línea para encontrar el código "*". dentro de las matrices. La forma de protagonizar la tomé del post de Hasan Brasi, ya que es sencilla y completa.

let arr = [ ['A', 'B', 'C'], ['D', '*', 'E'], ['F', 'G', 'H'] ] 

// find
let col, row = arr.findIndex(x => (col = x.indexOf("*")) !== -1);

// add *'s
if(row !== -1){
  // fill row with *
  arr[row].fill("*");
  // fill cols with *
  for(let i = 0; i < arr.length; i++) {
    arr[i][col] = "*";
  }
}

1

Gracias. Conseguí que funcionara con bucles anidados, pero quiero probar esto también. ¿Cómo puedo cambiar esto para que funcione con múltiples estrellas y cuadrículas no cuadradas?

usuario7876451

27/03/2021 a las 19:50



------------------------------------

// Return the [x, y] position of the star
function findStar(grid) {
    // Loop over all of the rows (y axis)
    for (let y = 0; y < grid.length; y++) {
        // Does the row's columns contain a star?
        // This'll be -1 if there is no star in the row,
        // otherwise it'll be the index of the column that contains the star.
        let x = grid[y].indexOf("*");

        // If we have a star (if not, we'll loop over to the next row)
        if (x > -1) {
            return {x: x, y: y};
        }
    }
}

// Given an [x, y] position and a grid, star out the row and column that
// intersect at the [x, y] position.
function starOut(grid, coords) {

    // Make a copy of the grid (mutation / side effects are bad!)
    // Returning here will of course exit the function and make the
    // outer loop stop running :)
    return grid.map((row, y)=>{
        // Create a clone of the current row in the map
    
        // If it's our current row (the one with the star in it)
        // make the row just all stars
        if (y == coords.y) return new Array(row.length).fill("*");
        
        // If it's not, loop through the row.
        // Return the cell if it's not in the star's column
        // Return a "*" character for that column.
        else return row.map((item, col)=> col == coords.x ? "*" : item);
    });
}

// The function you want, which combines the two tasks together!
function combined(grid) {
    return starOut(grid, findStar(grid));
}

Al crear este código usted mismo, una solución útil es dividirlo en tareas.

Piensa: ¿podré crear la salida sin conocer la posición (x, y) del carácter *? La respuesta es, por supuesto, no, así que esta es nuestra primera tarea: encontrar esa posición.

La segunda tarea es obvia: dado un (x,y) posición, marque la fila y columna dadas. Mi versión original de esta respuesta reunió ambas tareas en una sola función, pero para mostrar este punto en realidad tiene más sentido dividirlas en funciones separadas, como se muestra arriba.

Vale la pena señalar aquí que en realidad puedes realizar estas tareas de forma independiente: si encuentras una de ellas más fácil que la otra, puedes comenzar escribiendo esa y luego probándola.

Por ejemplo, podría escribir primero la función starOut, pasar la cuadrícula y decir {x: 1, y: 1} como parámetro para probarla, sin haber escrito findStar todavía.

Aparte de eso, esperamos que el ejemplo de código le resulte útil y que los comentarios expliquen lo que realmente sucede en cada línea. En el mundo real, en realidad no deberías venir.No es mucho (piense en ellos más como un comentario del director sobre una película, en lugar de un paso a paso de lo que sucede en una línea), pero en StackOverflow quiero asegurarme de que realmente comprenda literalmente cada línea.

Otro paradigma que vale la pena mencionar aquí, que es diferente a lo que ocurre en la respuesta de @Hasan, es que no mutamos la matriz. Esto significa que creamos una matriz completamente nueva, en lugar de cambiar la anterior. Tratar de evitar mutar las cosas que nos dan es un buen hábito, ya que a menudo puede causar problemas más adelante.

Finalmente, me doy cuenta de que es posible que no hayas estado demasiado expuesto al método .map en matrices. Este (y sus amigos .reduce, .filter, etc.) son muy útiles para este tipo de tareas. Recomiendo leer los artículos de MDN sobre estas funciones.--- aquí está el mapa como un buen punto de partida: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Si solo estás buscando el código, sin ninguna ayuda de aprendizaje, aquí lo tienes:

function starOutGrid(grid) {
    for (let y = 0; y < grid.length; y++) {
        let x = grid[y].indexOf("*");
        if (x > -1) {
            return grid.map((row, i)=>{
                if (i == y) return new Array(row.length).fill("*");
                else return row.map((item, col)=> col == x ? "*" : item);
            });
        }
    }
}
Respondido

27 de marzo de 2021 a las 12:15

toastrackengima

toastrackengima

7,742

4

4 insignias de oro

45

45 insignias de plata

56

56 insignias de bronce

3

Gracias. Conseguí que funcionara con bucles anidados, pero quiero probar esto también. ¿Cómo puedo cambiar esto para que funcione con múltiples estrellas y cuadrículas no cuadradas?

usuario7876451

27/03/2021 a las 19:49

@EA6923 Para varias estrellas: puedes modificar fácilmente findStar para que sea findAllStars. Cuando encuentra una, simplemente la agrega a una matriz en lugar de devolverla y luego devuelve la matriz al final. Luego, en nuestra función combinada, recorremos la matriz de coordenadas y caTodos protagonizarán cada uno, pasando por la cuadrícula creada por el último. ¡Separarlos en funciones que funcionan de forma independiente realmente nos ha ayudado aquí!

Toastrackengima

28 de marzo de 2021 a las 1:02

En cuanto a las cuadrículas no cuadradas: estoy bastante seguro de que mi versión ya funciona en ellas :)

Toastrackengima

28 de marzo de 2021 a las 1:05



------------------------------------

Yo consideraría esto como un proceso de dos pasos.

#1. Bucle ovBusque la matriz anidada para descubrir si realmente hay una estrella ubicada en cada matriz. Si es así, haz que esa fila sea toda estrellas. Además, guarde la ubicación del índice de estrella en una variable y empújela a una matriz vacía para su uso posterior. Si no hay estrellas, déjalo sin cambios.

   const grid = [["A","B","C"],["D","*","F"],["G","H","I"]];

   const starIndex = [];

   for (let i = 0; i < grid.length; i++) {

      if (grid[i].includes("*")) {
         const star = grid[i].indexOf("*")
         starIndex.push(star);
         grid[i].fill("*")
      }
   }

#2. Ahora que tenemos nuestras filas que muestran estrellas cuando corresponde, podemos centrarnos en las columnas de estrellas que deben implementarse. Podemos hacer esto con otro bucle. Esta vez recorremos la matriz que creamos para almacenar nuestro índice (o índices) de ubicación de estrellas. Luego ejecutamos un bucle for interno para recorrer todas las matrices de cuadrícula y cambiar el índice (o índices) a la ubicación correspondiente según nuestro índice (o índices) de estrella guardado.

    for (let i = 0; i < starIndex.length; i++) {
          for (let j = 0; j < grid.length; j++) {
             grid[j][starIndex[i]] = "*";
          }
       }
       return grid;
    }

Esto también es dinámico ya que funcionará para varias filas y columnas. También para múltiples estrellas enel argumento de la matriz anidada Respondido

16 de agosto de 2021 a las 17:59

JasonCodez

JasonCodez

1

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare