Sono un numero 'Redivosite'?


26

Redivosite è una parola portmanteau inventata al solo scopo di questa sfida. È un mix di riduzione, divisione e composito.

Definizione

Dato un numero intero N> 6 :

  • Se N è il numero primo, N non è un numero redivitato.
  • Se N è composto:
    • calcola ripetutamente N '= N / d + d + 1 fino a quando N' è primo, dove d è il divisore più piccolo di N maggiore di 1
    • N è un numero ridiviso se e solo se il valore finale di N ' è un divisore di N

Di seguito sono riportati i primi 100 numeri ridivisi (nessuna voce OEIS al momento della pubblicazione):

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

Esempi

  • N = 13 : 13 è primo, quindi 13 non è un numero redivosito
  • N = 32 : 32/2 + 3 = 19; 19 non è un divisore o 32, quindi 32 non è un Numero ridiviso
  • N = 260 : 260/2 + 3 = 133, 133/7 + 8 = 27, 27/3 + 4 = 13; 13 è un divisore o 260, quindi 260 è un numero ridiviso

Il tuo compito

  • Dato un numero intero N , restituisce un valore di verità se è un numero ridiviso o un valore di falsa in caso contrario. (È anche possibile generare due valori distinti, purché coerenti.)
  • L'ingresso è garantito per essere maggiore di 6 .
  • Questo è , quindi vince la risposta più breve in byte!

13
Vorrei davvero che tutte queste sfide della "sequenza numerica", che sono solo sequenze di numeri con una certa proprietà, fossero poste come problemi di decisione. Dubito fortemente che ci sia un modo per generarli direttamente, quindi l'unica soluzione possibile è risolvere il problema decisionale e quindi inserirlo in un ciclo che trova l'ennesimo o il primo N o tutti gli interi che soddisfano questa proprietà.
Martin Ender,

3
Mi piacciono le sfide in sequenza che non sono problemi di decisione in generale, ma per questo penso che un problema di decisione sia più adatto. Non vedo alcuna relazione tra i termini tali che si stampa il n ° o il primo n in modo intelligente, così forse consentire di prendere n come input e controllando se è redivosite ?
Mr. Xcoder,

1
@MartinEnder & Mr.Xcoder Questa era la mia intenzione iniziale (da qui il titolo originale a cui ho appena eseguito il rollback) e ho cambiato idea. Immagino che questo non dovrebbe rovinare alcuna soluzione WIP (per i motivi che dici), quindi l'ho modificato.
Arnauld,

5
@ Mr.Xcoder Sì, questo è ciò che intendevo. Non mi dispiace le sfide della sequenza che in realtà hanno senso come sequenza (o perché puoi calcolare a(n)direttamente, o perché puoi calcolare un termine da quelli precedenti). Grazie, Arnauld, per aver cambiato la sfida. :)
Martin Ender il

Risposte:


9

Haskell, 91 85 83 80 75 74 byte

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

Provalo 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

Modifica: -2 byte grazie a @BMO, -3 byte grazie a @ H.PWiz e -5 -6 byte grazie a @ Ørjan Johansen



In realtà,
rendilo

@ ØrjanJohansen: grazie ancora.
nimi,


6

C (gcc) , 94 89 byte

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;}

Provalo online!

Spiegazione

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 byte

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

Provalo online!

Come funziona

ÆḌḊ         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 byte

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

Provalo online!

Uscite tramite codice di uscita.

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.

Provalo online!


3

05AB1E , 17 16 byte

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

Provalo online!

Spiegazione

[                  # 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

Pyth , 20 byte

<P_QiI.WtPHh+/ZKhPZK

Provalo qui!

Come funziona

iI.WtPHh + / ZKhPZK || Programma completo.

  .W || Funzionale mentre. Ci vogliono due funzioni come argomenti, A e B.
                 || Mentre A (valore) è vero, trasforma il valore in B (valore). Il
                 || il valore iniziale è l'input.
    tPH || Prima funzione, A. Prende un singolo argomento, H.
     PH || .. I fattori primi fattori di H.
    t || .. Coda (rimuovi il primo elemento). Mentre in verità (H è composito):
       h + / ZKhPZK || La seconda funzione, B. Prende un singolo argomento, Z:
         / Z || .. Dividi Z, per:
           KhP || .. Il suo fattore primo più basso e assegnalo a K.   
       h || .. Incremento.
        + K || E aggiungi K.
iI || Controlla se il risultato (ultimo valore) divide l'input.

E i primi 4 byte ( <P_Q) controllano solo se l'input non è primo.

Con l'aiuto di Emigna , sono riuscito a salvare 3 byte.


Puoi usare qualcosa di simile al head(P)posto della fiITZ2parte, poiché il divisore più piccolo maggiore di 1 sarà sempre un numero primo?
Emigna,

@Emigna Ninja'd, risolto e grazie!
Mr. Xcoder

2

Python 3 , 149 byte

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

Provalo online!

Utilizzando un approccio setaccio. Dovrebbe essere veloce ( O(N log log N)= complessità temporale del setaccio di Eratostene) anche con grandi N(ma memorizza O(N)numeri interi in memoria)

Nota:

  • Si può dimostrare che tutti i valori intermedi di nnon superano Ne che N > 7 ppuò essere presente range(2,N)anziché range(2,N+1)per setacciatura.
  • /non funziona, //deve essere utilizzato, a causa dell'indice dell'elenco.
  • La memorizzazione rangein un'altra variabile non aiuta, sfortunatamente.

Spiegazione:

  • -~N== N+1.
  • Inizialmente, l'array sè inizializzato con N+1zero (Python è 0-indicizzazione, quindi gli indici sono 0..N)
  • Dopo l'inizializzazione, s[n]ci si aspetta che sia 0se nè un numero primo e pper pil primo minimo che divide nse nè un composto. s[0]e i s[1]valori non sono importanti.
  • Per ciascuno pnella gamma [2 .. N-1]:

    • Se s[p] < 1(cioè, s[p] == 0), allora pè un numero primo, e per ognuno di essi qè un multiplo di pe s[q] == 0, assegnare s[q] = p.
  • Le ultime 2 righe sono semplici, tranne che n//s[n]-~s[n]== (n // s[n]) + s[n] + 1.


Python 3 , 118 byte

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

Provalo online!

A scapito di prestazioni leggermente peggiori. (Questo viene eseguito in O(N log N)termini di complessità temporale, ipotizza un'implementazione ragionevole delle sezioni Python)


Il programma completo equivalente è di 117 byte .


È possibile utilizzare n//s[n]-~s[n]anziché n//s[n]+s[n]+1per 149 byte.
Mr. Xcoder

@ Mr.Xcoder Grazie!
user202729

Inoltre penso che or ppossa essere|p
Mr. Xcoder il

@ Mr.Xcoder No, or pesegue logico o, mentre |pesegue bit a bit o. Cioè, lo a or bè b if a == 0 else a.
user202729

È possibile modificare l'esterno forper utilizzare la sezione anziché un'altrafor . Il rangesimbolo è invertito, quindi gli indici più bassi sovrascriveranno quelli più grandi, e iniziare la sezione su di 2*pte non sostituirà s[0]o s[p].
Rod




1

Japt, 25 24 byte

Temo di essere andato nella direzione sbagliata con questo, ma ho esaurito il tempo per provare un approccio diverso.

Output 0per false o 1true.

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

Provalo


0

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

Darn Perl per non avere un controllore principale 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;}}}

Versione Ungolfed,

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;
        }
    }
}

Provalo online!



0

Pulito , 128 117 114 byte

import StdEnv
@n#v=hd[p\\p<-[2..]|and[gcd p i<2\\i<-[2..p-1]]&&n rem p<1]
|v<n= @(n/v+v+1)=n
?n= @n<n&&n rem(@n)<1

Provalo online!


0

J , 35 byte

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

Provalo online!

Il divisore minimo essendo il primo fattore primo è stato rubato dalla soluzione Jelly di @ Dennis (precedentemente stavo usando <./@q:).

Dovrebbe esserci un modo migliore per eseguire l'iterazione, ma non riesco a trovarlo. Ho pensato di evitare di fare il test di primalità ( ^:(0&p:)) e invece di usare gli effetti negativi, ma sembra che sarà un po 'più lungo poiché avrai bisogno di _2{alcuni cambiamenti che potrebbero non dare una riduzione netta.

Sento davvero che ci deve essere un modo per evitare di avere anche genitori attorno al controllo della primalità.

Spiegazione (ampliata)

(~: * 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

APL NARS, 43 caratteri, 85 byte

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

(sperando che converga per tutti i numeri> 6) test:

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  

L'idea di utilizzare 2 funzioni anonime arriva ad un'altra soluzione 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 byte

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

Vedi il codice sotto per una spiegazione - le uniche differenze sono (1) che N è diminuito prima di tenere conto dell'incremento all'inizio del ciclo e (2) usa NOR invece di OR.

Provalo online!



L'ho fatto prima di rileggere la domanda e ho notato che voleva solo un vero / falso.

Pyt, 52 byte

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

Stampa un elenco infinito di numeri Redivosite.

Spiegazione:

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)


Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.