Autor Tema: Obtener el casillero opuesto.

0 Usuarios y 2 Visitantes están viendo este tema.

21 Octubre, 2024, 10:31 am
Leído 923 veces

Tachikomaia

  • $$\Large \color{#5b61b3}\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 1,297
  • País: uy
  • Karma: +0/-0
  • Sexo: Masculino
No entiendo por qué me está costando tanto esto.

Supongamos que se tienen casilleros numerados así:
123
456

o puede ser
1234
5678

o más, o sea, el largo por fila y columna varía, pero siempre el largo de fila = el largo de columna.

Bueno, estoy pintando esos casilleros, y quiero que el dibujo sea simétrico (espejo así | ), entonces, cuando llego a un casillero cuya columna está a la derecha de la central, debe obtener el color de su casillero opuesto, por ejemplo en este caso:
123
456
789
cuando vaya a pintar el 3, debo obtener el color del 1.
del 6, el 4.
del 9, el 7.
La fórmula sería casillero-2.

Pero en este otro caso:
1234
5678
para el 4 sería 1
para el 3, 2
para el 8, 5
etc, o sea, entre más casilleros haya por fila, más variada será la diferencia y no logro darme cuenta de cual es la fórmula para obtener el opuesto.

¿Cual es la fórmula? De hecho, creo que hay más de 1, me pueden decir más de una si quieren...

21 Octubre, 2024, 11:32 am
Respuesta #1

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 58,905
  • País: es
  • Karma: +0/-0
Hola

 Si tienes \( n \) filas y  \( m \) columnas:

- la primera fila la tendrás numerada de \( 1 \) a \( m \)
- la segunda de \( m+1 \) a \( 2m \).
- la tercera de \( 2m+1 \) a \( 3m \).

y en general la fila \( i \) desde  \( (i-1)m+1 \) a \( im \).

Pues bien el simétrico del número \( k \) en la fila \( i \) es \( (2i-1)m+1-k \).

Por ejemplo si tienes \( 4 \) filas y \( 5 \) columnas:

1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20

El simétrico del \( 12 \) que está en la fila \( 3 \) es:

\( (2i-1)m+1-k=(2\cdot 3-1)\cdot 5+1-12=26-12=14. \)

Si dado \( k \) quieres saber la fila \( i \) en la que está es:

\( i=Parteentera[(k-1)/m]+1 \)

En este caso:

\( Parteentera[(14-1)/5]+1=2+1=3 \)

Saludos.

21 Octubre, 2024, 04:14 pm
Respuesta #2

Abdulai

  • Moderador Global
  • Mensajes: 3,044
  • País: ar
  • Karma: +0/-0
  • Sexo: Masculino
Luis fue mas rápido, es el mismo razonamiento pero ya lo tenía escrito :)

Si:  \( N_c \): Número de columnas, \( N_f \): Número de filas y \( n_i \): Posición ingresada.
\( floor() \)  redondea al entero menor o igual.

Con esa numeración, el simétrico está en la posición:  \( n_s=1+N_c(1+2*floor((n_i-1)/N_c))-n_i \)


En C, dado que trunca la división entera, es solamente: 
Código: [Seleccionar]
      ns = 1 + ((ni-1)/Nc*2+1)*Nc - ni ;

24 Octubre, 2024, 09:13 am
Respuesta #3

Tachikomaia

  • $$\Large \color{#5b61b3}\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 1,297
  • País: uy
  • Karma: +0/-0
  • Sexo: Masculino
Lo había intentado sin recurrir a filas ni columnas y como luego se me ocurrió una idea seguí intentándolo pero sigo estancado >__< Quisiera la fórmula sin recurrir a filas ni columnas. Les explico lo que tengo:

Se establece la cantidad de columnas y filas, pongamos que 4.

Se calcula la columna central izquierda y la derecha, aquí unos ejemplos:
Si hay 4 columnas: xIDx
Si hay 5: xIxDx
En este programa las tengo numeradas desde 0, las establezco así:
Código: [Seleccionar]
ColumnaCentralIzquierda = Math.floor((CuadraditosPorFila-1)/2);
ColumnaCentralDerecha = Math.ceil((CuadraditosPorFila-1)/2);
Por fila es igual que por columna. No sé si esas fórmulas están bien, tengo una duda más grande.

Los casilleros se van pintando. El 1, el 2, etc, pero cuando la columna de uno no es menor que la derecha central, tiene que captar el color del casillero opuesto, simétrico.
Ahí es donde más me lío. Si tengo:
0123
4567
y se va a pintar el 2, sé que el opuesto es el 1, es decir debo restarle 1, y si es el 4 debo restarle 2. Creo que tiene que ver con cual es el casillero central de la fila, el cual varía según la fila. Lo calculo así:
CuadraditoCentralDeLaFila = (_level0.CuadraditosPorFila*Fila+1+_level0.CuadraditosPorFila*(Fila+1))/2;
De nuevo, no sé si la fórmula está bien, mi principal lío es que no entiendo cómo usar esa variable. Si la distancia entre el casillero a pintar y el centro es X, debo restarle X al centro y me da el jodido casillero opuesto, pero algo estoy haciendo mal:
CuadraditoReflejo = Math.ceil(CuadraditosColocados-CuadraditoCentralDeLaFila);
ESO ¿qué tiene mal? Si es que es eso y no otra cosa, pero eso para empezar.
Como dije, pongamos que tenemos:
0123
4567
Se debe pintar el 2, por lo que debe tomarse el color del 1, para lo cual hay que usar la fórmula que de 1 a partir del 2.
Casillero a pintar - casillero central = 2-1.5 = 0.5 Le pongo ceil y me da 1, bien.
Ahora el 3:
Casillero a pintar - casillero central = 3-1.5 = 1.5 Le pongo ceil y me da 2. Pero tiene que dar 0 ¿es que tengo que hacer 2 restas? Como:
DistanciaAlCentral = Casillero a pintar - central
CasilleroOpuesto = central - distancia
¿No se puede hacer con un *2 o algo así en vez de hacer 2 restas? Tengo un lío bárbaro.

Tal vez es más fácil calcularlo usando columnas y filas pero quiero entender cómo sería de este modo. Les dejo el código resumido y algunos datos, no sé qué está mal.

Primero ocurre esto:
Código: [Seleccionar]
CuadraditosPorFila = 4;
// Columna izquierda más cercana al centro...
// contándolas desde 0:
ColumnaCentralIzquierda = Math.floor((CuadraditosPorFila-1)/2);
// Lo mismo pero derecha:
ColumnaCentralDerecha = Math.ceil((CuadraditosPorFila-1)/2);
MaxCuadradito = CuadraditosPorFila*CuadraditosPorFila;

Ahora ocurre esto:
Código: [Seleccionar]
// Agregar, distribuir cuadraditos y asignarles un color,
// de modo que queden coloreados simétricamente
// (espejo así | ):
CuadraditosColocados = 0;
Columna = 0;
Fila = 0;
CuadraditoCentralDeLaFila = (_level0.CuadraditosPorFila*Fila+1+_level0.CuadraditosPorFila*(Fila+1))/2;
trace ("Asignando colores para un nuevo dibujo");
do {
CuadraditosColocados = CuadraditosColocados+1;
// Si el cuadradito está a la izquierda o en el centro:
if (Columna < _level0.ColumnaCentralDerecha) {
// Asignar color al azar:
} else {
trace ("Tiene simetría el "+CuadraditosColocados);
// Asignar el mismo color que su simétrico:
CuadraditoReflejo = Math.ceil(CuadraditosColocados-CuadraditoCentralDeLaFila);
trace ("Es "+CuadraditoReflejo);
trace ("CuadraditoCentralDeLaFila es "+CuadraditoCentralDeLaFila);
}
Columna++;
if (Columna == _level0.CuadraditosPorFila) {
Columna = 0;
Fila = Fila+1;
CuadraditoCentralDeLaFila = (_level0.CuadraditosPorFila*Fila+1+_level0.CuadraditosPorFila*(Fila+1))/2;
}
} while (CuadraditosColocados<_level0.MaxCuadradito);

Resultado (tiene algo de azar):

Como ven, la parte derecha de cada dibujo (separados con línea verde) es igual a su parte superior pero al revés. O sea, tremendo lío, muchos errores a corregir, pero iré paso a paso.

Esto son informaciones que da el programa:
Citar
Tiene simetría el 3
Es 1
CuadraditoCentralDeLaFila es 2.5
Tiene simetría el 4
Es 2
CuadraditoCentralDeLaFila es 2.5
Tiene simetría el 7
Es 1
CuadraditoCentralDeLaFila es 6.5
Tiene simetría el 8
Es 2
CuadraditoCentralDeLaFila es 6.5
Lo que dice son los cuadraditos que deben captar el color de su opuesto, dice que el 3, el 4, 7 y 8 deben captarlo, eso está bien.
Donde dice "Es" se refiere a cual se consideró el opuesto, lo cual está mal hecho, la conclusión es falsa.
A CuadraditoCentralDeLaFila por lo visto debo restarle 1, lo que pasa que en otro programa tengo las filas contándolas desde 1 y acá es desde 0, por eso me entrevero, en algunos casos conviene de un modo y en otros del otro...

Haré los arreglos que pueda pero lo 1ero que necesito es esa fórmula que marqué con negrita.

24 Octubre, 2024, 09:27 am
Respuesta #4

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 58,905
  • País: es
  • Karma: +0/-0
Hola

Lo había intentado sin recurrir a filas ni columnas y como luego se me ocurrió una idea seguí intentándolo pero sigo estancado >__< Quisiera la fórmula sin recurrir a filas ni columnas. Les explico lo que tengo:

La fórmula que te han dado ya no depende de filas y columnas.

Saludos.

24 Octubre, 2024, 11:34 am
Respuesta #5

Tachikomaia

  • $$\Large \color{#5b61b3}\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 1,297
  • País: uy
  • Karma: +0/-0
  • Sexo: Masculino
m, lo voy a mirar cuando retome esto, pensé que era igual a tu solución porque dijo que el razonamiento era el mismo y habló de columnas.

24 Octubre, 2024, 11:37 am
Respuesta #6

Luis Fuentes

  • el_manco
  • Administrador
  • Mensajes: 58,905
  • País: es
  • Karma: +0/-0
Hola

m, lo voy a mirar cuando retome esto, pensé que era igual a tu solución porque dijo que el razonamiento era el mismo y habló de columnas.

Si; las dos soluciones son esencialmente la misma, aunque el dio sólo la fórmula final y yo en dos pasos.

Hablamos del tamaño de la cuadrícula: cuantas columnas tiene, simplemente. Ese dato hay que usarlo si o si.

Saludos.

25 Octubre, 2024, 01:53 pm
Respuesta #7

Tachikomaia

  • $$\Large \color{#5b61b3}\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 1,297
  • País: uy
  • Karma: +0/-0
  • Sexo: Masculino
Ya entendí  :aplauso:

Copio lo que escribí en mi diario sobre esto:
Citar
- la primera fila la tendrás numerada de 1 a c
- la segunda de c+1 a 2c.
- la tercera de 2c+1 a 3c.
A ver:
1234
5678
9...12
Correcto.
"y en general la fila i desde  (i−1)m+1 a im."
(f-1)*c+1 a f*c
(1-1)*4+1 a 1*4 -> 0+1 a 4
(2-1)*4+1 a 2*4 -> 4+1 a 8
Ok.
"(...) el simétrico del número k en la fila i es (2i−1)m+1−k."
(2*Fila-1)*4+1-K
A ver el 3:
(2*1-1)*4+1-3 = 2 Bien.
A ver el 4, sí, supongo, será 1 menos. M...
(2*1-1)*4+1 = 5 = 1+4
(2*2-1)*4+1 = 13 = 5+8
Se parece a los números que yo obtenía. M...
(f-1)*4+1 + f*4
(1-1)*4+1 + 1*4 = 1+4
(2-1)*4+1 + 2*4 = 5+8
Pero su fórmula es más corta, mejor.

¿Cómo esa 2nda fórmula:
(f-1)*4+1 + f*4
se simplifica, convirtiéndose en la tuya:
(2*f-1)*4+1
?
Ah, como f está sumando 2 veces se multiplica*2... y lo que sería cantidad de cuadraditos por fila multiplica eso ¿es así, no?

La respuesta de Abdulai la miro en otra ocasión.

25 Octubre, 2024, 02:15 pm
Respuesta #8

manooooh

  • $$\Large \color{#9c57a6}\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 4,791
  • País: ar
  • Karma: +1/-0
  • Sexo: Masculino
Hola

¿Cómo esa 2nda fórmula:
(f-1)*4+1 + f*4
se simplifica, convirtiéndose en la tuya:
(2*f-1)*4+1
?
Ah, como f está sumando 2 veces se multiplica*2... y lo que sería cantidad de cuadraditos por fila multiplica eso ¿es así, no?

\begin{align*}
(f-1)*4+1+f*4&=f*4+f*4-1*4+1\\
&=(2*f)*4-1*4+1\\
&=(2*f-1)*4+1.
\end{align*}

Saludos

25 Octubre, 2024, 02:28 pm
Respuesta #9

Tachikomaia

  • $$\Large \color{#5b61b3}\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 1,297
  • País: uy
  • Karma: +0/-0
  • Sexo: Masculino
Funcionó increíblemente sólo por poner la formulita



Código: [Seleccionar]
// Agregar, distribuir cuadraditos y asignarles un color,
// de modo que queden coloreados simétricamente
// (espejo así | ):
CuadraditosColocados = 0;
Columna = 0;
Fila = 0;
trace ("Asignando colores para un nuevo dibujo");
do {
CuadraditosColocados = CuadraditosColocados+1;
attachMovie("mCuadradito", "Cuadradito"+CuadraditosColocados, CuadraditosColocados);
setProperty ("Cuadradito"+CuadraditosColocados, _x, Columna*_level0.LargoDeCuadraditos);
setProperty ("Cuadradito"+CuadraditosColocados, _y, Fila*_level0.LargoDeCuadraditos);
setProperty ("Cuadradito"+CuadraditosColocados, _width, _level0.LargoDeCuadraditos);
setProperty ("Cuadradito"+CuadraditosColocados, _height, _level0.LargoDeCuadraditos);
ColorDeCuadradito = new Color("Cuadradito"+CuadraditosColocados);
// Si el cuadradito está a la izquierda o en el centro:
if (Columna < _level0.ColumnaCentralDerecha) {
// Asignar color al azar:
ColorDeCuadradito.setRGB(_level0.PosiblesColores[random(_level0.PosiblesColores.length)]);
// Incrementar el contador de cuadraditos de ese color:
Resumen = "Color"+ColorDeCuadradito;
set(Resumen, eval(Resumen)+1);
} else {
trace ("Tiene simetría el "+CuadraditosColocados);
// Asignar el mismo color que su simétrico:
CuadraditoReflejo = (2*(Fila+1)-1)*_level0.CuadraditosPorFila+1-CuadraditosColocados;
ColoraReflejar = new Color("Cuadradito"+CuadraditoReflejo);
ColorDeCuadradito.setRGB(ColoraReflejar.getRGB());
}
Columna++;
if (Columna == _level0.CuadraditosPorFila) {
Columna = 0;
Fila = Fila+1;
CuadraditoCentralDeLaFila = (_level0.CuadraditosPorFila*Fila+1+_level0.CuadraditosPorFila*(Fila+1))/2;
}
} while (CuadraditosColocados<_level0.MaxCuadradito);

Esto:
CuadraditoReflejo = (2*(Fila+1)-1)*_level0.CuadraditosPorFila+1-CuadraditosColocados;

No había tanto error en mi código como pensé, y los cuadraditos (o casillerosç9 sí están nombrados contando desde 1, lo que está contado desde 0 son las filas y columnas, pero ajusté la fórmula y quedó bien O_O