Algoritmos de computação se um número for múltiplo de 3


13

Ao fazer cálculo mental, pode-se fazer:

  • Dado um número inteiro k, some todos os dígitos (na base 10) e, se o resultado for múltiplo de 3, k será múltiplo de 3.

Você conhece algum algoritmo funcionando de maneira semelhante, mas operando com dígitos de números binários (bits)?

  • No começo, eu estava pensando em usar as funções prontas da minha linguagem convertendo número inteiro para ascii para realizar a conversão da base 2 para a base 10 e depois aplicar o truque de cálculo mental. Mas é claro que eu também poderia codificar a conversão de base 2 para 10. Ainda não o fiz, mas vou tentar.

  • Então eu pensei na divisão euclidiana na base 2 ...

No entanto, gostaria de saber se existem outros meios, algoritmos.


Respostas:


22

Considere as duas observações a seguir (deixadas como um exercício para o leitor):

  1. Os poderes pares de dois são 1 módulo 3.
  2. Os poderes ímpares de dois são -1 módulo 3.

Concluímos que um número (em binário) é divisível por três se e somente se a soma dos bits nas posições pares for igual à soma dos bits nas posições ímpares módulo 3.


7
É como a regra de ser divisível por 11 em decimal.
Yuval Filmus

1
@YuvalFilmus: Precisamente. Eu acrescentaria outro exercício para o leitor, mas decidi contra.
Mhum

3
OK, que tal descobrir se um número escrito em hexadecimal é divisível por 17 (decimal)? Ou 15 (decimal) para esse assunto? ;-)
vonbrand 27/01

33

Que tal um autômato de estado finito para o trabalho?

insira a descrição da imagem aqui

É claro que a mágica é apenas o módulo de computação 3. A adição do símbolo a string por trás x significa que o "valor binário" da string vai de v a l ( x ) para x a 2 v a l ( x ) + a para x a . Consequentemente, do estado pe símbolo a passamos para o estado 2 p + a mod 3 , para p { 0 , 1 , 2axval(x)x2val(x)+axapa2p+amod3 e um { 0 , 1 } . Nota x { 0 , 1 } é uma string, sendo que v a l ( x ) N é seu valor como string binária.p{0,1,2}a{0,1}x{0,1}val(x)N


1
Eu gosto da idéia, vamos tentar com 9. Eu alimento 1001 em binário. O primeiro bit me envia ao estado1, depois ao estado2, depois ao estado1 e depois ao estado0. Portanto, state0 é múltiplo de 3. E a complexidade do algoritmo é o número de bits usados, nada mais. É incrivel !
precisa saber é o seguinte

Esse conceito no link está relacionado? Eu acho que é mais simples. geomathry.wordpress.com/2017/02/13/0-1-and-a-new-number

1
0¯0=0¯0¯1=1¯1¯0=2¯1¯1=0¯2¯0=1¯2¯1=2¯Θ,1,01,2,0

Não sobre programação. Isso será mais eficiente em um computador ternário?

4

Em binário, os números 1, 100, 10000 (= 100 × 100), 1000000 (= 100 × 100 × 100) etc. todos fornecem o mesmo restante após a divisão por 11 (três). Portanto, se dividirmos um número binário em partes de comprimento par , a soma das partes fornecerá o mesmo restante que o número original.

(Ao dividir o número, adicionamos quantos zeros forem necessários ao início . Por exemplo, dividiríamos 10111 nos grupos 01,01,11 ou 0001,0111.)

Matematicamente, apenas divida o número em grupos de dois dígitos e adicione os grupos; e repita isso até que o resultado se torne 00 ou 11 = o número original era um múltiplo de três; ou 01 ou 10 = o número original não era um múltiplo de três.

Para um programa de computador, o uso de grupos de oito, dezesseis ou trinta e dois bits pode ser mais rápido para sua CPU. Por exemplo, se a adição de oito bits for mais rápida, faça uma soma de todos os bytes e, novamente, até que o resultado caiba em um byte. Em seguida, use uma instrução para determinar o restante depois de dividir por três.

(Observação: estamos assumindo números inteiros não assinados aqui. Com um número assinado, ele precisa de um pouco mais de atenção. Por exemplo, 129 é um múltiplo de 3, mas -127 não, embora os bits 10000001 signifiquem ex como um byte não assinado e este último como um byte assinado.)


0

Embora não seja específico do binário, na dúvida, a subtração repetida é sempre uma maneira infalível de calcular a divisão com o restante (e, portanto, se um número for múltiplo de 3).


2
Subtração repetida é uma má ideia. A divisão com o restante é muito mais rápida.
Yuval Filmus

3
provavelmente realmente muito caro na CPU, mas é um algoritmo diferente :-) que não merece -1 :-(
Stephane Rolland
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.