Me dieron el siguiente problema en una entrevista (que ya no pude resolver, sin tratar de engañarme): El juego comienza con un número entero positivo . (Por ejemplo, A 0 = 1234. ) Este número se convierte en representación binaria, y N es el número de bits establecido en 1 . (Por ejemplo, A 0 = b 100 1101 0010 , N = 5. )
El jugador 1 elige un número menor que A 0 . B 0 debe tener un solo bit establecido en 1. (Ej. B 0 = b 10 0000 0000 = 512. ) Sea A 1 = A 0 - B 0 . (Por ejemplo, A 1 = 1234 - 512 = 722 = b 10 1101 0010. ) Un movimiento es válido si B 0satisface las restricciones anteriores, y si el número de bits puestos en sigue siendo igual a N .
El jugador 2 continúa desde eligiendo un B 1 válido , luego el jugador 1 continúa desde A 2 , y así sucesivamente. Un jugador pierde si no le quedan movimientos válidos.
Asumiendo que ambos jugadores juegan de manera óptima, determine al jugador ganador usando un método razonablemente eficiente. (En mi definición del problema, las restricciones en esto fueron que el programa debe ser capaz de entregar una solución para unos pocos millones de números de entrada que se ajustan a un entero de 32 bits con signo). Es decir, la solución no necesita ser Totalmente analítico.
Mi interés personal aquí es determinar si la expectativa de que yo haya encontrado e implementado la solución correcta sin ningún comentario sobre la corrección en los 120 minutos que me dieron fue razonable; o si esta fue una de esas preguntas de "veamos si han visto este rompecabezas antes".
Fallé porque elegí implementar lo que parecía una estrategia razonable, que me dio resultados correctos para los pocos casos de prueba que me dieron por adelantado, perdí demasiado tiempo haciendo que esto corriera rápido y terminé entregando incorrectos salida completa cuando se me acabó el tiempo.
En retrospectiva, debería haber implementado una búsqueda de fuerza bruta y memorizar soluciones parciales para números iniciales pequeños, pero en retrospectiva siempre es 20/20. Sin embargo, tengo curiosidad si hay un enfoque común diferente que me eludió como un flunkee.
fuente
Respuestas:
Entonces, el único factor determinante en un juego es cuántos intercambios se necesitan para llegar al estado en el que todos están a la derecha, y no hay una estrategia de ganar o perder. La paridad del número de swaps que toma es el único factor determinante.
total
fuente
Una forma de resolver este problema es la siguiente:
Encuentre la solución para algunos valores simples utilizando el enfoque de "fuerza bruta memorizada" que sugiere.
Adivina la respuesta (qué posiciones están ganando y cuáles están perdiendo).
Intenta demostrar tu respuesta. Si tienes éxito, genial. De lo contrario, intente encontrar un contraejemplo y úselo para adivinar otra respuesta. Aquí podría ser útil resolver algunos casos más.
Es realmente difícil decir cuánto tiempo lleva eso. Sin embargo, en las entrevistas no necesariamente se espera que encuentre la solución. Por el contrario, los entrevistadores quieren saber cómo te acercaste a resolver el problema y qué progreso lograste hacer.
fuente
Observe en la respuesta de @ orlp que queremos la paridad de la suma de los desplazamientos desde la posición inicial hasta la posición final. Anotemos esto:
Entonces queremos
La primera parte es solo la paridad del número de bits en las posiciones impares. Puede enmascarar eso tomando el número entero máximo sin signo, dividiendo entre 0b11 y negando.
La segunda parte es la paridad de la mitad del número de bits
x
.bitcount
puede usar lapopcnt
instrucción de hardware o puede implementarse manualmente utilizando que solo se necesita el último o el penúltimo bit, con reducciones rápidas como esta .fuente