Tarea:
Su programa recibe una fracción simple positiva y adecuada en el formato .<numerator>/<denominator>
Para esta entrada, debe encontrar dos fracciones.
- Una fracción que es menor que la entrada.
- Una fracción que es mayor que la entrada.
Ambas fracciones deben tener un denominador más bajo que la entrada. De todas las fracciones posibles, deberían tener la menor diferencia con la entrada.
Salida:
La salida de su programa debe ser:
- Una fracción que es más pequeña que la entrada, en el formato
<numerator>/<denominator>
. - Seguido de un carácter de espacio (código ASCII 32).
- Seguido de una fracción que es mayor que la entrada, en el formato
<numerator>/<denominator>
.
Como sigue:
«fraction that is < input» «fraction that is > input»
Reglas:
- Todas las fracciones producidas deben estar en los términos más bajos .
- Todas las fracciones producidas deben ser fracciones apropiadas.
- Si no hay posibles fracciones apropiadas permitidas por las reglas, debe generar
0
una entrada en lugar de una fracción <entrada, y en1
lugar de una fracción> entrada. - Puede elegir si desea recibir la fracción como un argumento de línea de comandos (por ejemplo
yourprogram.exe 2/5
) o solicitar la entrada del usuario. - Puede suponer que su programa no recibirá entradas no válidas.
- El código más corto (en bytes, en cualquier idioma) gana.
Cualquier argumento de línea de comandos no estándar (argumentos que normalmente no se requieren para ejecutar un script) cuentan para el recuento total de caracteres.
Lo que su programa no debe hacer:
- Depende de cualquier recurso externo.
- Depende de tener un nombre de archivo específico.
- Salida de cualquier cosa que no sea la salida requerida.
- Tardar excepcionalmente en correr. Si su programa dura más de un minuto para fracciones con un numerador y un denominador de 6 dígitos (por ejemplo
179565/987657
) en la computadora de un usuario doméstico promedio, no es válido. - Fracciones de salida con
0
como denominador. No puedes dividir por cero. - Fracciones de salida con
0
el numerador. Su programa debe generar en0
lugar de una fracción. - Reducir una fracción ingresada. Si la fracción dada como entrada es reducible, debe usar la fracción tal como se ingresa.
- Su programa no debe estar escrito en un lenguaje de programación para el que no existía un compilador / intérprete disponible públicamente antes de que se publicara este desafío.
Ejemplos:
Entrada: 2/5
Salida: 1/3 1/2
Entrada: 1/2
Salida: 0 1
Entrada: 5/9
Salida: 1/2 4/7
Entrada: 1/3
Salida: 0 1/2
Entrada: 2/4
Salida: 1/3 2/3
Entrada: 179565/987657
Salida: 170496/937775 128779/708320
1/3 1/2
.Respuestas:
Sage -
119117Sage solo se necesita en la última línea, que se encarga de la salida. Todo lo demás también funciona en Python.
Reemplace
raw_input()
consys.argv[1]
para que la entrada se lea desde un argumento de línea de comandos en lugar de una solicitud. Esto no cambia el recuento de caracteres. (No funciona en Python sin importarsys
primero).Esto esencialmente construye recursivamente la secuencia de Farey respectiva utilizando mediantes de los elementos existentes, pero se limita a los elementos más cercanos a la entrada. Desde otro punto de vista, ejecuta una búsqueda de intervalo anidado en las respectivas secuencias de Farey.
Procesa correctamente todos los ejemplos en menos de un segundo en mi máquina.
Aquí hay una versión sin golf:
fuente
exec
!Python 2.7 - 138
Comencé con la obvia solución de fuerza bruta, pero me di cuenta de que, dado que el OP quería poder resolver instancias con numeradores y denominadores de seis dígitos en menos de un minuto, necesito una solución mejor que probar un billón de posibilidades. Encontré una fórmula útil en la página de Wikipedia para la secuencia de Farey: si a / b, c / d son vecinos en una de las secuencias de Farey, con
a/b<c/d
, entoncesb*c-a*b=1
. El ciclo while dentro de f en mi programa extiende este hecho a números no reducidos, usando el mcd, que calcula el otro ciclo while.Ya jugué bastante duro, pero me encantaría escuchar cualquier sugerencia.
Ediciones:
166-> 162: eliminado
a
yb
del programa externo. Eran innecesarios.162-> 155:
str()
-> ``155-> 154: Añadido
k
.154-> 152: Eliminado
x
desde el interior de la función, lo pasó como argumento152-> 150: dio
a
un valor predeterminado en lugar de pasarlo como argumento.150-> 146: Se modificó la inicialización de
x
yy
.146-> 145: eliminado
k
.145-> 144: Cambiado ... y ... o ... a (..., ...) [...], ahorrando así un espacio.
144-> 138: Cambiado (..., ...) [...] a ... + ... * (...). Gracias a @ mbomb007.
Casos de prueba:
La penúltima prueba tardó menos de un segundo en mi computadora, mientras que la última tardó unos 5-10 segundos.
fuente
k=1
es pura maldad.print`(a*n+p)/d`+('/'+`a`)*(a>1),
Mathematica, 163 bytes
Esto está severamente limitado por el requisito de entrada / salida como entrada y cadenas de usuario. Tratar con cuerdas es realmente engorroso en Mathematica (al menos cuando quieres jugar al golf). Haciendo esto de la manera natural en Mathematica, (usando solo enteros y racionales) probablemente lo reduciría al 50% del tamaño.
Puede hacer números de 6 dígitos en unos segundos en mi máquina.
Ligeramente más legible (aunque en realidad no es un golf):
Por diversión, hacer esto "de forma natural", es decir, como una función que toma el numerador y el denominador y devuelve dos racionales, esto es solo 84 caracteres (por lo que mi estimación del 50% estaba bastante cerca):
fuente
Julia -
127125bytesHe abordado esto desde una perspectiva matemática para evitar la necesidad de bucles, por lo que este código se ejecuta bastante rápido para entradas grandes (nota: si a / b es la entrada, entonces a * b debe caber dentro de Int64 (Int32 en sistemas de 32 bits) , de lo contrario, se generan respuestas sin sentido: si a y b son expresables en Int32 (Int16 en sistemas de 32 bits), no se producen problemas).
ACTUALIZACIÓN: Ya no es necesario sobrecargar la barra diagonal inversa para div, usando ÷, un ahorro neto de 2 bytes.
Sin golf:
Idea básica: encuentre la d y f más grande menor que b que satisfaga ad-bc = gcd (a, b) (siguiente más pequeña) y be-af = gcd (a, b) (siguiente más grande), luego calcule c y e a partir de allí. La salida resultante es c / de / f, a menos que d o f sea 1, en cuyo caso se omite / d o / f.
Curiosamente, esto significa que el código también funciona para fracciones impropias positivas, siempre que la entrada no sea un número entero (es decir, mcd (a, b) = a).
En mi sistema, ingresar
194857602/34512958303
no requiere tiempo perceptible para generar171085289/30302433084 23772313/4210525219
fuente
55552/999999
me da-396/920632 486/936509
.int32(55552*999999)
da-282630400
. Para mí, con esa prueba, obtengo51143/920632 52025/936509
: tenga en cuenta que los denominadores son los mismos y que 52025-51143 = 486 - (- 396). Agregaré una nota para mencionar este problema.1234567891234567/2145768375829475878
resultados en869253326028691/1510825213275018197 365314565205876/634943162554457681
. Este cambio agrega solo 3 caracteres adicionales.JavaScript, 131
Con notación de flecha gruesa y
eval
llamadas:La
179565/987657
prueba de esfuerzo se ejecuta en aproximadamente 35 segundos en Firefox, mucho más en Chrome (~ 6 minutos)Método más rápido y sin
eval
notación de flecha gruesaLa
179565/987657
prueba de esfuerzo se ejecuta en aproximadamente 5 segundos.No golfizado:
fuente
eval
. EEK2/6
da1/3 2/5
no1/3
es menor sino igual a2/6
.perl, 142 bytes (155 sin CPAN)
O si los módulos CPAN no están permitidos / se necesita un código 3-4 veces más rápido:
La primera versión toma 9.55 segundos en mi máquina, la última versión 2.44 segundos.
Menos ilegible:
fuente