Disculpa la demora, a veces me canso de estas cosas o no tengo ganas en el momento, queda para mañana y así, qué sé yo.
Algo que debo aclararte es que si bien me será útil obtener condiciones random, también voy a necesitar que se generen listas (eso cuando necesito poner una condición en un lado y no sé cual sería; equivale a usar fuerza bruta en la que el candidato no sería un número sino una condición). Olvidé eso. Listas es como esto:
https://www.geeksforgeeks.org/possible-strings-length-can-formed-given-string/Bien... ahora te has expresado mejor... Así que sí, si sirvió que te explicaras.
Sigo teniendo mis dudas.
De entrada te diré que ya te puse en otro hilo que abriste un pseudocódigo, pero nuevamente lo pisaste como una alfombra, sin saber que lo estabas pisando...
He revisado este tema
https://foro.elhacker.net/programacion_general/duda_sobre_expresiones_condicionales-t485203.10.html2 veces (la pág 3 sólo 1 vez) pero no sé a qué te refieres. Tal vez no pusiste el pseudo sino que mencionaste un algoritmo. Eso no lo revisé. No sé. Recuerdo que alguien me dijo una función, quizá tú, pero no lo encontré.
Lo importante de mis preguntas eran dos o tres cosas:
- 1º para que las necesitabas... esto es, solo querías imprimrlas o bien al final tendrías que aplicarlas. Contestado, al final acabarás aplicándolas...
Pero es lo de menos. Lo importante es que se impriman las que necesito y las pueda copiar. Lo demás es para más adelante. Si a copiarlas y pegarlas le quieres llamar "aplicarlas", bueno, también es eso, por ahora.
En fin, yo te sigo la corriente, pero me parece que en este sentido complicaste el tema innecesariamente.
- 2º cuánto de largas podrían llegar a ser tales expresiones?
Depende de cual sea el problema más complejo que yo logre resolver. En teoría, lo que el programa aguante, no sé, nunca me pasó que se trancara por exceso de información (sí por loops o en Clipper porque el programa al compilarlo pesaba mucho, pero era otra cosa, un juego).
aveces, si algo es breve, se resuelve más pronto a mano que generando un algoritmo efectivo.
Bueno, ya te expliqué que a la larga me convendría el code.
También porque si la cantidad es enorme, aplicarlas (o solo escribirlas a disco), podría llegar a tener tantas combinaciones que ni el disco tendría espacio suficiente, ni tu vida para verlas aparecer todas...
Estoy muy lejos de querer guardar una lista (sólo en la pantalla del output...) y no tengo interés en verlas todas.
- 3º Si no se iban a aplicar no tiene importancia ciertos detalles, si se van a aplicar, en cambio son otros detalles los que no importan.
No imagino del todo de qué hablas. Si me dices un poco más, gracias.
- 4º El lenguaje en que vayas a programar, generalmente no importa... peor a este caso, creo que sí, porque desconozco realmente hasta que punto 'tu lenguaje' tenga las cosas encesarias o las facilidades para poder programarlas adecuadamente.
En general siempre tuve todo lo que necesité. Lo que no tiene por ejemplo es "figuras" para hacer las detecciones de colisiones más exactas. Acá todo es rectangular o cuadrado. Tampoco tiene, creo, la función para obtener el resto de una división, pero se puede hacer. En fin, no sé qué decirte.
se le puede sumar el problema del rendimiento...
Tiene algunos, pero es largo de explicar y no viene mucho al caso (los problemas que yo conozco, otros puede que sí).
y siempre podrás adquieri un nuevo equipo, añadir memoria
He tenido problemas al hacer juegos, pero en esto no creo. Es sólo texto...
No tengo dinero ni mucho interés en toquetear mi machine.
o mejor cambiar de lenguaje.
Difícil pero supongo que no imposible.
Al caso
Al fin.
gran parte de lo que necesitas encaja de pleno en la teoría de compiladores, pero como ya has demostrado tu nivel, será harto complejo explicarte como abordarle de la forma más óptima.
Alguien me recomendó que haga "el árbol" o algo así, pero leí en wikipedia y no entendí. Sí recuerdo que hablaba de compiladores.
1 - Una forma sencilla de abordarlo y sin requerir paréntesis, es que generes dos operandos y los calcules, el resultado es un operando listo para ser operado con el siguiente operando generado.
Esta es la forma en que funciona una calculadora de mano simple.
A = A op B
A = A op C
A = A op D
'A', puede entenderse como 'acumulador', 'resultado' en una calculadora.
Y 'op' como el operando concreto que a cada momento se precise usar. El orden de ejecución será el que uno precise... aunque yo pongo B,C,D podría ser alterado
A = A op C
A = A op B
A = A op D
No estoy entendiendo.
Mira, he hecho este código:
SC1P1 = 1;
SC1P2 = 1;
SC1P3 = 0;
Op1 = " < ";
Op2 = " <= ";
Op3 = " == ";
Op4 = " != ";
Op5 = " > ";
Op6 = " => ";
function PassorPrint () {
if (SC1P1<SC1P3) {
if (SC1P2<5) {
trace ("V"+SC1P1+eval("Op"+SC1P2)+"V"+SC1P3);
} else {
trace ("V"+SC1P3+eval("Op"+(SC1P2-4))+"V"+SC1P1);
}
}
}
do {
if (SC1P3<2) {
SC1P3 = SC1P3+1;
PassorPrint();
} else {
SC1P3 = SC1P1;
if (SC1P2<6) {
SC1P2 = SC1P2+1;
PassorPrint();
} else {
SC1P2 = 1;
SC1P1 = SC1P1+1;
PassorPrint();
}
}
} while (SC1P1<2);
Este es el output:
V1 < V2
V1 <= V2
V1 == V2
V1 != V2
V2 < V1
V2 <= V1
Sólo eso, sí. Tendría que hacer un código que genere condiciones compuestas por más subcondiciones (SC), estoy en eso.
¿Ese output tiene que ver con lo que me estás diciendo? Cuando haya más SC tendré que ponerles paréntesis. Me dices que "sin usar paréntesis" entonces m...
2 - Dicho de otro modo habrá tantos modos de órdenes (de ordenar los operandos) de ser ejecutado como el factorial de operandos que haya. El factorial es 1*2*3*4*5 es decir 5 variables pueden ordenarse de 120 maneras distintas, 6 de 720 (1*2*·*4*5*6*7), etc....
Bien...
3 - Si usamos un solo operador son solo esas 120 expresiones distintas. Pero, nuevamente, aclaramos que la cantidad d eoperadores para n operandos siempre será n-1 operadores (el principio de la valla, cuantos postes se requierne para tender una alamabrada? 2 postes para una alambrada, y luego un poste por cada nueva alambrada, luego siempre hace falta 1 poste más que alambradas).
Ok...
...con 5 operandos, en medio habrá 4 operadores. Nuevamente estos operadores pueden ser ordenados de distintas formas... sigue la misma regla del factorial: 1*2*3*4 = 24 formas de ordenar los 4 operadores. Combinándolas con las 120 combinaciones posibles de operandos tendrás 120*24 = 2.880 expresiones.
No sé si te estoy siguiendo, pero una cosa son lo operadores de comparación y otros los que relacionan (and y or). xor puede ser también, aún no lo estudié.
4 - En este punto hay que observar que es evidente que habrá expresiones equivalentes "A = (B + C)" es equivalente a "A = (C + B)" (solo hemos cambiado el orden de los operandos, pero el operador no altera el producto.
m...... Probablemente no lo había aclarado pero, por ahora no quiero que haya operaciones en las condiciones, sólo Variable, comparador, variable, relacionador, etc.
No sé si lo que estás haciendo contradice eso. Si estás planeando poner operaciones me serviría, pero comencemos por lo sencillo.
5 - Sin embargo dada la velocidad de cálculo, es preferible recalcularlas que intentar buscarlas para desecharlas... es menos costoso
No entendí.
(creo que estamos hablando de operaciones buleanas... and or, xor... era así, no?).
Así es.
Natualmente optar por esta solución (que gana en velocidad y ahorra en simpleza), a cambio dará redundancia de resultados (saldrán más resultados 'correctos' pero que son equivalentes).
Quiero evitar redundancias...
6 - Bien, de hacer un filtrado de redundancia de expresiones equivalentes, es preferible hacerlo ahora, porque la cantidad de expresiones 'correctas' entre las que buscar equivalentes, será considerablemente menor que al comienzo con todas las combinaciones posibles. Es decir supongamos que de entre esas 2880 expresiones resultantes, 60 dan una respuesta 'correcta', buscar entre ellas las equivalentes entre sí, es considerablemente más breve (en tiempo de cálculo que hacerlo sobre las 2880.
¿Puedes encontrarlas sin filtro? m...
7a - No estamos considerando paréntesis de momento. Y no lo haremos hasta que quede claro todo lo previo y considerar si de verdad los vas a necesitar.
Phew.
Esto es si hay problemas de rendimeinto, por la complejidad de las expresiones que nos lleve a reducir de entrada las expresiones únicas para ejecutar solo esas... mientras no se demuestre que esto sea más rápido que calcularlas, no veo la necesidad de introducir paréntesis...
¿?
7b - Porque como ya te he dicho antes, si vas operando sobre la marcha y consideras las combinatoria de los operandos y de los operadores, no necesitas paréntesis porque acabas por ejecutar todas las expresiones posibles.
Se supone que lo has entendido, pero... necesito generar las expresiones posibles. ¿Cómo, sin paréntesis, podrías generar esto "(V1<V2 o V1<V3) y V1<V4"? Tú mismo me decías en otro tema que no se puede vivir sin paréntesis. En fin, tú sabrás lo que haces...
Y de momento lo dejo aquí esperando haberme hecho entender... y si es conforme que haya entendido correctamente tus necesidades dada tu explicación previa de lo que haces (exiges que haga el programa).
¡Pero cuánto protocolo hombre!
Y con lo que me digas si falta algo lo vemos y si no avanzamos derivando por un lado o por otro... Esto es, he puesto 7 puntos espero que todos y cada uno de ellos te hayan quedado claros, por eso los he marcado, para que no lo pises como si fueran invisibles.
No los memoricé pero sí los leí y opiné como has visto, pero me parece que te complicas mucho. De momento me serviría que hagas un código como el que yo hice, pero que en vez de producir condiciones de 1 subcondicion, sean de 2, o sea: V op V rel V op V
El output debería ser algo así:
V1 < V2 && V1 < V3
V1 < V2 && V1 <= V3
V1 < V2 && V1 == V3
V1 < V2 && V1 != V3
V1 < V2 && V3 < V1
V1 < V2 && V3 <= V1
V1 < V2 && V2 < V3
...
V1 < V2 && V4 < V3
Nota: V4 no es un error. Pero sólo hay V4 si en la misma condición hay otras 3.
...
V1 < V2 or V1 < V3
...
V1 < V2 or V4 < V3
V1 < V3 or V1 < V2 <-- Esta creo que es repetida, debe evitarse.
Por ahora es lo que intento hacer.
Tengo este código que sería un intermedio entre el código que antes te puse, y el que quiero hacer.
// Partes de la subcond.
SC1P1 = 1;
SC1P2 = 1;
SC1P3 = 0;
// Cosas para evitar ifs.
Op1 = " < ";
Op2 = " <= ";
Op3 = " == ";
Op4 = " != ";
Op5 = " > ";
Op6 = " => ";
CursorMax1 = 2;
CursorMax2 = 6;
CursorMax3 = 2;
Reset2 = 1;
Reset3 = SC1P1;
// Otras cosas.
Cursor = 3;
function PassorPrint () {
if (SC1P1<SC1P3) {
if (SC1P2<5) {
trace ("V"+SC1P1+eval("Op"+SC1P2)+"V"+SC1P3);
} else {
trace ("V"+SC1P3+eval("Op"+(SC1P2-4))+"V"+SC1P1);
}
} else {
Reset3 = SC1P1;
}
Cursor = 3;
}
do {
if (eval("SC1P"+Cursor)<eval("CursorMax"+Cursor)) {
set ("SC1P"+Cursor, eval("SC1P"+Cursor)+1);
PassorPrint();
} else {
set ("SC1P"+Cursor, eval("Reset"+Cursor));
Cursor = Cursor-1;
}
} while (SC1P1<2);
Si lo consideras confuso e ineficiente, concuerdo xD Pero por ahora es lo que tengo.
Gracias.