Eu sou um número 'redivosita'?


26

Redivosite é uma palavra portmanteau inventada com o único objetivo deste desafio. É uma mistura de redução, divisão e composto.

Definição

Dado um número inteiro N> 6 :

  • Se N é primo, N não é um número redivosita.
  • Se N for composto:
    • calcule N '= N / d + d + 1 repetidamente até N' ser primo, em que d é o menor divisor de N maior que 1
    • N é um número redivosito se e somente se o valor final de N ' for um divisor de N

Abaixo estão os 100 primeiros números de redivosite (nenhuma entrada do OEIS no momento da postagem):

14,42,44,49,66,70,143,153,168,169,176,195,204,260,287,294,322,350,414,462,518,553,572,575,592,629,651,702,726,735,775,806,850,869,889,891,913,950,1014,1023,1027,1071,1118,1173,1177,1197,1221,1235,1254,1260,1302,1364,1403,1430,1441,1554,1598,1610,1615,1628,1650,1673,1683,1687,1690,1703,1710,1736,1771,1840,1957,1974,2046,2067,2139,2196,2231,2254,2257,2288,2310,2318,2353,2392,2409,2432,2480,2522,2544,2635,2640,2650,2652,2684,2717,2758,2760,2784,2822,2835

Exemplos

  • N = 13 : 13 é primo, então 13 não é um número redivosita
  • N = 32 : 32/2 + 3 = 19; 19 não é um divisor ou 32, então 32 não é um número redivosito
  • N = 260 : 260/2 + 3 = 133, 133/7 + 8 = 27, 27/3 + 4 = 13; 13 é um divisor ou 260, então 260 é um número redivosita

Sua tarefa

  • Dado um número inteiro N , retorne um valor verdadeiro se for um Número Redivosita ou um valor falso, caso contrário. (Você também pode gerar dois valores distintos, desde que sejam consistentes.)
  • A entrada é garantida para ser maior que 6 .
  • Isso é , então a resposta mais curta em bytes vence!

13
Eu realmente gostaria que todos esses desafios da "sequência numérica", que são apenas sequências de números com uma determinada propriedade, fossem solicitados como problemas de decisão. Eu duvido muito que exista alguma maneira de gerá-los diretamente, portanto a única solução possível é resolver o problema de decisão e envolvê-lo em um loop que encontre o enésimo ou o primeiro N ou todos os números inteiros que satisfazem essa propriedade.
Martin Ender

3
Gosto de desafios de sequência que não são problemas de decisão em geral, mas para este acho que um problema de decisão seria mais adequado. Não vejo relação entre os termos, de modo que você imprima o n- ésimo ou o primeiro n de maneira inteligente, então talvez permita tomar n como entrada e verificar se é redivosita ?
Sr. Xcoder

1
@ MartinMnder & Mr.Xcoder Essa foi minha intenção inicial (daí o título original que acabei de reverter) e mudei de idéia. Eu acho que isso não deve arruinar nenhuma solução WIP (pelas razões que você diz), então eu a editei.
Arnauld

5
@ Mr.Xcoder Sim, foi isso que eu quis dizer. Não me importo com os desafios de sequência que, na verdade, fazem sentido como uma sequência (porque você pode calcular a(n)diretamente ou porque pode calcular um termo dos anteriores). Obrigado, Arnauld, por mudar o desafio. :)
Martin Ender

Respostas:


9

Haskell, 91 85 83 80 75 74 bytes

n#m=([n#(div m d+d+1)|d<-[2..m-1],mod m d<1]++[mod n m<1&&m<n])!!0
f x=x#x

Experimente online!

f x=x#x                           -- call # with x for both parameters
n#m               
         |d<-[2..m-1],mod m d<1   -- for all divisors d of m
    [n#(div m d+d+1)           ]  -- make a list of recursive calls to #,
                                  -- but with m set to m/d+d+1
   ++ [mod n m<1&&m<n]            -- append the Redivosite-ness of n (m divides n,
                                  -- but is not equal to n)
                           !!0    -- pick the last element of the list
                                  -- -> if there's no d, i.e. m is prime, the
                                  --    Redivosite value is picked, else the
                                  --    result of the call to # with the smallest d

Edit: -2 bytes graças a @BMO, -3 bytes graças a @ H.PWiz e -5 -6 bytes graças a @ Ørjan Johansen




@ ØrjanJohansen: Obrigado novamente.
nimi


6

C (gcc) , 94 89 bytes

m,n;o(k){for(m=1;m++<k;)if(k%m<1)return m;}
F(N){for(n=N;m=o(n),m-n;n=n/m-~m);N=m<N>N%n;}

Experimente online!

Explicação

m,n;                  // two global integers
o(k){                 // determine k's smallest divisor
 for(m=1;m++<k;)      // loop through integers 2 to n (inclusive)
  if(k%m<1)return m;} // return found divisor
F(N){                 // determine N's redivosity
 for(n=N;             // save N's initial value
  m=o(n),             // calculate n's smallest divisor (no name clash regarding m)
  m-n;                // loop while o(n)!=n, meaning n is not prime
                      //  (if N was prime, the loop will never be entered)
  n=n/m-~m);          // redivosite procedure, empty loop body
 N=m<N>N%n;}          // m<N evaluates to 0 or 1 depending on N being prime,
                      //  N%n==0 determines whether or not N is divisible by n,
                      //  meaning N could be redivosite => m<N&&N%n==0
                      //  <=> m<N&&N%n<1 <=> m<N&&1>N%n <=> (m<N)>N%n <=> m<N>N%n

4

Gelatina , 14 bytes

ÆḌḊ
Ç.ịS‘µÇ¿eÇ

Experimente online!

Como funciona

ÆḌḊ         Helper link. Argument: k

ÆḌ          Yield k's proper (including 1, but not k) divisors.
  Ḋ         Dequeue; remove the first element (1).


Ç.ịS‘µÇ¿eÇ  Main link. Argument: n

     µ      Combine the links to the left into a chain.
      Ç¿    While the helper link, called with argument n, returns a truthy result,
            i.e., while n is composite, call the chain to the left and update n.
Ç             Call the helper link.
 .ị           At-index 0.5; return the elements at indices 0 (last) and 1 (first).
              This yields [n/d, d].
   S          Take the sum.
    ‘         Increment.
        Ç   Call the helper link on the original value of n.
       e    Test if the result of the while loop belongs to the proper divisors.

4

Python 2 , 97 91 bytes

r=0;e=d=i=input()
while r-e:e=i;r=[j for j in range(2,i+1)if i%j<1][0];i=i/r-~r
d%e<1<d/e<q

Experimente online!

Saídas via código de saída.

Ungolfed:

r = 0                             # r is the lowest divisor of the current number,
                                  # initialized to 0 for the while loop condition.
e = d = i = input()               # d remains unchanged, e is the current number
                                  # and i is the next number.
while r != e:                     # If the number is equal to its lowest divisor,
                                  # it is prime and we need to end the loop.
    e = i                         # current number := next number
    r = [j for j in range(2, i+1) # List all divisors of the number in the range [2; number + 1)
         if i%j < 1][0]           # and take the first (lowest) one.
    i = i/r+r+1                   # Calculate the next number.
                                  # We now arrived at a prime number.
print d%e == 0 and d != e         # Print True if our current number divides the input
                                  # and is distinct from the input.
                                  # If our current number is equal to the input,
                                  # the input is prime.

Experimente online!


3

05AB1E , 17 16 bytes

[Dp#Òć©sP+>]Ö®p*

Experimente online!

Explicação

[                  # start loop
 Dp#               # break if current value is prime
    Ò              # get prime factors of current value
     ć©            # extract the smallest (d) and store a copy in register
       sP          # take the product of the rest of the factors
         +>        # add the smallest (d) and increment
           ]       # end loop
            Ö      # check if the input is divisible by the resulting prime
             ®p    # check if the last (d) is prime (true for all composite input)
               *   # multiply

2

Pitão , 20 bytes

<P_QiI.WtPHh+/ZKhPZK

Experimente aqui!

Como funciona

iI.WtPHh + / ZKhPZK || Programa completo.

  .W || Enquanto funcional. São necessárias duas funções como argumentos, A e B.
                 || Enquanto A (valor) for verdadeiro, transforme o valor em B (valor). o
                 || valor inicial é a entrada.
    tPH || Primeira função, A. Pega um único argumento, H.
     PH || .. Os principais fatores fatores de H.
    t || .. Tail (remova o primeiro elemento). Enquanto a verdade (H é composto):
       h + / ZKhPZK || A segunda função, B. Aceita um único argumento, Z:
         / Z || .. Divida Z, por:
           KhP || .. Seu menor fator primo e atribui isso a K.   
       h || .. incremento.
        + K || E adicione K.
iI || Verifique se o resultado (último valor) divide a entrada.

E os primeiros 4 bytes ( <P_Q) apenas verificam se a entrada não está pronta.

Com a ajuda de Emigna , consegui salvar 3 bytes.


Você pode usar algo como em head(P)vez da fiITZ2peça, pois o menor divisor maior que 1 sempre será primo?
Emigna 04/01/19

@ Emigna Ninja'd, consertado e obrigado!
Sr. Xcoder

2

Python 3 , 149 bytes

def f(N):
	n=N;s=[0]*-~N
	for p in range(2,N):
		if s[p]<1:
			for q in range(p*p,N+1,p):s[q]=s[q]or p
	while s[n]:n=n//s[n]-~s[n]
	return s[N]>1>N%n

Experimente online!

Usando uma abordagem de peneira. Deve ser rápido ( O(N log log N)= complexidade temporal da peneira de Eratóstenes), mesmo com grandes N(mas armazena O(N)números inteiros na memória)

Nota:

  • Pode-se provar que todos os valores intermediários de nnão excedem Ne N > 7 ppodem ser range(2,N)inseridos em vez de range(2,N+1)peneirados.
  • /não funciona, //deve ser usado, devido ao índice da lista.
  • Armazenar rangeem outra variável não ajuda, infelizmente.

Explicação:

  • -~N== N+1.
  • Inicialmente, a matriz sé inicializada com N+1zeros (Python é indexação 0, então os índices são 0..N)
  • Após a inicialização, s[n]espera-se 0que seja se né um primo e ppara po primo mínimo que divide nse né um composto. s[0]e s[1]valores não são importantes.
  • Para cada um pno intervalo [2 .. N-1]:

    • Se s[p] < 1(isto é, s[p] == 0), então pé primo, e para cada qum é um múltiplo de pe s[q] == 0, atribua s[q] = p.
  • As duas últimas linhas são diretas, exceto que n//s[n]-~s[n]== (n // s[n]) + s[n] + 1.


Python 3 , 118 bytes

def f(N):
	n=N;s=[0]*-~N
	for p in range(N,1,-1):s[2*p::p]=(N-p)//p*[p]
	while s[n]:n=n//s[n]-~s[n]
	return s[N]>1>N%n

Experimente online!

À custa de um desempenho um pouco pior. (Este é executado com O(N log N)complexidade de tempo, assume uma implementação razoável de fatias do Python)


O programa completo equivalente é 117 bytes .


Você pode usar em n//s[n]-~s[n]vez de n//s[n]+s[n]+1para 149 bytes.
Xcoder

@ Mr.Xcoder Obrigado!
precisa saber é o seguinte

Também acho que or ppode ser|p
Sr. Xcoder

@ Mr.Xcoder Não, or pexecuta lógica ou, enquanto |pexecuta bit a bit ou. Isto é, a or bé b if a == 0 else a.
precisa saber é o seguinte

Você pode modificar o externo forpara usar a fatia em vez de outrafor . O rangeinverso é invertido; portanto, os índices mais baixos substituem os maiores, e iniciar a fatia em que 2*pvocê não substitui s[0]ou s[p].
Rod




1

Japonês, 25 24 bytes

Receio ter ido na direção errada com isso, mas fiquei sem tempo para tentar uma abordagem diferente.

Saídas 0para falso ou 1verdadeiro.

j ?V©vU :ßU/(U=k g)+°UNg

Tente


0

Perl 5 , 291 + 1 (-a) = 292 bytes

Maldito Perl por não ter um verificador primário nativo.

use POSIX;&r($_,$_);
sub p{$n=shift;if($n<=1){return;}if($n==2||$n==3){return 1;}if($n%2==0||$n%3==0){return;}for(5..ceil($n/2)){if($n%$_==0){return;}}return 1;}
sub r{$n=shift;$o=shift;if(&p($n)){print $o%$n==0&&$n!=$o?1:0;last;}for(2..ceil($n/2)){if($n%$_==0){&r(($n/$_)+$_+1, $o);last;}}}

Versão não destruída,

use POSIX;
&r($_,$_);
sub p{
    my $n=shift;
    if($n<=1){
        return;
    }
    if($n==2||$n==3){
        return 1;
    }
    if($n%2==0||$n%3==0){
        return;
    }
    for(5..ceil($n/2)){
        if($n%$_==0){
            return;
        }
    }
    return 1;
}
sub r{
    my $n=shift;
    my $o=shift;
    if(&p($n)){
        print $o%$n==0&&$n!=$o ? 1 : 0;
        last;
    }
    for(2..ceil($n/2)){
        if($n%$_==0){
            &r(($n/$_)+$_+1, $o);
            last;
        }
    }
}

Experimente online!




0

J , 35 bytes

(~:*0=|~)(1+d+]%d=.0{q:)^:(0&p:)^:_

Experimente online!

O divisor mínimo, sendo o primeiro fator principal, foi roubado da solução @ Dennis's Jelly (anteriormente eu estava usando <./@q:).

Deve haver uma maneira melhor de fazer a iteração, mas não consigo encontrá-la. Pensei em evitar fazer o teste de primalidade ( ^:(0&p:)) e usar o adverso, mas parece que será um pouco mais longo, pois você precisará de _2{algumas alterações que podem não gerar uma redução líquida.

Eu realmente sinto que deve haver uma maneira de evitar parens em torno da verificação de primalidade também.

Explicação (expandida)

(~: * 0 = |~)(1 + d + ] % d =. 0 { q:) ^: (0&p:) ^:_ Input: N
             (1 + d + ] % d =. 0 { q:) ^: (0&p:) ^:_ Find the final N'
                                       ^:        ^:_  Do while
                                           0&p:       N is not prime
                                   q:                 Get prime factors (in order)
                               0 {                    Take first (smallest divisor)
                          d =.                        Assign this value to d
             1 + d + ] %  d                           Compute (N/d) + 1 + d
(~: * 0 = |~)                                        Is it redivosite?
      0 = |~                                          N = 0 (mod N'), i.e. N'|N
    *                                                 And
 ~:                                                   N =/= N', i.e. N is not prime

0

NARS APL, 43 caracteres, 85 bytes

{(⍵≤6)∨0π⍵:0⋄⍵{1=⍴t←π⍵:0=⍵|⍺⋄⍺∇1+↑t+⍵÷↑t}⍵}

(na esperança de convergir para todos os números> 6):

h←{(⍵≤6)∨0π⍵:0⋄⍵{1=⍴t←π⍵:0=⍵|⍺⋄⍺∇1+↑t+⍵÷↑t}⍵}
v←⍳100     
v,¨h¨v
   1 0  2 0  3 0  4 0  5 0  6 0  7 0  8 0  9 0  10 0  11 0
   12 0  13 0  14 1  15 0  16 0  17 0  18 0  19 0  20 0  
   21 0  22 0  23 0  24 0  25 0  26 0  27 0  28 0  29 0  
   30 0  31 0  32 0  33 0  34 0  35 0  36 0  37 0  38 0  
   39 0  40 0  41 0  42 1  43 0  44 1  45 0  46 0  47 0  
   48 0  49 1  50 0  51 0  52 0  53 0  54 0  55 0  56 0  
   57 0  58 0  59 0  60 0  61 0  62 0  63 0  64 0  65 0  
   66 1  67 0  68 0  69 0  70 1  71 0  72 0  73 0  74 0  
   75 0  76 0  77 0  78 0  79 0  80 0  81 0  82 0  83 0  
   84 0  85 0  86 0  87 0  88 0  89 0  90 0  91 0  92 0  
   93 0  94 0  95 0  96 0  97 0  98 0  99 0  100 0  

A idéia de usar 2 funções anônimas chego a outra solução Apl.

 {(⍵≤60)∨π⍵:0⋄ -- if arg ⍵ is prime or <=6 return 0
  ⍵{1=⍴t←π⍵:0=⍵|⍺⋄ -- if list of factors ⍵ has length 1 (it is prime)
                    -- then return ⍺mod⍵==0
  ⍺∇1+↑t+⍵÷↑t}⍵}   -- else recall this function with args ⍺ and 1+↑t+⍵÷↑t

0

Pyt , 44 bytes

←⁻0`ŕ⁺ĐĐϼ↓Đ3Ș⇹÷+⁺Đṗ¬⇹⁻⇹łŕáĐ0⦋Đ↔ĐŁ⁻⦋⁺|¬⇹ṗ⇹3Ș⊽

Veja o código abaixo para obter uma explicação - as únicas diferenças são (1) que N é decrementado antes para contabilizar o incremento no início do loop e (2) ele usa NOR em vez de OR.

Experimente online!



Eu fiz isso antes de reler a pergunta e percebi que ela só queria um verdadeiro / falso.

Pyt, 52 bytes

60`ŕ⁺ĐĐϼ↓Đ3Ș⇹÷+⁺Đṗ¬⇹⁻⇹łŕáĐ0⦋Đ↔ĐŁ⁻⦋⁺|¬⇹Đṗ⇹3Ș∨ł⇹Đƥ⇹ŕ1ł

Imprime uma lista infinita de números redivositos.

Explicação:

6                                                            Push 6
 0                                                           Push unused character
  `                   ł                     ł      ł         Return point for all three loops
   ŕ                                                         Remove top of stack
    ⁺                                                        Increment top of stack (n)
     ĐĐ                                                      Triplicate top of stack (n)
       ϼ↓                                                    Get smallest prime factor of n (returns 1 if n is prime) 
         Đ                                                   Duplicate top of stack
          3Ș⇹                                                Manipulate stack so that the top is (in descending order): [d,(N,N'),d]
             ÷+⁺                                             Calculates N'=(N,N')/d+d+1
                Đṗ¬                                          Is N' not prime?
                   ⇹⁻⇹                                       Decrement N' (so the increment at the beginning doesn't change the value), and keep the boolean on top - end of innermost loop (it loops if top of stack is true)
                       ŕ                                     Remove top of stack
                        á                                    Convert stack to array
                         Đ                                   Duplicate array
                          0⦋Đ                                Get the first element (N)
                             ↔ĐŁ⁻⦋                           Get the last element ((final N')-1)
                                  ⁺                          Increment to get (final N')
                                   |¬                        Does N' not divide N?
                                     ⇹Đṗ                     Is N prime?
                                        ⇹3Ș∨                 Is N prime or does N' not divide N? - end of second loop (loops if top of stack is true)
                                             ⇹Đƥ⇹ŕ           Print N, and reduce stack to [N]
                                                  1          Push garbage (pushes 1 so that the outermost loop does not terminate)


Experimente online!

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.