Неприкасаемые


9

Неприкасаемые числа α

Неприкасаемое число - это положительное целое число, которое не может быть выражено как сумма всех собственных делителей любого натурального числа (включая само неприкасаемое число).

Например, число 4 не является неприкосновенным, поскольку оно равно сумме правильных делителей 9: 1 + 3 = 4. Число 5 неприкосновенно, поскольку оно не является суммой правильных делителей любого натурального числа. 5 = 1 + 4 - единственный способ записать 5 в виде суммы различных положительных целых чисел, включая 1, но если 4 делит число, 2 также делает, поэтому 1 + 4 не может быть суммой всех собственных делителей любого числа (так как список факторов должен содержать как 4, так и 2).

Число 5, как полагают, является единственным нечетным неприкасаемым числом, но это не было доказано: оно будет следовать из немного более сильной версии гипотезы Гольдбаха. β

Есть бесконечно много неприкасаемых чисел, факт, который доказал Пол Эрдос.

Несколько свойств неприкасаемых:

  • Нет неприкасаемых 1 больше простого
  • Нет неприкасаемых 3 больше простого, кроме 5
  • Нет неприкасаемый это идеальный номер
  • До сих пор все неприкасаемые, кроме 2 и 5, составные.

Задача

Создайте программу или функцию, которая принимает натуральное число nчерез стандартные входные или функциональные параметры и печатает первые nнеприкасаемые числа.

Вывод должен иметь разделение между числами, но это может быть что угодно (например, переводы строк, запятые, пробелы и т. Д.).

Это должно быть в состоянии работать по крайней мере 1 <= n <= 8153. Это основано на том факте, что b-файл, предоставленный для записи OEIS γ, увеличивается до n = 8153.

Стандартные лазейки запрещены, как обычно.

Пример ввода / вывода

1    -> 2
2    -> 2, 5
4    -> 2, 5, 52, 88
10   -> 2, 5, 52, 88, 96, 120, 124, 146, 162, 188
8153 -> 2, 5, 52, 88, 96, 120, ..., ..., ..., 59996

Это , поэтому наименьшее количество байтов выигрывает.


α - Википедия , β - MathWorld , γ - OEIS


По какой-то причине это было помечено как дубликат вопроса «поиск полусовершенных чисел», однако задачи совершенно другие. В этом случае вы должны убедиться, что никакая сумма совершенных делителей любого натурального числа не может равняться определенному числу.


Это чисто умозрительно, так как я пока не задумывался над тем, как бы решить эту проблему: было бы обманом, если бы я принял верхний предел для полученных чисел? Скажите, если бы я написал код, который находит неприкасаемые числа до 60 000? Этого будет достаточно, чтобы покрыть входной диапазон. Но, конечно, я знаю это только на основании частичных результатов, которые вы предоставили.
Рето Коради,

Я думаю, это было бы хорошо. Технически это не жестко запрограммировано, не нарушает стандартные лазейки, насколько я знаю. Пока это соответствует остальной части спецификации, это будет хорошо.
Каде

@vihan Определенно нет.
Каде

Ответы:


6

Pyth, 21 байт

.f!fqZsf!%TYStTSh^Z2Q

Предупреждение: невероятно медленный Тестовый прогон и сроки ниже.

$ time pyth -c '.f!fqZsf!%TYStTSh^Z2Q' <<< 3
[2, 5, 52]

real    2m46.463s
user    2m46.579s
sys 0m0.004s

Это в основном грубая сила, насколько это возможно, тестирует факторизации вплоть до потенциального числа одиночного квадрата плюс один.


4

C 104 байта

j,i,z,w;u(y){for(z=2;y;z++)for(w=0;(++w<z*z||0&printf("%i ",z)+y--)&&j^z;)for(i=j=0;++i<w;j+=i*!(w%i));}

Это займет несколько минут для y > 20, но что угодно.


2

Java, 310 байт

class U{int[] p;U(int e){p=new int[(int)4e9];for(int i=1,c=0;c<e;i++)if(u(i)>0){System.out.println(i);c++;}}int p(int n){if(p[n]!=0)return p[n];int i,s=1;for(i=2;i<=n-1;i++)s+=n%i==0?i+(n/i!=i?n/i:0):0;return(p[n]=s);}int u(int n){if(n==1)return 0;for(int i=2;i<=(n-1)*(n-1);i++)if(p(i)==n)return 0;return 1;}}

Гольф, как мог, но я был более заинтересован в том, чтобы убедиться, что он работает в разумные сроки. Безглазная версия, вероятно, более интересна

public class Untouchable {
    int[] properDivisorSumMap;


    public Untouchable(int estimatedMaxium){
        properDivisorSumMap = new int[(estimatedMaxium-1)*(estimatedMaxium-1)];
    }


    public int properDivisorSum(int n){
        if(properDivisorSumMap[n] != 0){
            return properDivisorSumMap[n];
        }

        int sum = 1;
        for(int i=2;i<=(int)Math.sqrt(n);i++){
            if(n%i==0){
                sum+=i;
                if(n/i != i){
                    sum+=n/i;
                }
            }
        }
        properDivisorSumMap[n] = sum;
        return sum;
    }


    public boolean untouchable(int n){
        if(n==1){
            return false;
        }
        for(int i=2;i<=(n-1)*(n-1);i++){
            if(properDivisorSum(i) == n){
                return false;
            }
        } 
        return true;
    }


    public static void main(String[] args){
        Untouchable test = new Untouchable(8480);

        int elements = Integer.parseInt(args[0]);

        for(int i=1,count=0;count < elements;i++){
            if(test.untouchable(i)){
                System.out.printf("%4d: %4d%n",count,i);
                count++;
            }
        }
    }
}

1

Go, 396 байт

На самом деле не игра в гольф, но она может выполнить весь необходимый диапазон. Работает около ~ 20 минут и требует ~ 7 ГБ (независимо от n). Создает гигантский массив для вычисления суммы делителей для всех чисел до 59997 в квадрате.

func untouchable(n int) {
    const C = 59997
    const N = C * C
    s := make([]uint16, N)
    for d := 1; d < N; d++ {
        for i := 2 * d; i < N; i += d {
            v := int(s[i]) + d
            if v > C {
                v = C + 1 // saturate at C+1
            }
            s[i] = uint16(v)
        }
    }
    var m [C]bool
    for i := 2; i < N; i++ {
        if s[i] < C {
            m[s[i]] = true
        }
    }
    for i := 2; n > 0; i++ {
        if !m[i] {
            println(i)
            n--
        }
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.