├── .gitignore ├── LICENSE ├── Life └── Weed │ └── README.md ├── Math ├── Fatorial │ └── README.md ├── Números primos │ ├── README.md │ ├── algol-Resto.js │ ├── algol-Resto.mdown │ ├── algol-testaPrimo.js │ ├── algol-testaPrimoResto.js │ ├── algol-testaPrimoRestoInvertido.js │ ├── algol-testaPrimoRestoRaiz.js │ ├── algol-testaResto.js │ ├── algol-teste.js │ └── index.js └── Números primos │ ├── README.md │ ├── algol-Resto.js │ ├── algol-Resto.mdown │ ├── algol-testaPrimo.js │ ├── algol-testaPrimoResto.js │ ├── algol-testaPrimoRestoInvertido.js │ ├── algol-testaPrimoRestoRaiz.js │ ├── algol-testaResto.js │ ├── algol-teste.js │ └── index.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 WebSchool.io 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Life/Weed/README.md: -------------------------------------------------------------------------------- 1 | # Algoritmo -------------------------------------------------------------------------------- /Math/Fatorial/README.md: -------------------------------------------------------------------------------- 1 | # Algoritmo Fatorial 2 | 3 | ## Definição 4 | 5 | > Na matemática, o fatorial (AO 1945: factorial) de um número natural n, representado por n!, é o produto de todos os inteiros positivos menores ou iguais a n. 6 | 7 | *fonte: https://pt.wikipedia.org/wiki/Fatorial* 8 | 9 | -------------------------------------------------------------------------------- /Math/Números primos/README.md: -------------------------------------------------------------------------------- 1 | # Algoritmo - Números primos 2 | 3 | ##Definição 4 | 5 | A definição de um número primo é: 6 | 7 | > Número primo, é um número p cujo conjunto dos divisores não inversíveis não é vazio, e todos os seus elementos são produtos de p por números inteiros inversíveis. De acordo com esta definição, 0, 1 e -1 não são números primos. 8 | 9 | fonte: [https://pt.wikipedia.org/wiki/N%C3%BAmero_primo](https://pt.wikipedia.org/wiki/N%C3%BAmero_primo) 10 | 11 | Mas o que isso significa? 12 | 13 | Significa que para um número inteiro ser primo, ele só pode ser divisível: 14 | 15 | - por 1; 16 | - por ele mesmo. 17 | 18 | Sabendo disso o que você consegue deduzir sobre o número primo? 19 | 20 | ![](https://media.giphy.com/media/FwmBBOop7p1mw/giphy.gif) 21 | 22 | **Se ele só é divisível por 1 e por ele mesmo, logo ele não tem nenhum outro divisor inteiro.** 23 | 24 | Vamos então ver os números primos de 1 até 7: 25 | 26 | ``` 27 | 1 / 1 = 1 28 | 29 | 2 / 1 = 2 30 | 2 / 2 = 1 31 | 32 | 3 / 1 = 3 33 | 3 / 2 = 1.5 34 | 3 / 3 = 1 35 | 36 | 4 / 1 = 4 37 | 4 / 2 = 2 38 | 4 / 3 = 1.333 39 | 4 / 4 = 1 40 | 41 | 5 / 1 = 5 42 | 5 / 2 = 2.5 43 | 5 / 3 = 1.666 44 | 5 / 4 = 1.25 45 | 5 / 5 = 1 46 | 47 | 6 / 1 = 6 48 | 6 / 2 = 3 49 | 6 / 3 = 2 50 | 6 / 4 = 1.5 51 | 6 / 5 = 1.2 52 | 6 / 6 = 1 53 | 54 | 7 / 1 = 7 55 | 7 / 2 = 3.5 56 | 7 / 3 = 2.333 57 | 7 / 4 = 1.75 58 | 7 / 5 = 1.4 59 | 7 / 6 = 1.166 60 | 7 / 7 = 1 61 | ``` 62 | 63 | Baseando-se nos dados acima, quais são os números primos de 1 a 7? 64 | 65 | > 2,3,5,7 66 | 67 | **Entendeu o que teremos que testar para verificar se um número é primo???** 68 | 69 | ![](https://media.giphy.com/media/xf20D8HzvTQzu/giphy.gif) 70 | 71 | Primeiramente escrevemos as regras explícitas, não precisamos testar se o número é divisível por 1, mas precisamos testar se o número **tem algum divisor entre ele e 1**. 72 | 73 | Para fazer iremos utilizar a mesma lógica da função `multiplicar/dividir` do [Curso de Matemática para Programadores](https://github.com/Webschool-io/matematica-para-programadores). 74 | 75 | Sabemos então que não precisaos dividir por `1`, mas pecisamos dividir por `2` e esse este será o primeiro do nosso algritmo, pois tamb 76 | 77 | Para escrever isso como algoritmo eu preciso entender antes o conceito de *loop*. 78 | 79 | O *loop* na programação é uma função que irá executar um número pré-definido de vezes, para exemplificar isso utilizarei a função `for` que se encontra em quase todas as linguagens, porém utilizarei JavaScript. 80 | 81 | Antes de criamos o algoritmo precisamos entender como a divisão funciona por aqui. 82 | 83 | Se eu dividir 4 por 2, que são divisores, o resultado é 2. E se eu dividir 4 por 3? 84 | 85 | Vai resultar em um dízima periódica: `1.333333`. 86 | 87 | Ou seja, analisando o resultado dessas 2 operações, **como você acha que testaremos se um número é divisível por outro?** 88 | 89 | ```js 90 | const numero = 4; 91 | const divisor = 2; 92 | if(numero/divisor) ??? 93 | ``` 94 | 95 | Bom apenas dividir nossos números não nos resolve o problema, precisamos testar é o **resto da divisão**. 96 | 97 | **Então qual será a lógica?** 98 | 99 | Pense comigo: 100 | 101 | > Todo número dividido por um divisor irá **sempre** resultar em um número inteiro! 102 | 103 | Ou seja, se você dividir um número por outro **que não seja seu divisor**, por exemplo `3/2`, o resultado **NUNCA** será inteiro, sendo assim o resto da divisão **NUNCA** resultará em 0. 104 | 105 | Para entender melhor o algoritmo de divisão [leia mais aqui]() 106 | 107 | Na programação podemos testar isso de 2 formas: 108 | 109 | - testando o resultado se é inteiro; 110 | - testando o resto da divisão se é 0. 111 | 112 | Vamos iniciar nosso algoritmo 113 | 114 | ## Testando se o resultado da divisão é inteiro 115 | 116 | Nesse caso precisamos verificar se o resultado da divisão será um inteiro, pois se ele for nós encontramos um divisor. 117 | 118 | **Mas como assim?** 119 | 120 | Simples, divida `4` por `2`. 121 | 122 | O resultado é `2`, ou seja, um inteiro. 123 | 124 | Agora divida `4` por `3`. 125 | 126 | O resultado é `1.33333`, ou seja, não inteiro. 127 | 128 | Para facilitar nossa vida o JavaScript nos provê a função `Number.isInteger()` que irá fazer teste automaticamente: 129 | 130 | ```js 131 | let primo = false; 132 | const numero = 4; 133 | const divisor = 2; 134 | const resultado = numero/divisor; 135 | 136 | if(Number.isInteger(resultado)) { 137 | primo = true; 138 | } 139 | 140 | console.log('O resultado da divisão entre '+numero+' e '+divisor+' é inteiro?', primo); 141 | ``` 142 | 143 | Você pode executar esse código diretamente do seu navegador, entrando no Console (favor pesquisar como fazer em seu Navegador). 144 | 145 | Perceba que no `if` estou chamando a função `Number.isInteger` passando como parâmetro o resultado da divisão, essa mesma função irá retornar verdadeiro(`true`) caso o número seja inteiro ou falso(`false`) caso não. 146 | 147 | Para facilitar nossa vida futura irei encapsular essa lógica para poder sempre reusar, basta apenas criar uma função para tal: 148 | 149 | ```js 150 | let primo = false; 151 | const numero = 4; 152 | const divisor = 3; 153 | const resultado = numero/divisor; 154 | 155 | const isInteger = (numero) => { 156 | if(Number.isInteger(numero)) { 157 | inteiro = true; 158 | } 159 | console.log('O número '+numero+' é inteiro?', inteiro); 160 | return inteiro; 161 | } 162 | 163 | isInteger(resultado); 164 | ``` 165 | 166 | Bom, você deve ter percebido que utilizei `let` e `const` para definir os valores, a diferença básica entre elas é que usando `const` o valor definido não pode ser mais modificado e com `let` pode. 167 | 168 | Depois crio a função com `const isInteger = (numero) => { ... }`, onde a definição da função é `(numero) => { ... }`. 169 | 170 | Claramente você percebe que a definição dos parâmetros da função são feitos em `(numero)`, antes da `=>` que é a definição da função propriamente dita. 171 | 172 | Depois executo a função `isInteger(resultado)` passando a constante do `resultado` da divisão. 173 | 174 | **Agora com esse conhecimento o que você acha que devemos fazer?** 175 | 176 | Iniciamos adicionando nossa função para usá-la para testar o resultado das divisões do nosso número a ser testado, isso por quê? 177 | 178 | Pois para um número ser primo nós precisaremos testar o resultado da divisão dele por todos seus números anteriores acima de 2. 179 | 180 | ```js 181 | const isInteger = (numero) => { 182 | let inteiro = false; 183 | if(Number.isInteger(numero)) { 184 | inteiro = true; 185 | } 186 | console.log('O número '+numero+' é inteiro?', inteiro); 187 | return inteiro; 188 | } 189 | 190 | // Definimos o estado atual 191 | let primo = false; 192 | const numero = 5; 193 | // Não preciso testar se é divisível por 1 194 | for(let contador = 2; contador < numero; contador++) { 195 | // Preciso testar se o número tem algum divisor entre ele e 2 196 | // Se não achar nenhum divisor ele será PRIMO 197 | let resultado = numero/contador; 198 | if(isInteger(resultado) === false) { 199 | primo = true; 200 | } 201 | console.log('Contador: ', contador); 202 | console.log('Resultado: ', resultado); 203 | // Como definimos o estado inicial em FALSE 204 | // Só mudaremos ele se for PRIMO, porém usado a mesma variável 205 | console.log('O número '+numero+' é primo?', primo); 206 | return primo 207 | } 208 | ``` 209 | 210 | Percebeu que no teste do for eu não passo uma valor abritrário, mas sim testo se o `contador` é menor que o `numero`(5), quando o `contador` tiver o valor de 5 ele irá sair. 211 | 212 | Como iremos testar algo sempre devemos partir do pressuposto que é falso e com nossa lógica iremos testar para mudar esse estado. 213 | 214 | No código acim estamos simplesmente retornando falso se o número for divisível por outro menor que ele e maior que 2. 215 | 216 | Caso você não tenha entendido essa linha: 217 | 218 | ```js 219 | for(let contador = 2; contador < 4; contador++) 220 | ``` 221 | 222 | A função `for` recebe 3 parâmetros: 223 | 224 | - atribuição do valor inicial do contador; 225 | - teste para saída do *looping*; 226 | - incrementação(adição de 1) do contador. 227 | 228 | Precisamos de um contador para poder saber quantos *loopings* ele fez e para poder sair dele, pois caso você coloque um teste que nunca dê falso o `for` *NUNCA* sairá do *looping*. 229 | 230 | Sabendo disso entendemos que o contador irá de 2 até < 4, fazendo o que? 231 | 232 | ```js 233 | if(numero/contador === 0) 234 | ``` 235 | 236 | **ISSO MESMO!!!** Testando a divisão entre o `numero`(4) e o `contador` que terá um valor diferente a cada *loop*, sendo que esse valor inicia em 2 e vai sendo **incrementado em 1** por causa do terceiro parâmetro do `for`. 237 | 238 | Então você percebeu que aquele `contador++` é o tal do incrementador né? 239 | 240 | Ele simplesmente adiciona 1 ao valor do `contador` cada vez que passa. 241 | 242 | Agora refatoramos o algoritmo para encapsular a lógica do número primo em uma função: 243 | 244 | ```js 245 | const isInteger = (numero) => { 246 | let inteiro = false; 247 | if(Number.isInteger(numero)) { 248 | inteiro = true; 249 | } 250 | console.log('O número '+numero+' é inteiro?', inteiro); 251 | return inteiro; 252 | } 253 | 254 | const isPrime = (numero) => { 255 | if(isInteger(numero/2)) { 256 | return false; 257 | } 258 | for(let contador = 3; contador < numero; contador++) { 259 | // Preciso testar se o número tem algum divisor entre ele e 1 260 | // Se não achar nenhum divisor ele será PRIMO 261 | let resultado = numero/contador; 262 | if(isInteger(resultado)) { 263 | return false; 264 | } 265 | } 266 | return true; 267 | } 268 | const numero = 273; 269 | const primo = isPrime(numero); 270 | 271 | console.log('O número '+numero+' é primo?', primo); 272 | ``` 273 | 274 | ## Testando o resto da divisão se é igual a 0 275 | 276 | Podemos resolver o mesmo problema com uma abordagem diferente, em vez de testar o resultado da divisão iremos testar se o resto dessa divisão é igual a 0. 277 | 278 | Vamos reusar o algoritmo passado: 279 | 280 | ```js 281 | // Definimos o estado atual 282 | let primo = false; 283 | const numero = 5; 284 | // Não preciso testar se é divisível por 1 nem 2 285 | for(let contador = 2; contador < numero; contador++) { 286 | // Preciso testar se o número tem algum divisor entre ele e 1 287 | // Se não achar nenhum divisor ele será PRIMO 288 | let resultado = numero/contador; 289 | if(isInteger(resultado) === false) { 290 | primo = true; 291 | } 292 | console.log('Contador: ', contador); 293 | console.log('Resultado: ', resultado); 294 | // Como definimos o estado inicial em FALSE 295 | // Só mudaremos ele se for PRIMO, porém usado a mesma variável 296 | console.log('O número '+numero+' é primo?', primo); 297 | return primo; 298 | } 299 | ``` 300 | 301 | Como iremos trabalhar com o valor do **resto** da divisão precisamos inicialmente conhecer esse conceito. 302 | 303 | **O que é esse resto?** 304 | 305 | Para exemplificar melhor acompanhe aqui comigo: 306 | 307 | ``` 308 | 4 / 2 = 2 309 | ``` 310 | 311 | A divisão de 4 por 2 resulta em 2 e tem 0 como resto, pois: 312 | 313 | ``` 314 | 4 |2 315 | -4 2 316 | 0 317 | ``` 318 | 319 | Vamos ver com um número ímpar: 320 | 321 | ``` 322 | 4 |3 323 | -3 1.3 324 | 10 325 | -9 326 | 1 327 | ... é uma dízima periódica 328 | ``` 329 | 330 | Logo você percebe que se o número a ser dividido(4), o dividendo, pelo divisor(3) não encontrar um resultado inteiro você deverá adicionar uma casa decimal (colocando a vírgula), fazendo isso você deve multiplicar o **resto** por 10, pois adicionou a vírgula no resultado, e continuar a divisão normalmente. 331 | 332 | Ótimo então já sabemos dividir (hehehe) agora vamos criar um algoritmo para verificar o resto de uma divisão: 333 | 334 | ```js 335 | const divisor = 4; 336 | const dividendo = 3 337 | 338 | const calculateRest = (divisor, dividendo) => { 339 | const resultado = divisor/dividendo; 340 | console.log('resultado: ', resultado); 341 | return divisor - (dividendo * parseInt(resultado)); 342 | } 343 | ``` 344 | 345 | Porém como as linguagens de programação vieram para facilitar nossa vida nós não precisaremos utilizar a função acima para retornar o resto, utilizaremos o [operador de módulo](https://pt.wikipedia.org/wiki/Opera%C3%A7%C3%A3o_m%C3%B3dulo) ou também conhecido como **mod**, [no JavaScript usamos o operador %](). 346 | 347 | ```js 348 | const calculateRest = (dividendo, divisor) => { 349 | const resultado = dividendo/divisor; 350 | console.log('resultado: ', resultado); 351 | return (dividendo - (divisor * parseInt(resultado))); 352 | } 353 | 354 | const isInteger = (numero) => { 355 | let inteiro = false; 356 | if(Number.isInteger(numero)) { 357 | inteiro = true; 358 | } 359 | console.log('O número '+numero+' é inteiro?', inteiro); 360 | return inteiro; 361 | } 362 | 363 | const isPrime = (numero) => { 364 | if(isInteger(numero/2)) { 365 | return false; 366 | } 367 | for(let contador = 3; contador < numero; contador++) { 368 | if(!calculateRest(numero, contador)) { 369 | return false; 370 | } 371 | } 372 | return true; 373 | } 374 | const numero = 5; 375 | const primo = isPrime(numero); 376 | console.log('O número '+numero+' é primo?', primo); 377 | ``` 378 | 379 | Dessa vez nós reusamos as funções passadas `isInteger` e `isPrime`, criando a função `calculateRest` que irá retornar o valor do resto da divisão para testarmos se ele é diferente de 0, **pois se o resto for 0 o `numero` encontrou um divisor**. 380 | 381 | Quero que você analise essa linha comigo: 382 | 383 | ```js 384 | if(!calculateRest(numero, contador)) 385 | ``` 386 | 387 | **Por que não estou testando se o resultado de `calculateRest(numero, contador)` é diferente de 0?** 388 | 389 | Pense aqui comigo, o retorno da função `calculateRest` será um inteiro, caso seja 0 significa que o número achou seu divisor, logo não é primo, por isso retornamos `false`: 390 | 391 | ```js 392 | for(let contador = 3; contador < numero; contador++) { 393 | if(!calculateRest(numero, contador)) { 394 | return false; 395 | } 396 | } 397 | ``` 398 | 399 | Então como o valor 0 que significa `false` entrou no `if` onde só pode entrar caso o valor seja `true`, no JavaScript também usamos o valor `0` para `false` e o valor `1` (ou maiores que 0) para `true`. 400 | 401 | **Agora que vem a malandragem da lógica!** 402 | 403 | Para o valor `0` entrar no if nós precisamos inverter seu valor já para Booleano(`true` ou `false`). Confira executando isso no seu console: 404 | 405 | ``` 406 | !0 407 | true 408 | !1 409 | false 410 | ``` 411 | 412 | E pronto! 413 | 414 | ## Desafio 415 | 416 | **Agora o seu desafio é inverter a lógica!** 417 | 418 | Em vez de iniciar do 3 você deverá iniciar do valor passado a ser testado, ou seja, em vez de incrementar você irá decrementar. 419 | 420 | **E também deverá criar um algoritmo para retornar `true` ou `false` caso um número seja Inteiro, utilizando-o em vez da função parseInt().** 421 | 422 | ## Dividindo por √¯n 423 | 424 | Caso não esteja familiarizado com o algoritmo da radiciação [leia mais nesse meu conteúdo](https://github.com/Webschool-io/matematica-para-programadores#radiciação-1), nele eu deduzi uma fórmula "simples" para números inteiros positivos: 425 | 426 | ``` 427 | √¯y = x 428 | 429 | y/x = x 430 | ``` 431 | 432 | Ela pode ser provada da seguinte forma: 433 | 434 | ``` 435 | √¯49 = x 436 | 49 = x ^ 2 437 | 49 = x . x 438 | 49/x = x 439 | 49/7 = 7 440 | ``` 441 | 442 | Nesse caso sabemos que qualquer número divido pela sua raíz quadrada será a própria raíz, ou seja, qualquer número pode ser escrito como a multiplicação de dois números. 443 | 444 | Sabendo disso podemos inferir que um número `x` pode ser escrito como uma multiplicação de 2 números inteiros e positivos menores que ele, sendo a multiplicação da sua raíz por ela mesma o maior valor. 445 | 446 | Agora podemos melhorar nosso algoritmo não precisando dividir por todos seus antecessores, bastando iniciar da raíz do número até 2. 447 | 448 | Veja o que mudaremos dentro da função `isPrime`: 449 | 450 | ```js 451 | const isPrime = (numero) => { 452 | 453 | if(isInteger(numero/2)) { 454 | return false; 455 | } 456 | 457 | const raiz = Math.sqrt(numero); 458 | 459 | if(raiz > 2) { 460 | for(let contador = 3; contador < raiz; contador++) { 461 | if(!calculateRest(numero, contador)) { 462 | return false; 463 | } 464 | } 465 | return true; 466 | } 467 | } 468 | ``` 469 | 470 | Logo após o teste pra verificar se é par em `if(isInteger(numero/2))` adicionei o cálculo da raíz quarada utilizando a função `Math.sqrt(numero)`. 471 | 472 | Para na sequência testar se a `raiz` é maior que `2` para garantir que não entrarei nesse `if` caso o `numero` seja menor que 4, que é par. 473 | 474 | Depois bastou modificar o teste de saída do `for` para `contador < raiz`, poupando-nos **muito processamento**. 475 | 476 | Apenas observe nosso algoritmo antes: 477 | 478 | ``` 479 | 37 / 2 = 18.5 480 | O número 18.5 é inteiro? false 481 | 37/3 12.333333333333334 482 | 37/4 9.25 483 | 37/5 7.4 484 | 37/6 6.166666666666667 485 | 37/7 5.285714285714286 486 | 37/8 4.625 487 | 37/9 4.111111111111111 488 | 37/10 3.7 489 | 37/11 3.3636363636363638 490 | 37/12 3.0833333333333335 491 | 37/13 2.8461538461538463 492 | 37/14 2.642857142857143 493 | 37/15 2.466666666666667 494 | 37/16 2.3125 495 | 37/17 2.176470588235294 496 | 37/18 2.0555555555555554 497 | 37/19 1.9473684210526316 498 | 37/20 1.85 499 | 37/21 1.7619047619047619 500 | 37/22 1.6818181818181819 501 | 37/23 1.608695652173913 502 | 37/24 1.5416666666666667 503 | 37/25 1.48 504 | 37/26 1.4230769230769231 505 | 37/27 1.3703703703703705 506 | 37/28 1.3214285714285714 507 | 37/29 1.2758620689655173 508 | 37/30 1.2333333333333334 509 | 37/31 1.1935483870967742 510 | 37/32 1.15625 511 | 37/33 1.121212121212121 512 | 37/34 1.088235294117647 513 | 37/35 1.0571428571428572 514 | 37/36 1.0277777777777777 515 | O número 37 é primo? true 516 | ``` 517 | 518 | E agora com o algoritmo otimizado: 519 | 520 | ``` 521 | 37 / 2 = 18.5 522 | O número 18.5 é inteiro? false 523 | 37/3 12.333333333333334 524 | 37/4 9.25 525 | 37/5 7.4 526 | 37/6 6.166666666666667 527 | O número 37 é primo? true 528 | ``` 529 | 530 | **Saímos de 37 operações para apenas 7!** E claro que esse número pode aumentar **MUITO!!!** 531 | 532 | 533 | 534 | -------------------------------------------------------------------------------- /Math/Números primos/algol-Resto.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const divisor = 4; 4 | const dividendo = 3 5 | 6 | const calcularResto = (divisor, dividendo) => { 7 | const resultado = divisor/dividendo; 8 | console.log('resultado: ', resultado); 9 | return divisor - (dividendo * parseInt(resultado)); 10 | } 11 | 12 | console.log('resto: ', calcularResto(divisor, dividendo)); 13 | 14 | -------------------------------------------------------------------------------- /Math/Números primos/algol-Resto.mdown: -------------------------------------------------------------------------------- 1 | const -------------------------------------------------------------------------------- /Math/Números primos/algol-testaPrimo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const isInteger = (numero) => { 4 | let inteiro = false; 5 | if(Number.isInteger(numero)) { 6 | inteiro = true; 7 | } 8 | console.log('O número '+numero+' é inteiro?', inteiro); 9 | return inteiro; 10 | } 11 | 12 | const isPrime = (numero) => { 13 | if(isInteger(numero/2)) { 14 | return false; 15 | } 16 | for(let contador = 3; contador < numero; contador++) { 17 | // Preciso testar se o número tem algum divisor entre ele e 1 18 | // Se não achar nenhum divisor ele será PRIMO 19 | let resultado = numero/contador; 20 | if(isInteger(resultado)) { 21 | return false; 22 | } 23 | } 24 | return true; 25 | } 26 | const numero = 273; 27 | const primo = isPrime(numero); 28 | 29 | console.log('O número '+numero+' é primo?', primo); 30 | -------------------------------------------------------------------------------- /Math/Números primos/algol-testaPrimoResto.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const calculateRest = (dividendo, divisor) => { 4 | const resultado = dividendo/divisor; 5 | console.log(dividendo+'/'+divisor, resultado); 6 | return (dividendo - (divisor * parseInt(resultado))); 7 | } 8 | 9 | const isInteger = (numero) => { 10 | let inteiro = false; 11 | if(Number.isInteger(numero)) { 12 | inteiro = true; 13 | } 14 | console.log('O número '+numero+' é inteiro?', inteiro); 15 | return inteiro; 16 | } 17 | 18 | const isPrime = (numero) => { 19 | console.log(numero+' / 2 = ', numero/2); 20 | if(isInteger(numero/2)) { 21 | return false; 22 | } 23 | for(let contador = 3; contador < numero; contador++) { 24 | if(!calculateRest(numero, contador)) { 25 | return false; 26 | } 27 | } 28 | return true; 29 | } 30 | const numero = 37; 31 | const primo = isPrime(numero); 32 | console.log('O número '+numero+' é primo?', primo); 33 | 34 | -------------------------------------------------------------------------------- /Math/Números primos/algol-testaPrimoRestoInvertido.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const calculateRest = (dividendo, divisor) => { 4 | const resultado = dividendo/divisor; 5 | console.log(dividendo+'/'+divisor, resultado); 6 | return (dividendo - (divisor * parseInt(resultado))); 7 | } 8 | 9 | const isInteger = (numero) => { 10 | let inteiro = false; 11 | if(Number.isInteger(numero)) { 12 | inteiro = true; 13 | } 14 | console.log('O número '+numero+' é inteiro?', inteiro); 15 | return inteiro; 16 | } 17 | 18 | const isPrime = (numero) => { 19 | if(isInteger(numero/2)) { 20 | return false; 21 | } 22 | for(let contador = numero-1; contador <= numero; contador--) { 23 | if(contador === 2) { 24 | break; 25 | } 26 | console.log(numero+'/'+contador, numero/contador); 27 | if(!calculateRest(numero, contador)) { 28 | return false; 29 | } 30 | } 31 | return true; 32 | } 33 | const numero = 25; 34 | const primo = isPrime(numero); 35 | console.log('O número '+numero+' é primo?', primo); 36 | 37 | -------------------------------------------------------------------------------- /Math/Números primos/algol-testaPrimoRestoRaiz.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const calculateRest = (dividendo, divisor) => { 4 | const resultado = dividendo/divisor; 5 | console.log(dividendo+'/'+divisor, resultado); 6 | return (dividendo - (divisor * parseInt(resultado))); 7 | } 8 | 9 | const isInteger = (numero) => { 10 | let inteiro = false; 11 | if(Number.isInteger(numero)) { 12 | inteiro = true; 13 | } 14 | console.log('O número '+numero+' é inteiro?', inteiro); 15 | return inteiro; 16 | } 17 | 18 | const isPrime = (numero) => { 19 | console.log(numero+' / 2 = ', numero/2); 20 | if(isInteger(numero/2)) { 21 | return false; 22 | } 23 | 24 | const raiz = Math.sqrt(numero); 25 | if(raiz > 2) { 26 | for(let contador = 3; contador < raiz; contador++) { 27 | if(!calculateRest(numero, contador)) { 28 | return false; 29 | } 30 | } 31 | return true; 32 | } 33 | } 34 | 35 | const numero = 37; 36 | const primo = isPrime(numero); 37 | console.log('O número '+numero+' é primo?', primo); 38 | 39 | -------------------------------------------------------------------------------- /Math/Números primos/algol-testaResto.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let inteiro = false; 4 | const numero = 4; 5 | const divisor = 3; 6 | const resto = numero/divisor; 7 | 8 | const isInteger = (numero) => { 9 | let inteiro = false; 10 | if(Number.isInteger(numero)) { 11 | inteiro = true; 12 | } 13 | 14 | console.log('O número '+numero+' é inteiro?', inteiro); 15 | return inteiro; 16 | } 17 | 18 | isInteger(resto); -------------------------------------------------------------------------------- /Math/Números primos/algol-teste.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const numero = 4; 4 | // Definimos o estado atual 5 | let primo = false; 6 | // Não preciso testar se é divisível por 1 7 | for(let contador = 2; contador < 4; contador++) { 8 | // Preciso testar se o número tem algum divisor entre ele e 1 9 | // Se não achar nennhum divisor ele será PRIMO 10 | console.log(numero+'/'+contador, numero/contador) 11 | if(numero/contador !== 0) { 12 | primo = true; 13 | } 14 | } 15 | // Como definimos o estado inicial em FALSE 16 | // Só mudaremos ele qse for PRIMO, porém usado a mesma variável 17 | console.log(primo); -------------------------------------------------------------------------------- /Math/Números primos/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const testaNumeroPrimo = (numero) => { 4 | let primo = false; 5 | for(let contador = 2; contador <=4; contador++) { 6 | console.log(numero+'/'+contador, numero/contador) 7 | if(!numero/contador) { 8 | primo = true; 9 | } 10 | return primo; 11 | } 12 | } 13 | 14 | console.log(testaNumeroPrimo(84)); -------------------------------------------------------------------------------- /Math/Números primos/README.md: -------------------------------------------------------------------------------- 1 | # Algoritmo - Números primos 2 | 3 | ##Definição 4 | 5 | A definição de um número primo é: 6 | 7 | > Número primo, é um número p cujo conjunto dos divisores não inversíveis não é vazio, e todos os seus elementos são produtos de p por números inteiros inversíveis. De acordo com esta definição, 0, 1 e -1 não são números primos. 8 | 9 | fonte: [https://pt.wikipedia.org/wiki/N%C3%BAmero_primo](https://pt.wikipedia.org/wiki/N%C3%BAmero_primo) 10 | 11 | Mas o que isso significa? 12 | 13 | Significa que para um número inteiro ser primo, ele só pode ser divisível: 14 | 15 | - por 1; 16 | - por ele mesmo. 17 | 18 | Sabendo disso o que você consegue deduzir sobre o número primo? 19 | 20 | ![](https://media.giphy.com/media/FwmBBOop7p1mw/giphy.gif) 21 | 22 | **Se ele só é divisível por 1 e por ele mesmo, logo ele não tem nenhum outro divisor inteiro.** 23 | 24 | Vamos então ver os números primos de 1 até 7: 25 | 26 | ``` 27 | 1 / 1 = 1 28 | 29 | 2 / 1 = 2 30 | 2 / 2 = 1 31 | 32 | 3 / 1 = 3 33 | 3 / 2 = 1.5 34 | 3 / 3 = 1 35 | 36 | 4 / 1 = 4 37 | 4 / 2 = 2 38 | 4 / 3 = 1.333 39 | 4 / 4 = 1 40 | 41 | 5 / 1 = 5 42 | 5 / 2 = 2.5 43 | 5 / 3 = 1.666 44 | 5 / 4 = 1.25 45 | 5 / 5 = 1 46 | 47 | 6 / 1 = 6 48 | 6 / 2 = 3 49 | 6 / 3 = 2 50 | 6 / 4 = 1.5 51 | 6 / 5 = 1.2 52 | 6 / 6 = 1 53 | 54 | 7 / 1 = 7 55 | 7 / 2 = 3.5 56 | 7 / 3 = 2.333 57 | 7 / 4 = 1.75 58 | 7 / 5 = 1.4 59 | 7 / 6 = 1.166 60 | 7 / 7 = 1 61 | ``` 62 | 63 | Baseando-se nos dados acima, quais são os números primos de 1 a 7? 64 | 65 | > 2,3,5,7 66 | 67 | **Entendeu o que teremos que testar para verificar se um número é primo???** 68 | 69 | ![](https://media.giphy.com/media/xf20D8HzvTQzu/giphy.gif) 70 | 71 | Primeiramente escrevemos as regras explícitas, não precisamos testar se o número é divisível por 1, mas precisamos testar se o número **tem algum divisor entre ele e 1**. 72 | 73 | Para fazer iremos utilizar a mesma lógica da função `multiplicar/dividir` do [Curso de Matemática para Programadores](https://github.com/Webschool-io/matematica-para-programadores). 74 | 75 | Sabemos então que não precisaos dividir por `1`, mas pecisamos dividir por `2` e esse este será o primeiro do nosso algritmo, pois tamb 76 | 77 | Para escrever isso como algoritmo eu preciso entender antes o conceito de *loop*. 78 | 79 | O *loop* na programação é uma função que irá executar um número pré-definido de vezes, para exemplificar isso utilizarei a função `for` que se encontra em quase todas as linguagens, porém utilizarei JavaScript. 80 | 81 | Antes de criamos o algoritmo precisamos entender como a divisão funciona por aqui. 82 | 83 | Se eu dividir 4 por 2, que são divisores, o resultado é 2. E se eu dividir 4 por 3? 84 | 85 | Vai resultar em um dízima periódica: `1.333333`. 86 | 87 | Ou seja, analisando o resultado dessas 2 operações, **como você acha que testaremos se um número é divisível por outro?** 88 | 89 | ```js 90 | const numero = 4; 91 | const divisor = 2; 92 | if(numero/divisor) ??? 93 | ``` 94 | 95 | Bom apenas dividir nossos números não nos resolve o problema, precisamos testar é o **resto da divisão**. 96 | 97 | **Então qual será a lógica?** 98 | 99 | Pense comigo: 100 | 101 | > Todo número dividido por um divisor irá **sempre** resultar em um número inteiro! 102 | 103 | Ou seja, se você dividir um número por outro **que não seja seu divisor**, por exemplo `3/2`, o resultado **NUNCA** será inteiro, sendo assim o resto da divisão **NUNCA** resultará em 0. 104 | 105 | Para entender melhor o algoritmo de divisão [leia mais aqui]() 106 | 107 | Na programação podemos testar isso de 2 formas: 108 | 109 | - testando o resultado se é inteiro; 110 | - testando o resto da divisão se é 0. 111 | 112 | Vamos iniciar nosso algoritmo 113 | 114 | ## Testando se o resultado da divisão é inteiro 115 | 116 | Nesse caso precisamos verificar se o resultado da divisão será um inteiro, pois se ele for nós encontramos um divisor. 117 | 118 | **Mas como assim?** 119 | 120 | Simples, divida `4` por `2`. 121 | 122 | O resultado é `2`, ou seja, um inteiro. 123 | 124 | Agora divida `4` por `3`. 125 | 126 | O resultado é `1.33333`, ou seja, não inteiro. 127 | 128 | Para facilitar nossa vida o JavaScript nos provê a função `Number.isInteger()` que irá fazer teste automaticamente: 129 | 130 | ```js 131 | let primo = false; 132 | const numero = 4; 133 | const divisor = 2; 134 | const resultado = numero/divisor; 135 | 136 | if(Number.isInteger(resultado)) { 137 | primo = true; 138 | } 139 | 140 | console.log('O resultado da divisão entre '+numero+' e '+divisor+' é inteiro?', primo); 141 | ``` 142 | 143 | Você pode executar esse código diretamente do seu navegador, entrando no Console (favor pesquisar como fazer em seu Navegador). 144 | 145 | Perceba que no `if` estou chamando a função `Number.isInteger` passando como parâmetro o resultado da divisão, essa mesma função irá retornar verdadeiro(`true`) caso o número seja inteiro ou falso(`false`) caso não. 146 | 147 | Para facilitar nossa vida futura irei encapsular essa lógica para poder sempre reusar, basta apenas criar uma função para tal: 148 | 149 | ```js 150 | let primo = false; 151 | const numero = 4; 152 | const divisor = 3; 153 | const resultado = numero/divisor; 154 | 155 | const isInteger = (numero) => { 156 | if(Number.isInteger(numero)) { 157 | inteiro = true; 158 | } 159 | console.log('O número '+numero+' é inteiro?', inteiro); 160 | return inteiro; 161 | } 162 | 163 | isInteger(resultado); 164 | ``` 165 | 166 | Bom, você deve ter percebido que utilizei `let` e `const` para definir os valores, a diferença básica entre elas é que usando `const` o valor definido não pode ser mais modificado e com `let` pode. 167 | 168 | Depois crio a função com `const isInteger = (numero) => { ... }`, onde a definição da função é `(numero) => { ... }`. 169 | 170 | Claramente você percebe que a definição dos parâmetros da função são feitos em `(numero)`, antes da `=>` que é a definição da função propriamente dita. 171 | 172 | Depois executo a função `isInteger(resultado)` passando a constante do `resultado` da divisão. 173 | 174 | **Agora com esse conhecimento o que você acha que devemos fazer?** 175 | 176 | Iniciamos adicionando nossa função para usá-la para testar o resultado das divisões do nosso número a ser testado, isso por quê? 177 | 178 | Pois para um número ser primo nós precisaremos testar o resultado da divisão dele por todos seus números anteriores acima de 2. 179 | 180 | ```js 181 | const isInteger = (numero) => { 182 | let inteiro = false; 183 | if(Number.isInteger(numero)) { 184 | inteiro = true; 185 | } 186 | console.log('O número '+numero+' é inteiro?', inteiro); 187 | return inteiro; 188 | } 189 | 190 | // Definimos o estado atual 191 | let primo = false; 192 | const numero = 5; 193 | // Não preciso testar se é divisível por 1 194 | for(let contador = 2; contador < numero; contador++) { 195 | // Preciso testar se o número tem algum divisor entre ele e 2 196 | // Se não achar nenhum divisor ele será PRIMO 197 | let resultado = numero/contador; 198 | if(isInteger(resultado) === false) { 199 | primo = true; 200 | } 201 | console.log('Contador: ', contador); 202 | console.log('Resultado: ', resultado); 203 | // Como definimos o estado inicial em FALSE 204 | // Só mudaremos ele se for PRIMO, porém usado a mesma variável 205 | console.log('O número '+numero+' é primo?', primo); 206 | return primo 207 | } 208 | ``` 209 | 210 | Percebeu que no teste do for eu não passo uma valor abritrário, mas sim testo se o `contador` é menor que o `numero`(5), quando o `contador` tiver o valor de 5 ele irá sair. 211 | 212 | Como iremos testar algo sempre devemos partir do pressuposto que é falso e com nossa lógica iremos testar para mudar esse estado. 213 | 214 | No código acim estamos simplesmente retornando falso se o número for divisível por outro menor que ele e maior que 2. 215 | 216 | Caso você não tenha entendido essa linha: 217 | 218 | ```js 219 | for(let contador = 2; contador < 4; contador++) 220 | ``` 221 | 222 | A função `for` recebe 3 parâmetros: 223 | 224 | - atribuição do valor inicial do contador; 225 | - teste para saída do *looping*; 226 | - incrementação(adição de 1) do contador. 227 | 228 | Precisamos de um contador para poder saber quantos *loopings* ele fez e para poder sair dele, pois caso você coloque um teste que nunca dê falso o `for` *NUNCA* sairá do *looping*. 229 | 230 | Sabendo disso entendemos que o contador irá de 2 até < 4, fazendo o que? 231 | 232 | ```js 233 | if(numero/contador === 0) 234 | ``` 235 | 236 | **ISSO MESMO!!!** Testando a divisão entre o `numero`(4) e o `contador` que terá um valor diferente a cada *loop*, sendo que esse valor inicia em 2 e vai sendo **incrementado em 1** por causa do terceiro parâmetro do `for`. 237 | 238 | Então você percebeu que aquele `contador++` é o tal do incrementador né? 239 | 240 | Ele simplesmente adiciona 1 ao valor do `contador` cada vez que passa. 241 | 242 | Agora refatoramos o algoritmo para encapsular a lógica do número primo em uma função: 243 | 244 | ```js 245 | const isInteger = (numero) => { 246 | let inteiro = false; 247 | if(Number.isInteger(numero)) { 248 | inteiro = true; 249 | } 250 | console.log('O número '+numero+' é inteiro?', inteiro); 251 | return inteiro; 252 | } 253 | 254 | const isPrime = (numero) => { 255 | if(isInteger(numero/2)) { 256 | return false; 257 | } 258 | for(let contador = 3; contador < numero; contador++) { 259 | // Preciso testar se o número tem algum divisor entre ele e 1 260 | // Se não achar nenhum divisor ele será PRIMO 261 | let resultado = numero/contador; 262 | if(isInteger(resultado)) { 263 | return false; 264 | } 265 | } 266 | return true; 267 | } 268 | const numero = 273; 269 | const primo = isPrime(numero); 270 | 271 | console.log('O número '+numero+' é primo?', primo); 272 | ``` 273 | 274 | ## Testando o resto da divisão se é igual a 0 275 | 276 | Podemos resolver o mesmo problema com uma abordagem diferente, em vez de testar o resultado da divisão iremos testar se o resto dessa divisão é igual a 0. 277 | 278 | Vamos reusar o algoritmo passado: 279 | 280 | ```js 281 | // Definimos o estado atual 282 | let primo = false; 283 | const numero = 5; 284 | // Não preciso testar se é divisível por 1 nem 2 285 | for(let contador = 2; contador < numero; contador++) { 286 | // Preciso testar se o número tem algum divisor entre ele e 1 287 | // Se não achar nenhum divisor ele será PRIMO 288 | let resultado = numero/contador; 289 | if(isInteger(resultado) === false) { 290 | primo = true; 291 | } 292 | console.log('Contador: ', contador); 293 | console.log('Resultado: ', resultado); 294 | // Como definimos o estado inicial em FALSE 295 | // Só mudaremos ele se for PRIMO, porém usado a mesma variável 296 | console.log('O número '+numero+' é primo?', primo); 297 | return primo; 298 | } 299 | ``` 300 | 301 | Como iremos trabalhar com o valor do **resto** da divisão precisamos inicialmente conhecer esse conceito. 302 | 303 | **O que é esse resto?** 304 | 305 | Para exemplificar melhor acompanhe aqui comigo: 306 | 307 | ``` 308 | 4 / 2 = 2 309 | ``` 310 | 311 | A divisão de 4 por 2 resulta em 2 e tem 0 como resto, pois: 312 | 313 | ``` 314 | 4 |2 315 | -4 2 316 | 0 317 | ``` 318 | 319 | Vamos ver com um número ímpar: 320 | 321 | ``` 322 | 4 |3 323 | -3 1.3 324 | 10 325 | -9 326 | 1 327 | ... é uma dízima periódica 328 | ``` 329 | 330 | Logo você percebe que se o número a ser dividido(4), o dividendo, pelo divisor(3) não encontrar um resultado inteiro você deverá adicionar uma casa decimal (colocando a vírgula), fazendo isso você deve multiplicar o **resto** por 10, pois adicionou a vírgula no resultado, e continuar a divisão normalmente. 331 | 332 | Ótimo então já sabemos dividir (hehehe) agora vamos criar um algoritmo para verificar o resto de uma divisão: 333 | 334 | ```js 335 | const divisor = 4; 336 | const dividendo = 3 337 | 338 | const calculateRest = (divisor, dividendo) => { 339 | const resultado = divisor/dividendo; 340 | console.log('resultado: ', resultado); 341 | return divisor - (dividendo * parseInt(resultado)); 342 | } 343 | ``` 344 | 345 | Porém como as linguagens de programação vieram para facilitar nossa vida nós não precisaremos utilizar a função acima para retornar o resto, utilizaremos o [operador de módulo](https://pt.wikipedia.org/wiki/Opera%C3%A7%C3%A3o_m%C3%B3dulo) ou também conhecido como **mod**, [no JavaScript usamos o operador %](). 346 | 347 | ```js 348 | const calculateRest = (dividendo, divisor) => { 349 | const resultado = dividendo/divisor; 350 | console.log('resultado: ', resultado); 351 | return (dividendo - (divisor * parseInt(resultado))); 352 | } 353 | 354 | const isInteger = (numero) => { 355 | let inteiro = false; 356 | if(Number.isInteger(numero)) { 357 | inteiro = true; 358 | } 359 | console.log('O número '+numero+' é inteiro?', inteiro); 360 | return inteiro; 361 | } 362 | 363 | const isPrime = (numero) => { 364 | if(isInteger(numero/2)) { 365 | return false; 366 | } 367 | for(let contador = 3; contador < numero; contador++) { 368 | if(!calculateRest(numero, contador)) { 369 | return false; 370 | } 371 | } 372 | return true; 373 | } 374 | const numero = 5; 375 | const primo = isPrime(numero); 376 | console.log('O número '+numero+' é primo?', primo); 377 | ``` 378 | 379 | Dessa vez nós reusamos as funções passadas `isInteger` e `isPrime`, criando a função `calculateRest` que irá retornar o valor do resto da divisão para testarmos se ele é diferente de 0, **pois se o resto for 0 o `numero` encontrou um divisor**. 380 | 381 | Quero que você analise essa linha comigo: 382 | 383 | ```js 384 | if(!calculateRest(numero, contador)) 385 | ``` 386 | 387 | **Por que não estou testando se o resultado de `calculateRest(numero, contador)` é diferente de 0?** 388 | 389 | Pense aqui comigo, o retorno da função `calculateRest` será um inteiro, caso seja 0 significa que o número achou seu divisor, logo não é primo, por isso retornamos `false`: 390 | 391 | ```js 392 | for(let contador = 3; contador < numero; contador++) { 393 | if(!calculateRest(numero, contador)) { 394 | return false; 395 | } 396 | } 397 | ``` 398 | 399 | Então como o valor 0 que significa `false` entrou no `if` onde só pode entrar caso o valor seja `true`, no JavaScript também usamos o valor `0` para `false` e o valor `1` (ou maiores que 0) para `true`. 400 | 401 | **Agora que vem a malandragem da lógica!** 402 | 403 | Para o valor `0` entrar no if nós precisamos inverter seu valor já para Booleano(`true` ou `false`). Confira executando isso no seu console: 404 | 405 | ``` 406 | !0 407 | true 408 | !1 409 | false 410 | ``` 411 | 412 | E pronto! 413 | 414 | ## Desafio 415 | 416 | **Agora o seu desafio é inverter a lógica!** 417 | 418 | Em vez de iniciar do 3 você deverá iniciar do valor passado a ser testado, ou seja, em vez de incrementar você irá decrementar. 419 | 420 | **E também deverá criar um algoritmo para retornar `true` ou `false` caso um número seja Inteiro, utilizando-o em vez da função parseInt().** 421 | 422 | ## Dividindo por √¯n 423 | 424 | Caso não esteja familiarizado com o algoritmo da radiciação [leia mais nesse meu conteúdo](https://github.com/Webschool-io/matematica-para-programadores#radiciação-1), nele eu deduzi uma fórmula "simples" para números inteiros positivos: 425 | 426 | ``` 427 | √¯y = x 428 | 429 | y/x = x 430 | ``` 431 | 432 | Ela pode ser provada da seguinte forma: 433 | 434 | ``` 435 | √¯49 = x 436 | 49 = x ^ 2 437 | 49 = x . x 438 | 49/x = x 439 | 49/7 = 7 440 | ``` 441 | 442 | Nesse caso sabemos que qualquer número divido pela sua raíz quadrada será a própria raíz, ou seja, qualquer número pode ser escrito como a multiplicação de dois números. 443 | 444 | Sabendo disso podemos inferir que um número `x` pode ser escrito como uma multiplicação de 2 números inteiros e positivos menores que ele, sendo a multiplicação da sua raíz por ela mesma o maior valor. 445 | 446 | Agora podemos melhorar nosso algoritmo não precisando dividir por todos seus antecessores, bastando iniciar da raíz do número até 2. 447 | 448 | Veja o que mudaremos dentro da função `isPrime`: 449 | 450 | ```js 451 | const isPrime = (numero) => { 452 | 453 | if(isInteger(numero/2)) { 454 | return false; 455 | } 456 | 457 | const raiz = Math.sqrt(numero); 458 | 459 | if(raiz > 2) { 460 | for(let contador = 3; contador < raiz; contador++) { 461 | if(!calculateRest(numero, contador)) { 462 | return false; 463 | } 464 | } 465 | return true; 466 | } 467 | } 468 | ``` 469 | 470 | Logo após o teste pra verificar se é par em `if(isInteger(numero/2))` adicionei o cálculo da raíz quarada utilizando a função `Math.sqrt(numero)`. 471 | 472 | Para na sequência testar se a `raiz` é maior que `2` para garantir que não entrarei nesse `if` caso o `numero` seja menor que 4, que é par. 473 | 474 | Depois bastou modificar o teste de saída do `for` para `contador < raiz`, poupando-nos **muito processamento**. 475 | 476 | Apenas observe nosso algoritmo antes: 477 | 478 | ``` 479 | 37 / 2 = 18.5 480 | O número 18.5 é inteiro? false 481 | 37/3 12.333333333333334 482 | 37/4 9.25 483 | 37/5 7.4 484 | 37/6 6.166666666666667 485 | 37/7 5.285714285714286 486 | 37/8 4.625 487 | 37/9 4.111111111111111 488 | 37/10 3.7 489 | 37/11 3.3636363636363638 490 | 37/12 3.0833333333333335 491 | 37/13 2.8461538461538463 492 | 37/14 2.642857142857143 493 | 37/15 2.466666666666667 494 | 37/16 2.3125 495 | 37/17 2.176470588235294 496 | 37/18 2.0555555555555554 497 | 37/19 1.9473684210526316 498 | 37/20 1.85 499 | 37/21 1.7619047619047619 500 | 37/22 1.6818181818181819 501 | 37/23 1.608695652173913 502 | 37/24 1.5416666666666667 503 | 37/25 1.48 504 | 37/26 1.4230769230769231 505 | 37/27 1.3703703703703705 506 | 37/28 1.3214285714285714 507 | 37/29 1.2758620689655173 508 | 37/30 1.2333333333333334 509 | 37/31 1.1935483870967742 510 | 37/32 1.15625 511 | 37/33 1.121212121212121 512 | 37/34 1.088235294117647 513 | 37/35 1.0571428571428572 514 | 37/36 1.0277777777777777 515 | O número 37 é primo? true 516 | ``` 517 | 518 | E agora com o algoritmo otimizado: 519 | 520 | ``` 521 | 37 / 2 = 18.5 522 | O número 18.5 é inteiro? false 523 | 37/3 12.333333333333334 524 | 37/4 9.25 525 | 37/5 7.4 526 | 37/6 6.166666666666667 527 | O número 37 é primo? true 528 | ``` 529 | 530 | **Saímos de 37 operações para apenas 7!** E claro que esse número pode aumentar **MUITO!!!** 531 | 532 | 533 | 534 | -------------------------------------------------------------------------------- /Math/Números primos/algol-Resto.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const divisor = 4; 4 | const dividendo = 3 5 | 6 | const calcularResto = (divisor, dividendo) => { 7 | const resultado = divisor/dividendo; 8 | console.log('resultado: ', resultado); 9 | return divisor - (dividendo * parseInt(resultado)); 10 | } 11 | 12 | console.log('resto: ', calcularResto(divisor, dividendo)); 13 | 14 | -------------------------------------------------------------------------------- /Math/Números primos/algol-Resto.mdown: -------------------------------------------------------------------------------- 1 | const -------------------------------------------------------------------------------- /Math/Números primos/algol-testaPrimo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const isInteger = (numero) => { 4 | let inteiro = false; 5 | if(Number.isInteger(numero)) { 6 | inteiro = true; 7 | } 8 | console.log('O número '+numero+' é inteiro?', inteiro); 9 | return inteiro; 10 | } 11 | 12 | const isPrime = (numero) => { 13 | if(isInteger(numero/2)) { 14 | return false; 15 | } 16 | for(let contador = 3; contador < numero; contador++) { 17 | // Preciso testar se o número tem algum divisor entre ele e 1 18 | // Se não achar nenhum divisor ele será PRIMO 19 | let resultado = numero/contador; 20 | if(isInteger(resultado)) { 21 | return false; 22 | } 23 | } 24 | return true; 25 | } 26 | const numero = 273; 27 | const primo = isPrime(numero); 28 | 29 | console.log('O número '+numero+' é primo?', primo); 30 | -------------------------------------------------------------------------------- /Math/Números primos/algol-testaPrimoResto.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const calculateRest = (dividendo, divisor) => { 4 | const resultado = dividendo/divisor; 5 | console.log(dividendo+'/'+divisor, resultado); 6 | return (dividendo - (divisor * parseInt(resultado))); 7 | } 8 | 9 | const isInteger = (numero) => { 10 | let inteiro = false; 11 | if(Number.isInteger(numero)) { 12 | inteiro = true; 13 | } 14 | console.log('O número '+numero+' é inteiro?', inteiro); 15 | return inteiro; 16 | } 17 | 18 | const isPrime = (numero) => { 19 | console.log(numero+' / 2 = ', numero/2); 20 | if(isInteger(numero/2)) { 21 | return false; 22 | } 23 | for(let contador = 3; contador < numero; contador++) { 24 | if(!calculateRest(numero, contador)) { 25 | return false; 26 | } 27 | } 28 | return true; 29 | } 30 | const numero = 37; 31 | const primo = isPrime(numero); 32 | console.log('O número '+numero+' é primo?', primo); 33 | 34 | -------------------------------------------------------------------------------- /Math/Números primos/algol-testaPrimoRestoInvertido.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const calculateRest = (dividendo, divisor) => { 4 | const resultado = dividendo/divisor; 5 | console.log(dividendo+'/'+divisor, resultado); 6 | return (dividendo - (divisor * parseInt(resultado))); 7 | } 8 | 9 | const isInteger = (numero) => { 10 | let inteiro = false; 11 | if(Number.isInteger(numero)) { 12 | inteiro = true; 13 | } 14 | console.log('O número '+numero+' é inteiro?', inteiro); 15 | return inteiro; 16 | } 17 | 18 | const isPrime = (numero) => { 19 | if(isInteger(numero/2)) { 20 | return false; 21 | } 22 | for(let contador = numero-1; contador <= numero; contador--) { 23 | if(contador === 2) { 24 | break; 25 | } 26 | console.log(numero+'/'+contador, numero/contador); 27 | if(!calculateRest(numero, contador)) { 28 | return false; 29 | } 30 | } 31 | return true; 32 | } 33 | const numero = 25; 34 | const primo = isPrime(numero); 35 | console.log('O número '+numero+' é primo?', primo); 36 | 37 | -------------------------------------------------------------------------------- /Math/Números primos/algol-testaPrimoRestoRaiz.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const calculateRest = (dividendo, divisor) => { 4 | const resultado = dividendo/divisor; 5 | console.log(dividendo+'/'+divisor, resultado); 6 | return (dividendo - (divisor * parseInt(resultado))); 7 | } 8 | 9 | const isInteger = (numero) => { 10 | let inteiro = false; 11 | if(Number.isInteger(numero)) { 12 | inteiro = true; 13 | } 14 | console.log('O número '+numero+' é inteiro?', inteiro); 15 | return inteiro; 16 | } 17 | 18 | const isPrime = (numero) => { 19 | console.log(numero+' / 2 = ', numero/2); 20 | if(isInteger(numero/2)) { 21 | return false; 22 | } 23 | 24 | const raiz = Math.sqrt(numero); 25 | if(raiz > 2) { 26 | for(let contador = 3; contador < raiz; contador++) { 27 | if(!calculateRest(numero, contador)) { 28 | return false; 29 | } 30 | } 31 | return true; 32 | } 33 | } 34 | 35 | const numero = 37; 36 | const primo = isPrime(numero); 37 | console.log('O número '+numero+' é primo?', primo); 38 | 39 | -------------------------------------------------------------------------------- /Math/Números primos/algol-testaResto.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let inteiro = false; 4 | const numero = 4; 5 | const divisor = 3; 6 | const resto = numero/divisor; 7 | 8 | const isInteger = (numero) => { 9 | let inteiro = false; 10 | if(Number.isInteger(numero)) { 11 | inteiro = true; 12 | } 13 | 14 | console.log('O número '+numero+' é inteiro?', inteiro); 15 | return inteiro; 16 | } 17 | 18 | isInteger(resto); -------------------------------------------------------------------------------- /Math/Números primos/algol-teste.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const numero = 4; 4 | // Definimos o estado atual 5 | let primo = false; 6 | // Não preciso testar se é divisível por 1 7 | for(let contador = 2; contador < 4; contador++) { 8 | // Preciso testar se o número tem algum divisor entre ele e 1 9 | // Se não achar nennhum divisor ele será PRIMO 10 | console.log(numero+'/'+contador, numero/contador) 11 | if(numero/contador !== 0) { 12 | primo = true; 13 | } 14 | } 15 | // Como definimos o estado inicial em FALSE 16 | // Só mudaremos ele qse for PRIMO, porém usado a mesma variável 17 | console.log(primo); -------------------------------------------------------------------------------- /Math/Números primos/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const testaNumeroPrimo = (numero) => { 4 | let primo = false; 5 | for(let contador = 2; contador <=4; contador++) { 6 | console.log(numero+'/'+contador, numero/contador) 7 | if(!numero/contador) { 8 | primo = true; 9 | } 10 | return primo; 11 | } 12 | } 13 | 14 | console.log(testaNumeroPrimo(84)); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algoritmos 2 | 3 | Algoritmos para todas as coisas da vida. 4 | --------------------------------------------------------------------------------