Problema:
Na sua escolha de idioma, escreva a função mais curta que retorna o piso da raiz quadrada de um número inteiro de 64 bits não assinado.
Casos de teste:
Sua função deve funcionar corretamente para todas as entradas, mas aqui estão algumas que ajudam a ilustrar a idéia:
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
Regras:
- Você pode nomear sua função como quiser. (As funções sem nome, anônima ou lambda são boas, desde que sejam de alguma forma chamadas.)
- A contagem de caracteres é o que mais importa nesse desafio, mas o tempo de execução também é importante. Tenho certeza de que você poderia procurar iterativamente para cima a resposta em tempo O (√n) com uma contagem de caracteres muito pequena, mas o tempo O (log (n)) seria realmente melhor (ou seja, assumindo um valor de entrada n, não um comprimento de bit de n).
- Você provavelmente desejará implementar a função usando puramente inteiro e / ou aritmética booleana. No entanto, se você realmente deseja usar cálculos de ponto flutuante, tudo bem, desde que você não chame nenhuma função de biblioteca. Portanto, simplesmente dizer
return (n>0)?(uint32_t)sqrtl(n):-1;
em C está fora dos limites, mesmo que produza o resultado correto. Se você estiver usando aritmética de ponto flutuante, você pode usar*
,/
,+
,-
, e exponenciação (por exemplo,**
ou^
se é um built-in operador no idioma de sua escolha, mas a exponenciação única de poderes não inferior a 1 ). Essa restrição é para evitar "trapaça" chamandosqrt()
ou uma variante ou aumentando um valor para a ½ potência. - Se você estiver usando operações de ponto flutuante (consulte # 3), não será necessário que o tipo de retorno seja inteiro; apenas que o valor de retorno seja um número inteiro, por exemplo, floor (sqrt (n)), e seja capaz de manter qualquer valor de 32 bits não assinado.
- Se você estiver usando C / C ++, poderá assumir a existência de tipos inteiros de 64 e 32 bits não assinados, por exemplo,
uint64_t
euint32_t
conforme definido emstdint.h
. Caso contrário, verifique se o tipo inteiro é capaz de conter qualquer número inteiro não assinado de 64 bits. - Se o seu idioma não suportar números inteiros de 64 bits (por exemplo, o Brainfuck aparentemente possui apenas o número inteiro de 8 bits), faça o seu melhor com isso e indique a limitação no título da resposta. Dito isso, se você puder descobrir como codificar um número inteiro de 64 bits e obter corretamente a raiz quadrada usando aritmética primitiva de 8 bits, terá mais poder para você!
- Divirta-se e seja criativo!
O(log_2 n) === O(log_4 n)
. log_4(n) = log_2(n) / log_2(2) = log_2(n) / 2