Esta é uma versão do desafio recente. Esse número é uma potência inteira de -2? com um conjunto diferente de critérios projetados para destacar a natureza interessante do problema e dificultar o desafio. Eu coloquei alguma consideração nisso aqui .
O desafio, maravilhosamente declarado por Toby na questão vinculada, é:
Existem maneiras inteligentes de determinar se um número inteiro é uma potência exata de 2. Isso não é mais um problema interessante, então vamos determinar se um número inteiro inteiro é uma potência exata de -2 . Por exemplo:
-2 => yes: (-2)¹ -1 => no 0 => no 1 => yes: (-2)⁰ 2 => no 3 => no 4 => yes: (-2)²
Regras:
- Um número inteiro é de 64 bits, assinado, complemento de dois. Esse é o único tipo de dados com o qual você pode trabalhar.
- Você só pode usar as seguintes operações. Cada um deles conta como uma operação.
n << k
,n >> k
: Deslocamento esquerdo / direiton
emk
bits. O bit de sinal é estendido no turno direito.n >>> k
: Desloque para a direita, mas não estenda o bit de sinal. 0s são trocados.a & b
,a | b
,a ^ b
: Bitwise AND, OR, XOR.a + b
,a - b
,a * b
: Adicionar, subtrair, multiplicar.~b
: Inverter bit a bit.-b
: Negação do complemento de dois.a / b
,a % b
: Divide (quociente inteiro, arredonda para 0) e módulo.- O módulo de números negativos usa as regras especificadas em C99 :
(a/b) * b + a%b
devem ser iguaisa
. Assim5 % -3
é2
e-5 % 3
é-2
: 5 / 3
é1
,5 % 3
é2
, como 1 * 3 + 2 = 5.-5 / 3
é-1
,-5 % 3
é-2
, como -1 * 3 + -2 = -5.5 / -3
é-1
,5 % -3
é2
, como -1 * -3 + 2 = 5.-5 / -3
é1
,-5 % -3
é-2
, como 1 * -3 + -2 = -5.- Observe que o
//
operador de divisão de piso do Python%
não atende à propriedade "round round 0" da divisão aqui, e o operador do Python também não atende aos requisitos.
- O módulo de números negativos usa as regras especificadas em C99 :
- As atribuições não contam como uma operação. Como em C, as atribuições avaliam o valor do lado esquerdo após a atribuição:
a = (b = a + 5)
defineb
paraa + 5
, depois definea
parab
e conta como uma operação. - As atribuições de compostos podem ser usadas como
a += b
médiasa = a + b
e contam como uma operação.
- Você pode usar constantes inteiras, elas não contam como nada.
- Parênteses para especificar a ordem das operações são aceitáveis.
- Você pode declarar funções. As declarações de função podem ter qualquer estilo conveniente para você, mas observe que números inteiros de 64 bits são o único tipo de dados válido. As declarações de função não contam como operações, mas uma chamada de função conta como uma. Além disso, fique claro: as funções podem conter várias
return
instruçõesreturn
es de qualquer ponto são permitidas. Oreturn
próprio não conta como uma operação. - Você pode declarar variáveis sem nenhum custo.
- Você pode usar
while
loops, mas não pode usarif
oufor
. Os operadores usados nawhile
condição contam para sua pontuação.while
os loops são executados desde que sua condição seja avaliada como um valor diferente de zero (um "verdadeiro" 0 em idiomas que possuem esse conceito não é um resultado válido). Desde o início de retorno é permitido, você tem permissão para usarbreak
bem - Estouro / estouro insuficiente é permitido e nenhum valor de fixação será feito. É tratado como se a operação realmente tivesse ocorrido corretamente e foi truncado para 64 bits.
Critérios de pontuação / vencedor:
Seu código deve produzir um valor diferente de zero se a entrada for uma potência de -2 e zero, caso contrário.
Isso é código-atômico-golfe . Sua pontuação é o número total de operações presentes no seu código (conforme definido acima), não o número total de operações que são executadas em tempo de execução. O código a seguir:
function example (a, b) {
return a + ~b;
}
function ispowerofnegtwo (input) {
y = example(input, 9);
y = example(y, 42);
y = example(y, 98);
return y;
}
Contém 5 operações: duas na função e três chamadas de função.
Não importa como você apresenta seu resultado, use o que for conveniente em seu idioma, seja ele armazenando o resultado em uma variável, retornando-o de uma função ou qualquer outra coisa.
O vencedor é o post que está comprovadamente correto (forneça uma prova casual ou formal, se necessário) e tem a menor pontuação, conforme descrito acima.
Desafio de modo muito difícil de bônus !
Para ter a chance de ganhar absolutamente nada, exceto a capacidade potencial de impressionar as pessoas nas festas, envie uma resposta sem usar while
loops! Se um número suficiente deles for submetido, posso até considerar dividir os grupos vencedores em duas categorias (com e sem loops).
Nota: Se você desejar fornecer uma solução em um idioma que suporte apenas números inteiros de 32 bits, faça isso, desde que justifique suficientemente que ainda será correto para números inteiros de 64 bits em uma explicação.
Além disso: certos recursos específicos do idioma podem ser permitidos sem custo, se eles não violarem as regras, mas forem necessários para coagir o seu idioma a se comportar de acordo com as regras acima . Por exemplo (artificial), permitirei uma comparação livre não igual a 0 em while
loops, quando aplicada à condição como um todo, como uma solução alternativa para um idioma que possui 0s "verdadeiros". Não são permitidas tentativas claras de tirar proveito desses tipos de coisas - por exemplo, o conceito de valores "verdadeiros" 0 ou "indefinidos" não existe no conjunto de regras acima e, portanto, eles não podem ser invocados.
m ^= s
ainda impressionante, e acho que seria totalmente bom fazer a substituição para melhorá-lo ainda mais.
while
e break
mas não if
? if (x) { ... }
é equivalente a while (x) { ... break; }
.
break
e os retornos iniciais são a parte lamentável) e é uma longa história e uma lição aprendida em regras para desafios futuros. Sempre há a versão "bônus"! :)
if
e for
não são permitidos? int x=condition; while (x) { ... x=0; }
é gratuito, apenas mais código. A mesma coisa com o estilo c for
.