Iterated Divisor Twist


13

Definicje

Pozwolić mi nbyć dodatnimi liczbami całkowitymi. Mówimy, że mjest skręt dzielnik od njeśli istnieje liczby całkowite 1 < a ≤ btakie, że n = a*bi m = (a - 1)*(b + 1) + 1. Jeśli mmoże być uzyskane z nstosując zero lub więcej skrętów dzielnik do niej, a następnie mjest potomkiem z n. Zauważ, że każda liczba jest własnym potomkiem.

Rozważmy na przykład n = 16. Możemy wybrać a = 2i b = 8, ponieważ 2*8 = 16. Następnie

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

co pokazuje, że 10jest to skręt dzielnika 16. Za pomocą a = 2i b = 5widzimy, że 7jest to zwrot dzielnika 10. Zatem 7jest potomkiem 16.

Zadanie

Biorąc pod uwagę dodatnią liczbę całkowitą n, oblicz potomków nwymienionych w kolejności rosnącej, bez duplikatów.

Zasady

Nie wolno używać wbudowanych operacji obliczających dzielniki liczby.

Akceptowane są zarówno pełne programy, jak i funkcje, a zwracanie typu danych kolekcji (jak pewnego rodzaju zestawu) jest dozwolone, o ile jest ono posortowane i wolne od duplikatów. Wygrywa najniższa liczba bajtów, a standardowe luki są niedozwolone.

Przypadki testowe

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, jeśli pozwalasz na łańcuch 0 zwrotów dzielnika, to dlaczego nie każda liczba jest potomkiem jakiejkolwiek innej liczby?
rorlork

3
@rcrmn Dla mnie łańcuch zerowych operacji oznacza operację tożsamości. Tak więc zezwolenie na skręcenie dzielnika zerowego oznacza tylko, że każda liczba jest potomkiem samego siebie.
Zgarb

@Zgarb dobrze, więc definicja powinna zostać zmieniona, aby wyrazić, że jeśli nie, o ile mogę stwierdzić, każda liczba jest uważana za potomek każdej innej liczby. Nie wiem, dlaczego potrzebowała refleksji. Czy chciałbyś wyjaśnić?
rorlork

@rcrmn Zmieniłem nieznacznie sformułowanie, czy jest teraz jaśniejsze?
Zgarb

@Zgarb przepraszam, ale nie, to nie jest operacja, definiujesz związek między liczbami. Jeśli zdefiniujesz relację <dla liczb naturalnych, za każdy n otrzymasz każdą liczbę mniejszą od niej, ale nie samą. Myślę, że to powinno być coś podobnego. W ten sposób myślę, że tylko 4 byłoby własnym potomkiem (choć nie jestem tego pewien).
rorlork

Odpowiedzi:


9

Python 2, 109 98 85 82 bajtów

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])))

Ponieważ (a-1)*(b+1)+1 == a*b-(b-a)i b >= apotomkowie są zawsze mniejsi lub równi oryginalnej liczbie. Możemy więc zacząć od początkowej liczby i generować ściśle mniejszych potomków, dopóki ich nie pozostanie.

Warunek (n<x*x)>n%xsprawdza dwie rzeczy w jednym - to n<x*xi n%x == 0.

(Dzięki @xnor za zdjęcie 3 bajtów ze skrzynki podstawowej)

Pyth, 32 bajty

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

Bezpośrednie tłumaczenie powyższego, z wyjątkiem faktu, że Pyth wydaje się dusić podczas próby sumowania ( s) na pustej liście.

Definiuje funkcję, yktórą można wywołać dodając y<number>na końcu, tak jak to ( spróbuj online ):

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

CJam, 47 45 bajtów

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

Również przy użyciu tej samej metody, z kilkoma modyfikacjami. Chciałem wypróbować CJam do porównania, ale niestety jestem znacznie gorszy w CJam niż w Pyth / Python, więc prawdopodobnie jest dużo miejsca na ulepszenia.

Powyżej jest blok (w zasadzie wersja nienazwanych funkcji CJam), który przyjmuje int i zwraca listę. Możesz to przetestować w ten sposób ( wypróbuj online ):

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

Nie jestem ekspertem od Pythona, ale czy istnieje powód, dla którego potrzebujesz set()? Nie możesz po prostu zwrócić posortowanej listy?
Alex A.

@Alex set()ma usunąć duplikaty :)
Sp3000,

W porządku Schludny. Dobra robota!
Alex A.

Można chyba zrobić [n]+sum(...,[])tak sum(...,[n])?
xnor

@ xnor Ah tak, mogę. Nigdy nie używałem niczego innego []niż podstawowego przypadku do sumowania list, więc zupełnie zapomniałem!
Sp3000,

6

Java, 148 146 104 bajtów

Wersja golfowa:

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

Długa wersja:

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

Debiutuję więc na PPCG za pomocą tego programu, który wykorzystuje TreeSet(na szczęście automatycznie sortuje liczby) i rekurencję podobną do programu Geobitów, ale w inny sposób, sprawdzając wielokrotności n, a następnie używając ich w następna funkcja. Powiedziałbym, że jest to całkiem niezły wynik jak na pierwszy raz (szczególnie w Javie, która nie wydaje się być najlepszym językiem dla tego rodzaju rzeczy i pomocy Geobitów).


Witamy w PPCG! Można zaoszczędzić parę zmieniając a*bsię nna linii 9.
Geobits

Dzięki za powitanie i sugestię! Tak, zajmie mi trochę czasu, aby zauważyć te małe rzeczy. Liczy się każdy bajt! Dzięki jeszcze raz!
TNT

Możesz także zaoszczędzić jeszcze dwa, wkładając do c=n+a-bśrodka add(). Alternatywnie, możesz ccałkowicie się pozbyć i po prostu użyć n+a-bw obu miejscach dla tych samych dwóch bajtów.
Geobity

Mówiąc o tym, nie sądzę, że muszę używać adddwa razy. Poczekaj chwilę ...
TNT

Ale druga pętla nie jest potrzebna w całości. Jeśli masz coś a, co dobrze dzieli n, to nie powinieneś zapętlać, aby znaleźć b, to po prostu n/a. W tym momencie zaczyna się coraz bardziej zbliżać do mojego;)
Geobits

4

Java, 157 121

Oto funkcja rekurencyjna, która pobiera potomków każdego potomka n. Zwraca a TreeSet, który jest domyślnie sortowany.

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

Z pewnymi podziałami linii:

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

Oktawa, 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

Ładny druk:

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
Rozumiem, że Octave może kończyć bloki tylko endzamiast endfori endfunction. To zaoszczędzi Ci 11 bajtów.
Alex A.

Hej, masz rację! Nie tak nauczyłem się języka i nigdy nie zdawałem sobie sprawy, że da się to zrobić. Dlaczego jako pierwszy zwróciłeś na to uwagę po tym, jak grałem z nim w golfa?
dcsohl,

Wiedziałem to tylko dlatego, że ostatnio to sprawdziłem po tym, jak zobaczyłem to w czyimś golfie na inne pytanie. Nigdy nie korzystałem z Octave i minęły lata, odkąd korzystałem z Matlaba. Domyślam się, że na PPCG nie ma tylu aktywnych użytkowników Octave, ale mogę się mylić.
Alex A.

Dziękuję za zwrócenie na to uwagi.
dcsohl,

Cała przyjemność po mojej stronie, cieszę się, że mogłem pomóc. Niezłe rozwiązanie.
Alex A.

1

Haskell, 102 100 bajtów

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]

Zastosowanie: p 16które wyjścia[7,10,16]

Funkcja drekurencyjnie oblicza wszystkich potomków, ale nie sprawdza duplikatów, więc wielu pojawia się więcej niż jeden raz, np. d [4]Zwraca nieskończoną listę 4s. Funkcje ppobierają pierwsze nelementy z tej listy, usuwają duplikaty i sortują listę. Voilà.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.