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.