[ Foro de Pascal ]

Array de arrays

24-Oct-2014 03:05
Invitado (Martin)
14 Respuestas

Hola a todos.
Mi duda es la siguiente:
tengo un array de arrays (una matriz queda), y quiero  girarla hacia la izquierda de manera que quede asi.

1    2   3   4                          4  8  12 16
5    6   7   8  =========    3  7   11 15
9  10  11 12                        2  6   10  14
13 14 15 16                        1  5   9    13

Seria bueno si me pudieran dar un ejemplo en codigo para que la matriz se de vuelta y se pueda seguir girando asi , como un proceso o algo. Gracias.  


24-Oct-2014 15:41
Nacho Cabanes (+30)

Según lo programes, eso no es un array de arrays, sino un array bidimensional.

Para ver cómo programarlo, piensa simplemente lo que ocurre con los índices de los pares de elementos que intercambias:

- El (fila=1, columna=1) pasa a recibir lo que contenía el (fila=1, columna=n)
- El (fila=1, columna=2) pasa a recibir lo que contenía el (fila=2, columna=n)
...
- El (fila=2, columna=1) pasa a recibir lo que contenía el (fila=1, columna=n-1)
- El (fila=2, columna=2) pasa a recibir lo que contenía el (fila=2, columna=n-1)
...

Si lo miras con detenimiento, no te costará ver cual es la relación entre la posición inicial y la posición final.


24-Oct-2014 18:01
Invitado (Martin)

Si, tengo la idea y pense varias formas de implementarlo, pero no queda como lo quiero hacer. Estoy intentando pasar la primer fila al lugar de la primer columna,  y asi, pero el codigo no lo hace y no me doy cuenta que hago mal. Seguramente este haciendolo mal algo con los for. Dejo el codigo por las dudas.

 
procedure Giro(var tablero: TipoTablero);
var a: integer;
var i:integer;
var j:integer;
var fila:TipoFila;
var tablero2:TipoTablero;
 
 
begin
for a:=1 to Maxdo
	begin
		for i:=1 to Max do
		begin
			for j:=1 to Max do
			begin
					fila[i]:=tablero[a,j];
 
			end;	
 
		end;
 
tablero2[i,a]:=fila[i];
 
for i:=Max downto 1 do
	begin
        tablero:=tablero2;
	 end;
 
               end;
end;
 





24-Oct-2014 23:33
Luis Torres (+12)

Tú pretendes que en el array unidimensional "fila" se almacenen los valores de cada fila del array bidimensional "tablero"; pero el código no está haciendo eso, sino asignarle a "fila" varios valores para un solo índice de "fila", al final quedará asignado el último valor de "tablero". Esa parte del código debes revisarla con más detenimiento para que veas lo que en realidad está haciendo y buscar la solución.

 
for i:=1 to Max do 
  begin 
    for j:=1 to Max do 
      begin 
        fila[i]:=tablero[a,j];  (* Aquí veo un error *)
     end;	
end; 
 


De todas maneras, esperemos el comentario del prof. Nacho Cabanes.

Saludos.


25-Oct-2014 04:58
Invitado (Martin)

Lo hice de una forma bastante simple, gira a la derecha pero es lo mismo, solo cambio la cantidad de veces que giro el tablero y listo. Dejo el código por si a alguien le sirve.

 
procedure GirarDerecha(var tablero: TipoTablero);
 
var i:integer;
var j:integer;
var tablero2: TipoTablero;
 
 
begin 
for i:=1 to Max do
	begin
		for j:=1 to Max do 
			begin
				tablero2[i,j] := tablero[Max-(j-1),i];
end;
 
	end;
	for i:=1 to Max do
	begin
	for j:=1 to Max do
	begin
		tablero[i,j]:=tablero2[i,j];
	end;
	end;
	end;
 


Ahora tengo un problema en las veces que le aplico el proceso a las filas, porque se me pasa de cantidad. Por ejemplo, si tengo que sumar dos consecutivos una sola vez, lo sumo mas veces, es un proceso que tengo, y no se aplicarlo bien.

Ejemplo [4,5,4,7]======[9,0,4,7]
    pero yo aplico mal y queda [9,0,11,0].

Esto no lo vi mucho pero no parece difícil, si lo arreglo lo subo por si le es útil a alguien más.


25-Oct-2014 15:00
Luis Torres (+12)

Resolver esta parte es cuestión de jugar con los índices del array. Para cada fila, sumo la columna 1 con la columna 2, el resultado de la suma lo asigno a la columna 1 y, en la columna 2 asigno el valor cero.

Saludos.


25-Oct-2014 17:23
Invitado (Martin)

Si, el proceso que hice esta bien, solo que hago mal el numero de veces que se aplica, entonces se pasa, pero ya lo voy a solucionar.


25-Oct-2014 19:23
luis lagaxio

buenas, tambien estoy con arrays de arrays, pero tengo un problema mucho mas básico... tengo que crear una funcion booleana que me diga si la matriz no tiene ceros en ningun elemento. Y escribe la función, pero no se porque razon al ejecutarla en linea de comandos se queda esperando una orden y no me devuelve nada...

esto es el codigo que escribi... gracias!

 
program p2018;
 
const
MAXTablero=4;
MAXValor=2048;
valortab=2;
 
 
type  
RangoIndice= 1 .. MAXTablero;
TipoValor = 0 .. MAXValor; 
TipoFila = array [RangoIndice] of TipoValor;
TipoTablero = array [RangoIndice] of TipoFila;
 
var
tablero: TipoTablero;
 
{procedimiento para iniciar el tablero}
procedure IniciarTablero(var tablero: TipoTablero);
var i,j,cont:integer;
begin
	cont:=1;
	for i:=1 to MAXTablero do
	  begin
	  for j:=1 to MAXTablero do
		begin
		tablero[i,j]:=cont;
		cont:=cont+1;
		end;
		tablero[1,1]:=0;
	  end;	
 
 
 
end;
 
 
 
{procedimiento mostrar tablero}
procedure MostrarTablero(tablero: TipoTablero);
var i,j:integer;
begin
 
	for i:=1 to MAXTablero do begin
		for j:=1 to MAXTablero do
		write (tablero[i,j],' ');
		writeln;
	end;
 
 
end;
 
function TieneCeros(tablero:TipoTablero): boolean;
var i,j:integer;
 
	begin
	j:=1;
	for i:=1 to MAXTablero do 
		while (j<=MAXTablero) and (tablero[i,j]<>0) do
		begin
		j:=i+1;
	TieneCeros:=j<=MAXTablero;
		end;
 
	end;
 
 
 
 
begin
IniciarTablero (tablero);
MostrarTablero (tablero);
 
if TieneCeros(tablero) then
begin
writeLn ('el tablero tiene al menos un cero');
end
else
writeln ('el tablero no tiene ningun cero')
 
end.
 




25-Oct-2014 19:39
Martin Rodriguez

A mi me paso con los while y preferi ponerle for, se quedaba colgado e incluso me trababa la consola.


Fing?


25-Oct-2014 19:49
luis lagaxio

ya lo solucioné,

esta es la funcion que me anduvo...

 
function TieneCeros(tablero:TipoTablero): boolean;
var i,j:integer;
	exito: boolean;	
 
	begin
	exito:=false;
	for i:=1 to MAXTablero do 
		for j:=1 to MAXTablero do
			if (tablero[i,j]=0) then
			exito:=true
			else
	TieneCeros:=exito;
		end;
 


ya voy a volver con otras preguntas


25-Oct-2014 19:52
luis lagaxio

ja, si fing... pero para completar soy economista y estoy haciendo materias para poder hacer un posgrado... o sea, tengo 35 pirulos, hijo, laburo, etc... me pedi un par de dias para la tarea, pero estoy en el horno (como veras), ahora toca lo de ver que todos sean distintos entre si... luego ver lo de contar la cantidad de fusiones y el mover izquierda que no tengo ni idea...


25-Oct-2014 19:59
Martin Rodriguez

Te aconsejo que hagas el de mover a la izquierda, despues en terminar juego lo aplicas a las filas  (sin modificar el tablero original) y despues miras si tiene ceros, si no se movio a la izquierda  y esta lleno se supone que no tiene 0.


25-Oct-2014 20:20
luis lagaxio

gracias por el consejo,

hasta ahora logre poco, pero anda (jaja):

1)escribí la función de iniciar el tablero (lleno de 0 y con 2 en dos lugares aleatorios).
2)escribí el fin del juego (devuelve true si el tablero ya no tiene ceros y ningún elemento es fusionable con el de al lado), y parece que anda... si queres te lo paso.

decís que ahora me meta con lo de moverizquierdafila?? cualquiera de esos dos (contar la cantidad de fusiones y realizar el movimiento y la fusión) me tienen agarrado de los pelos...

el transponer el tablero lo tenía bastante avanzado (y lo verifique con tu codigo de mas arriba je)

gracias de verdad... creo que hasta el lunes no paro!


26-Oct-2014 02:05
luis lagaxio

lo prometido es deuda... acá estoy de nuevo:

logré hacer el procedimiento para desplazar los elementos distintos de cero hacia la izquierda y luego sumar aquellos que son iguales, solo una vez e insertando un cero en la posición del segundo elemento sumado...

el problema es que no puedo pasarlo a una matriz... el tablero es un array de array y tengo que pasarle las filas del tablero para que haga el movimiento y fusión hacia la izquierda para todas las filas...

este es el codigo del movimiento y fusion en el array... cualquier ayuda sirve.

 
procedure MoverIzquierdaFila(var arr: TipoFila); 
	{procedimiento que las mueve hacia la izquierda}
	procedure MoverIzquierda(var arr:TipoFila);
 
		{procedimiento para intercambiar celdas}
		procedure Intercambiar(var a,b:integer);
		var 
		aux: integer;
		begin
 
		aux:=a;
		a:=b;
		b:=aux;
		end;
 
 
	var
	i,k:integer;
	begin
	k:=1;
	repeat
	for i:=1 to (MAXTablero-1) do
 
	if (arr[i]=0) then 
	Intercambiar(arr[i],arr[i+1])
	else
	k:=k+1;
	until k>=MAXTablero;
	end;
 
var 
k,i:integer;
 
begin
MoverIzquierda (arr);
k:=1;
repeat
for i:=1 to (MAXTablero-1) do 
	begin
	if arr[i]=arr[i+1] then
	begin
	arr[i]:=arr[i] + arr[i+1];
	arr[i+1]:=0;
	end
	else
	k:=k+1;
end
until arr[k]=0;
 
end;
 






28-Oct-2014 00:15
Nacho Cabanes (+30)

Entonces... ¿ahora mismo con qué problema te encuentras?  ¿Hacerlo con un array de arrays en vez de con array bidimensional?






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)