Nota : Según el consenso sobre Meta , las preguntas de redacción de desafíos están en el tema aquí.
A la luz de esta "cosa que debe evitarse al escribir desafíos" , comencé a pensar en los desafíos que implican la generación aleatoria de ciertos tipos de objetos.
A veces sucede que quiero publicar un desafío de código de golf que implica generar aleatoriamente un foo, donde
- es muy fácil verificar si una cosa determinada es un tonto, y
- es un poco más difícil generar rápidamente un foo aleatorio de "buena calidad".
Como ejemplo, un foo podría ser una matriz binaria donde no hay segmentos de 4 bits iguales en ninguna dirección. Es fácil verificar si una matriz binaria dada es un foo, pero generar un foo aleatorio con una distribución bien distribuida parece requerir un algoritmo de retroceso o algo similar.
De todos modos, ahora tendré que especificar objetivamente qué califica como un foo aleatorio, y me gustaría que sea "impredecible" en el sentido intuitivo de que cuando ejecuto el programa varias veces, los resultados siempre se ven diferentes. El enfoque más restrictivo es exigir que la salida sea uniformemente aleatoria: todos los foos válidos tienen la misma probabilidad de ser generados. Esto suele ser demasiado restrictivo, porque no tengo idea de cómo hacerlo, salvo para generar todos los foos válidos, eliminar duplicados y elegir uno, lo cual es aburrido y lento.
Mi siguiente idea es exigir que todos los foos válidos tengan una probabilidad positiva de ser generados. Sin embargo, esto significa que el siguiente enfoque es válido: generar una cosa aleatoria similar a un foo (en nuestro ejemplo, una matriz binaria aleatoria), si es un foo, devuélvala; de lo contrario, devuelva un foo codificado (por ejemplo, la matriz de identidad ) Esto también es algo aburrido, ya que básicamente es solo un reconocedor de foos agregado a un generador de matriz aleatorio.
¿Podría haber una buena definición general para un foo impredecible al azar?
TL; DR
¿Hay una buena manera de especificar un objeto "impredecible" generado aleatoriamente que no arregle la distribución pero desaliente la codificación rígida?
Respuestas:
Devuelve mil foos diferentes
Esto hace que sea imposible devolver valores codificados y tener un golf medio decente. Sin embargo, un generador de foo legítimo tiene una pequeña posibilidad de generar foos duplicados a menos que realmente los esté verificando. Para eliminar la carga de la verificación, una tasa de falla comprobada empíricamente, digamos 10%, podría especificarse como aceptable.
Tenga en cuenta la paradoja del cumpleaños , que la probabilidad de duplicados puede ser mayor de lo que piensa. Si solo hay un millón de posibles foos, mil foos aleatorios tendrán una probabilidad de aproximadamente 0.6 de que haya un duplicado allí en alguna parte, y eso supone que la generación de foos es completamente uniforme. Si esto pudiera ser un problema, requiere decir 900 foos únicos por cada 1000 generados, lo cual es mucho más generoso para un generador de foo genuino pero aún no es práctico para la codificación rígida.
Esto también te permite generar repetidamente cosas parecidas a las de los foo y comprobar la locura hasta que te pongan foos. Creo que esta es una solución válida, pero si no te gusta:
Hazlo rápido
Las posibilidades de que una cosa parecida a un foo sea aleatoria son probablemente bastante bajas, por lo que especificar un límite de tiempo probablemente forzará un intento genuino de generación de foo.
Para adaptarse a las diferencias de velocidad entre diferentes idiomas, es posible que desee tener límites de tiempo diferentes según el idioma como Hackerrank: https://www.hackerrank.com/environment . Sin embargo, si especifica foos lo suficientemente grandes, la probabilidad de que las cosas parecidas a foo sean aleatorias podría ser realmente baja, por lo que una regla de "antes de la muerte por calor del Universo" podría ser suficiente.
fuente
No pretendo tener la solución definitiva al problema (o que esta lista sea exhaustiva), pero quiero esbozar algunos enfoques posibles que se me ocurren y por qué funcionarían o no. Tampoco abordaré cuestiones tangenciales como si el uso de la marca de tiempo actual como fuente de aleatoriedad es lo suficientemente "impredecible" y cómo aplicar ciertas propiedades de la distribución de probabilidad: me concentraré en evitar soluciones que usen codificación rígida.
No es una solución: no permitir la codificación explícitamente
Esta es una mala idea. Es un requisito no observable (lo que significa que no puede determinar si se cumple simplemente ejecutando el programa), que se desaconseja firmemente en PPCG y puede ser absolutamente imposible si se ejecuta el programa en cualquier otra plataforma, donde las presentaciones se verifican en un manera automatizada El problema con un requisito como este es que tendría que comenzar por encontrar una definición objetiva para "codificación rígida". En general, si intentas esto, solo empeorarás las cosas.
Hacer que la codificación no sea factible
Si no puede rechazarlo por completo, pero no desea que las personas lo usen, puede intentar diseñar el desafío de manera que la codificación rígida simplemente no sea un enfoque competitivo. Esto es posible si los objetos que deberían generarse son lo suficientemente grandes e incompresibles como para poner un ejemplo en el código requeriría muchos más bytes que escribir un algoritmo que genere soluciones válidas al azar. En su ejemplo específico, ese no es el caso, por supuesto, porque las matrices de identidad son válidas y generalmente son fáciles de generar, pero para otros problemas, ese podría no ser el caso. Si los objetos de destino son lo suficientemente irregulares, solo es necesario que sean de gran tamaño, lo que probablemente no afectará el recuento de bytes de un algoritmo real, pero explotará la parte codificada.
Parametrizar la salida
A menudo, estos problemas vienen con uno o más parámetros naturales, como el tamaño de la matriz en su ejemplo. Si es así, hacer que ese parámetro sea una entrada puede ser suficiente para hacer imposible la codificación rígida o al menos poco práctica. En algunos casos, puede ser fácil codificar una solución específica para un valor de parámetro dado que se ha encontrado manualmente o mediante una búsqueda exhaustiva, pero tal vez no haya una forma cerrada simple para una instancia de estas soluciones en general, por lo que no es posible generar un valor predeterminado para entradas arbitrarias fácilmente. Nuevamente, este no es el caso para el ejemplo que menciona, porque la matriz de identidad funciona en cualquier tamaño, pero es una solución óptima para este problema relacionadogeneralmente es muy irregular, por lo que no es posible tener un valor predeterminado sin buscar activamente valores válidos de todos modos. Puede combinar esto con un límite de tiempo para evitar una búsqueda de fuerza bruta para un valor predeterminado.
Poner alguna restricción en la distribución de probabilidad
Si usted está dispuesto a renunciar a un completo distribución de probabilidad sin restricciones, puede poner algunas restricciones sobre el mismo, que todavía dan que responden mucha libertad en la elección de su distribución, sino que hacen difícil la codificación de una difícil o imposible:
El problema principal con estos enfoques es que es mucho más difícil razonar sobre ellos, es difícil demostrar que las respuestas son correctas y verificar experimentalmente la exactitud puede ser imposible para grandes espacios de salida. Aún así, proporcionan un requisito principalmente observable para el programa que puede hacer imposible la codificación rígida.
Es posible que estos enfoques también necesiten un límite de tiempo, porque una forma de aumentar la probabilidad de los valores no predeterminados sería intentar encontrar un valor aleatorio varias veces antes de volver al valor predeterminado.
fuente