Problema:
En el idioma que elija, escriba la función más corta que devuelve el piso de la raíz cuadrada de un entero de 64 bits sin signo.
Casos de prueba:
Su función debe funcionar correctamente para todas las entradas, pero aquí hay algunas que ayudan a ilustrar la idea:
INPUT ⟶ OUTPUT
0 ⟶ 0
1 ⟶ 1
2 ⟶ 1
3 ⟶ 1
4 ⟶ 2
8 ⟶ 2
9 ⟶ 3
15 ⟶ 3
16 ⟶ 4
65535 ⟶ 255
65536 ⟶ 256
18446744073709551615 ⟶ 4294967295
Reglas:
- Puedes nombrar tu función como quieras. (Las funciones sin nombre, anónimas o lambda están bien, siempre que de alguna manera sean invocables).
- El conteo de personajes es lo que más importa en este desafío, pero el tiempo de ejecución también es importante. Estoy seguro de que puede escanear hacia arriba de forma iterativa para obtener la respuesta en el tiempo O (√n) con un recuento de caracteres muy pequeño, pero el tiempo O (log (n)) realmente sería mejor (es decir, suponiendo un valor de entrada de n, no una longitud de bits de n).
- Probablemente deseará implementar la función usando artitmética puramente entera y / o booleana. Sin embargo, si realmente desea utilizar cálculos de punto flotante, entonces está bien siempre que no llame a funciones de biblioteca. Entonces, simplemente decir
return (n>0)?(uint32_t)sqrtl(n):-1;
en C está fuera de los límites aunque produciría el resultado correcto. Si está usando aritmética de punto flotante, es posible utilizar*
,/
,+
,-
, y exponenciación (por ejemplo,**
o^
si es un operador incorporado en el idioma de su elección, pero exponenciación única de poderes no inferior a 1 ). Esta restricción es para evitar "hacer trampa" llamandosqrt()
o una variante o elevando un valor a la ½ potencia. - Si está utilizando operaciones de punto flotante (ver # 3), no es necesario que el tipo de retorno sea entero; solo que el valor de retorno es un número entero, por ejemplo, floor (sqrt (n)), y puede contener cualquier valor de 32 bits sin signo.
- Si está utilizando C / C ++, puede suponer la existencia de tipos enteros de 64 bits y 32 bits sin signo, por ejemplo,
uint64_t
yuint32_t
como se define enstdint.h
. De lo contrario, solo asegúrese de que su tipo entero sea capaz de contener cualquier número entero sin signo de 64 bits. - Si su idioma no es compatible con enteros de 64 bits (por ejemplo, Brainfuck aparentemente solo tiene soporte de enteros de 8 bits), haga lo mejor que pueda con eso y establezca la limitación en su título de respuesta. Dicho esto, si puedes descubrir cómo codificar un número entero de 64 bits y obtener correctamente la raíz cuadrada del mismo usando la aritmética primitiva de 8 bits, ¡entonces tendrás más potencia!
- ¡Diviértete y sé creativo!
O(log_2 n) === O(log_4 n)
. log_4(n) = log_2(n) / log_2(2) = log_2(n) / 2