Twist Divisore Iterato


13

definizioni

Lasciate med nessere numeri interi positivi. Diciamo che mè una svolta del divisoren se esistono numeri interi 1 < a ≤ btali che n = a*be m = (a - 1)*(b + 1) + 1. Se si mpuò ottenere napplicando zero o più colpi di scena divisori, allora mè un discendente di n. Si noti che ogni numero è il proprio discendente.

Ad esempio, considera n = 16. Possiamo scegliere a = 2e b = 8, da allora 2*8 = 16. Poi

(a - 1)*(b + 1) + 1 = 1*9 + 1 = 10

che mostra che 10è una svolta del divisore di 16. Con a = 2e b = 5, vediamo quindi che 7è una svolta del divisore di 10. Quindi 7è un discendente di 16.

L'obiettivo

Dato un numero intero positivo n, calcola i discendenti di n, elencati in ordine crescente, senza duplicati.

Regole

Non è consentito utilizzare le operazioni integrate che calcolano i divisori di un numero.

Sono accettati programmi e funzioni completi e è consentita la restituzione di un tipo di dati di raccolta (come un set di qualche tipo), purché sia ​​ordinato e duplicato. Vince il conteggio di byte più basso e non sono consentite scappatoie standard.

Casi test

1 ->  [1]
2 ->  [2] (any prime number returns just itself)
4 ->  [4]
16 -> [7, 10, 16]
28 -> [7, 10, 16, 25, 28]
51 -> [37, 51]
60 -> [7, 10, 11, 13, 15, 16, 17, 18, 23, 25, 28, 29, 30, 32, 43, 46, 49, 53, 55, 56, 60]

@Zgarb se consenti una catena di 0 colpi di scena divisori, come fa ogni numero a non discendere da qualsiasi altro numero?
rorlork,

3
@rcrmn Per me, una catena di zero operazioni indica l'operazione di identità. Pertanto, consentire zero colpi di scena divisori implica solo che ogni numero è un discendente di se stesso.
Zgarb,

@Zgarb va bene, quindi la definizione dovrebbe essere modificata per esprimere ciò, perché in caso contrario, per quanto ne so, qualsiasi numero è considerato un discendente di ogni altro numero. Non so perché sia ​​necessaria la riflessività. Ti andrebbe di spiegare?
rorlork,

@rcrmn Ho modificato leggermente il testo, ora è più chiaro?
Zgarb,

@Zgarb scusa ma no, non è un'operazione, stai definendo una relazione tra numeri. Se si definisce la relazione <per i numeri naturali, per ogni n si ottiene ogni numero più piccolo di esso ma non se stesso. Penso che questo dovrebbe essere qualcosa di simile. In questo modo penso che solo 4 sarebbe il suo discendente (non ne sono sicuro, però).
rorlork,

Risposte:


9

Python 2, 109 98 85 82 byte

f=lambda n:sorted(set(sum(map(f,{n-x+n/x for x in range(2,n)if(n<x*x)>n%x}),[n])))

Dal momento che (a-1)*(b+1)+1 == a*b-(b-a)e b >= a, i discendenti sono sempre inferiori o uguali al numero originale. Quindi possiamo solo iniziare con il numero iniziale e continuare a generare discendenti strettamente più piccoli fino a quando non ne rimane più nessuno.

La condizione (n<x*x)>n%xcontrolla due cose in una: quella n<x*xe n%x == 0.

(Grazie a @xnor per aver rimosso 3 byte dal case base)

Pyth, 32 byte

LS{s+]]bmydm+-bk/bkf><b*TT%bTr2b

Traduzione diretta di quanto sopra, tranne per il fatto che Pyth sembra soffocare quando cerca di sommare ( s) in un elenco vuoto.

Questo definisce una funzione yche può essere chiamata aggiungendo y<number>alla fine, in questo modo ( provalo online ):

LS{s+]]bmydm+-bk/bkf><b*TT%bTr2by60

CJam, 47 45 byte

{{:X_,2>{__*X>X@%>},{_X\/\-X+}%{F}%~}:F~]_&$}

Anche usando lo stesso metodo, con alcune modifiche. Volevo provare CJam per il confronto, ma sfortunatamente sono molto peggio in CJam di quanto non lo sia in Pyth / Python, quindi probabilmente c'è molto margine di miglioramento.

Quanto sopra è un blocco (sostanzialmente la versione di funzioni senza nome di CJam) che accetta un int e restituisce un elenco. Puoi provarlo in questo modo ( provalo online ):

{{:X_,2>{__*X>X@%>},{_X\/\-X+}%{F}%~}:F~]_&$}:G; 60 Gp

Non sono un esperto di Python, ma c'è un motivo per cui ti serve set()lì? Non puoi semplicemente restituire l'elenco ordinato?
Alex A.

@Alex set()rimuove i duplicati :)
Sp3000,

Oh ok. Neat. Bel lavoro!
Alex A.

Puoi forse fare [n]+sum(...,[])come sum(...,[n])?
xnor

@xnor Ah sì, posso. Non ho mai usato altro che []come base per le liste di riepilogo, quindi mi sono completamente dimenticato!
Sp3000,

6

Java, 148 146 104 byte

Versione golfizzata:

import java.util.*;Set s=new TreeSet();void f(int n){s.add(n);for(int a=1;++a*a<n;)if(n%a<1)f(n+a-n/a);}

Versione lunga:

import java.util.*;
Set s = new TreeSet();
void f(int n) {
    s.add(n);
    for (int a = 1; ++a*a < n;)
        if (n%a < 1)
            f(n + a - n/a);
}

Quindi sto facendo il mio debutto su PPCG con questo programma, che utilizza un TreeSet(che ordina automaticamente i numeri, per fortuna) e una ricorsione simile al programma di Geobits, ma in un modo diverso, controllando i multipli di n e poi usandoli nel prossima funzione. Direi che questo è un punteggio abbastanza giusto per un primo timer (specialmente con Java, che non sembra essere il linguaggio più ideale per questo tipo di cose, e l'aiuto di Geobits).


Benvenuti in PPCG! Puoi salvare un paio passando a*balla nriga 9.
Geobits

Grazie per l'accoglienza e il suggerimento! Sì, ci vorrà un po 'di tempo per individuare queste piccole cose. Ogni byte conta! Grazie ancora!
TNT,

Puoi anche salvarne altri due inserendoli c=n+a-ball'interno add(). In alternativa, potresti liberarti del ctutto e utilizzarlo n+a-bin entrambi i posti per gli stessi due byte.
Geobits,

A proposito, non credo di doverne usare adddue volte. Aspetta un momento ...
TNT,

Ma il secondo ciclo non è necessario nel complesso. Se hai un ache sai che divide in nmodo pulito, allora non dovresti trovare un loop per trovarlo b, è solo n/a. A quel punto inizia ad avvicinarsi sempre di più al mio;)
Geobits il

4

Java, 157 121

Ecco una funzione ricorsiva che ottiene i discendenti di ciascun discendente di n. Restituisce a TreeSet, che è ordinato per impostazione predefinita.

import java.util.*;Set t(int n){Set o=new TreeSet();for(int i=1;++i*i<n;)o.addAll(n%i<1?t(n+i-n/i):o);o.add(n);return o;}

Con alcune interruzioni di riga:

import java.util.*;
Set t(int n){
    Set o=new TreeSet();
    for(int i=1;++i*i<n;)
        o.addAll(n%i<1?t(n+i-n/i):o);
    o.add(n);
    return o;
}

2

Ottava, 107 96

function r=d(n)r=[n];a=find(!mod(n,2:sqrt(n-1)))+1;for(m=(a+n-n./a))r=unique([d(m) r]);end;end

Pretty-print:

function r=d(n)
  r=[n];                          # include N in our list
  a=find(!mod(n,2:sqrt(n-1)))+1;  # gets a list of factors of a, up to (not including) sqrt(N)
  for(m=(a+n-n./a))               # each element of m is a twist
    r=unique([d(m) r]);           # recurse, sort, and find unique values
  end;
end

1
Comprendo che Octave può terminare i blocchi con solo endanziché endfore endfunction. Ciò ti farebbe risparmiare 11 byte.
Alex A.

Ehi, hai ragione! Non come ho imparato la lingua e non ho mai capito che si potesse fare. Perché sei il primo a segnalarlo dopo aver fatto più golf con esso?
dcsohl,

Lo sapevo solo perché di recente l'ho cercato dopo averlo visto nel golf di qualcun altro su un'altra domanda. Non ho mai usato Octave e sono anni che uso Matlab. La mia ipotesi è che non ci siano così tanti utenti di Octave attivi su PPCG, ma potrei sbagliarmi.
Alex A.

Bene, grazie per averlo sottolineato.
dcsohl,

Piacere mio, felice di poterti aiutare. Bella soluzione.
Alex A.

1

Haskell, 102 100 byte

import Data.List
d[]=[]
d(h:t)=h:d(t++[a*b-b+a|b<-[2..h],a<-[2..b],a*b==h])
p n=sort$nub$take n$d[n]

Utilizzo: p 16quali output[7,10,16]

La funzione dcalcola ricorsivamente tutti i discendenti, ma non verifica la presenza di duplicati, quindi molti appaiono più di una volta, ad esempio d [4]restituisce un elenco infinito di 4s. Le funzioni pprendono i primi nelementi da questo elenco, rimuovono i duplicati e ordinano l'elenco. Ecco.


1

CJam - 36

ri_a\{_{:N,2>{NNImd!\I-z*-}fI}%|}*$p

Provalo online

Oppure, metodo diverso:

ri_a\{_{_,2f#_2$4*f-&:mq:if-~}%|}*$p

Li ho scritti quasi 2 giorni fa, mi sono bloccato a 36 anni, sono rimasto frustrato e sono andato a dormire senza postare.

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.