Ви ще загубили?


31

Ваше завдання полягає в реалізації цілочисельної послідовності A130826 :

п є найменше натуральне число таке , що п - п є цілою кратною 3 , і в два рази більше дільників п - п) / 3 дає п - й член в перших різниць послідовності вироблених Флавіуса Йосифове сито.

Втратили ще? Ну, насправді це досить просто.

Йосип Флавій сито визначає ціле послідовності наступним чином .

  1. Почніть з послідовності натуральних чисел і встановіть k = 2 .

  2. Видаліть кожне k -те ціле число послідовності, починаючи з k- го .

  3. Збільшення k і повернутися до кроку 2.

f n - n- е ціле число (1-індексоване), яке ніколи не видаляється.

Якщо - як завжди - σ 0 (к) позначає число позитивних дільників цілого числа до , ми можемо визначити в п як найменше натуральне число таке , що 0 ((а п - п) / 3) = F N + 1 - f n .

Виклик

Написати програму або функцію , яка приймає ціле позитивне число п в якості вхідних даних і виводить або повертає в п .

Діють стандартні правила . Нехай найкоротший код виграє!

Працювали приклади

Якщо ми видалимо кожен другий елемент натуральних чисел, ми залишимося

 1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 ...

Вилучивши кожен третій елемент залишку, отримуємо

 1  3  7  9 13 15 19 21 25 27 31 33 37 39 ...

Тепер, видаляючи нас кожен четвертий, потім п’ятий, потім шостий елемент

 1  3  7 13 15 19 25 27 31 37 39 ...
 1  3  7 13 19 25 27 31 39 ...
 1  3  7 13 19 27 31 39 ...
 1  3  7 13 19 27 39 ...

В останньому рядку показані терміни f 1 до f 7 .

Відмінності послідовних елементів цих термінів є

 2  4  6  6  8 12

Поділивши ці передні різниці на 2 , отримаємо

 1  2  3  3  4  6 

Це підрахунки цільового дільника.

  • 4 - перше ціле число k таке, що σ 0 ((k - 1) / 3) = 1 . Насправді σ 0 (1) = 1 .
  • 8 - це перше ціле число k таке, що σ 0 ((k - 2) / 3) = 2 . Насправді σ 0 (2) = 2 .
  • 15 - це перше ціле число k таке, що σ 0 ((k - 3) / 3) = 3 . Насправді σ 0 (4) = 3 .
  • 16 - це перше ціле число k таке, що σ 0 ((k - 4) / 3) = 3 . Насправді σ 0 (4) = 3 .
  • 23 - це перше ціле число k таке, що σ 0 ((k - 5) / 3) = 4 . Насправді σ 0 (6) = 4 .
  • 42 - це перше ціле число k таке, що σ 0 ((k - 6) / 3) = 6 . Насправді σ 0 (12) = 6 .

Тестові справи

   n     a(n)

   1        4
   2        8
   3       15
   4       16
   5       23
   6       42
   7       55
   8      200
   9       81
  10       46
  11      119
  12      192
  13      205
  14   196622
  15    12303
  16       88
  17      449
  18      558
  19      127
  20     1748
  21   786453
  22       58
  23     2183
  24     3096
  25     1105
  26   786458
  27 12582939
  28      568
  29     2189
  30     2730

14
Ключове слово на OEIS: німий ("неважлива послідовність").
orlp

15
Тупий? Це могло б врятувати світ!
Денніс

3
Цей каламбур, хоча ...
Mego

Відповіді:


7

Желе, 30 29 27 25 байт

Збережено 2 байти завдяки тому, що @Dennis повідомив про мене Æd, та ще 2 байти для поєднання двох ланцюгів.

RUð÷‘Ċ×µ/
‘Ç_ÇH0Æd=¥1#×3+

Спробуйте в Інтернеті!

Це було, мабуть, найвеселіше, що я коли-небудь мав з Джеллі. Я почав з другого рядка, який обчислює f n від n, використовуючи формулу на OEIS, і є досить красивим.

Пояснення

RUð ÷ 'Ċ × µ / Помічник для обчислення F n . Аргумент: n
R Отримати числа [1..n]
 U Зворотний
        / Зменшити на "округлення до наступних 2 кратних":
   ÷ Розділіть на наступне число
    'Приріст пропустити кратне
     Ċ Стеля (заокруглення)
      × Помножте на наступне число

'Ç_ÇH0Æd = ¥ 1 # × 3 + Основне посилання. Аргумент: n
'Приріст n
 Ç Обчислити F n + 1 
   Ç Обчислити F n
  _ Віднімання
    H Ділимо на 2
     0 1 # Починаючи з 0, знайдіть першого кандидата для (a n -n) / 3
                   що задовольняє ...
      Æd σ 0 ((a n -n) / 3)
        = = (F n + 1 -F n ) / 2
            × 3 Помножте на 3, щоб перетворити (a n -n) / 3 на n -n
              + Додати n, щоб перетворити n -n на n

3

Python 2 , 121 119 118 байт

n=input();r=range(1,4**n);d=s,=r*1,
for k in r:del s[k::k+1];d+=sum(k%j<1for j in r)*2,
print d.index(s[n]-s[n-1])*3+n

Час роботи повинен бути приблизно O (16 n ) з використанням O (4 n ) пам'яті. Заміна 4**nна 5<<n- що, на мою думку, є достатнім - це суттєво поліпшило б, але я не переконаний, що він працює для довільно великих значень n .

Спробуйте в Інтернеті!

Асимптотична поведінка та верхні межі n

Визначте b n як (a n - n) / 3 , тобто найменше додатне ціле число k таке, що σ 0 (k) = ½ (f n + 1 - f n ) .

Як зазначається на сторінці OEIS, f n ~ ¼πn 2 , тому f n + 1 - f n ~ ¼π (n + 1) 2 - ¼πn 2 = ¼π (2n + 1) ~ ½πn .

Таким чином, ½ (f n + 1 - f n ) ~ ¼πn . Якщо дійсне число є простим p , найменше додатне ціле число з дільниками p дорівнює 2 p-1 , тому b n можна наблизити до 2 c n , де c n ~ ¼πn .

Тому b n <4 n буде достатньо великим n , та враховуючи, що 2 ¼πn <2 n << (2 n ) 2 = 4 n , я впевнений, що немає протилежних прикладів .

Як це працює

n=input();r=range(1,4**n);d=s,=r*1,

Це створює кілька посилань на наш ітераційний процес.

  • n - введення користувача: додатне ціле число.

  • r - список [1, ..., 4 n - 1] .

  • s - копія r .

    Повторення списку один раз із r*1створює дрібну копію, тому зміна s не змінить r .

  • d ініціалізується як кортеж (и) .

    Це перше значення не важливо. Усі інші матимуть число дільників додатних цілих чисел.

for k in r:del s[k::k+1];d+=sum(k%j<1for j in r)*2,

Для кожного цілого k від 1 до 4 n - 1 робимо наступне.

  • del s[k::k+1]вживає всіх (до + 1) е цілому числу в сек - починаючи з (до + 1) й - і видаляє цей шар від ї .

    Це прямий спосіб зберігання початкового інтервалу сита Флавія Йосифа в с . Він обчислить набагато більше необхідних n + 1 початкових термінів, але використовуючи єдиний forцикл для оновлення і s, і d зберігає деякі байти.

  • d+=sum(k%j<1for j in r)*2,підраховує, скільки елементів r поділяє k рівномірно і додає 0 (k) до d .

    Оскільки d було ініціалізовано як однотонний кортеж, 0 (k) зберігається в індексі k .

print d.index(s[n]-s[n-1])*3+n

Це знаходить перший показник f n + 1 - f n в d , який є найменшим k таким, що 0 (k) = f n + 1 - f n , потім обчислює a n як 3k + 1 і друкує результат.


2

Java 8, 336 , 305 , 303 , 287 , 283 279 байт

Вилучено 57 байт завдяки Kritixi Lithos

Гольф

class f{static int g(int s,int N){return s<1?N+1:g(s-1,N+N/s);}static int h(int k){int u=0,t=1,i;for(;u!=(g(k,k)-g(k,k-1))/2;t++)for(i=1,u=0;i<=t;)if(t%i++<1)u++;return 3*t-3+k;}public static void main(String[]a){System.out.print(h(new java.util.Scanner(System.in).nextInt()));}}

Безумовно

class f {
    static int g(int s,int N){return s < 1 ? N + 1 : g(s - 1, N + N / s);}

    static int h(int k) {
        int u = 0, t = 1, i;
        // get the first number with v divisors
        while(u != (g(k, k) - g(k, k - 1))/2){
            u = 0;
            for (i = 1; i <= t; i++)
                if (t % i < 1) u++;
            t++;
        }
        // 3*(t-1)+k = 3*t+k-3
        return 3 * t + k - 3;
    }

    public static void main(String[] a) {
        System.out.print(h(new java.util.Scanner(System.in).nextInt()));
    }
}

Я думаю, що аналіз аргументів командного рядка як an intє коротшим, ніж використання java.util.Scanner. Але навіть якщо ви використовуєте Scanner, ви можете зробити System.out.print(h(new java.util.Scanner().nextInt()))та видалити попередній рядок
Kritixi Lithos

@KritixiLithos thx, виправляємо зараз ...
Bobas_Pett

Всередині int h()його можна змінити int v = (g(k,k)-g(k,k-1))/2,u = 0,t = 1;. Ви можете змінити свій if-заяву (що знаходиться всередині вашого for-loop) з if(t%i==0)наif(t%i<1)
Kritixi Lithos

Крім того, ви можете змінити свою функцію, gщоб повернутися за допомогою потрійних операторів на кшталт return s==0?N+1:g(s-1,N+N/2)-ish
Kritixi Lithos

2
@KritixiLithos lol у цьому пункті ви повинні просто опублікувати це як ур власне окреме рішення
Bobas_Pett

1

Математика, 130 116 106 103 байт

3Catch@Do[f=#2⌈#/#2+1⌉&~Fold~Reverse@Range@#&;If[Tr[2+0Divisors@k]==f[#+1]-f@#,Throw@k],{k,∞}]+#&

або

3Catch@Do[f=#2⌈#/#2+1⌉&~Fold~Reverse@Range@#&;If[2DivisorSum[k,1&]==f[#+1]-f@#,Throw@k],{k,∞}]+#&

Закінчився майже ідентичним коду Jelly @ Pietu1998 ...

Пояснення

Catch@

Catchвсе, що є, Throw-ed (кинутий).

Do[ ... ,{k,∞}]

Нескінченна петля; kпочинається з 1кожної ітерації і збільшується з кроком.

f= ...

Призначити f:

Reverse@Range@#

Знайдіть {1, 2, ... , n}. Зворотний.

#2⌈#/#2+1⌉&

Функція, яка виводить ceil (n1 / n2 + 1) * n2

f= ... ~Fold~ ... &

Призначте fфункцію, яка рекурсивно застосовує вищевказану функцію до списку з двох етапів вище, використовуючи кожен вихід як перший вхід, а кожен елемент списку як другий вхід. Початковий "вихід" (перший вхід) - перший елемент списку.

Tr[2+0Divisors@k]==f[#+1]-f@#

Перевірте, чи вдвічі число дільників kдорівнює f (n + 1) - f (n).

If[ ... ,Throw@k]

Якщо умова є True, Throwзначення k. Якщо ні, продовжуйте циклічно.

3 ... +#&

Помножте вихід на 3 і додайте n.

130-байтна версія

Catch@Do[s=#+1;a=k-#;If[3∣a&&2DivisorSigma[0,a/3]==Differences[Nest[i=1;Drop[#,++i;;;;i]&,Range[s^2],s]][[#]],Throw@k],{k,∞}]&

1

Perl 6 , 154 149 136 107 байт

->\n{n+3*first ->\o{([-] ->\m{m??&?BLOCK(m-1).rotor(m+0=>1).flat!!1..*}(n)[n,n-1])/2==grep o%%*,1..o},^Inf}

Безголовки:

-> \n {                    # Anonymous sub taking argument n
  n + 3 * first -> \o {    # n plus thrice the first integer satisfying:
    (                      #
      [-]                  #
      -> \m {              # Compute nth sieve iteration:
        m                  # If m is nonzero,
          ?? &?BLOCK(m-1).rotor(m+0=>1).flat # then recurse and remove every (m+1)-th element;
          !! 1..*          # the base case is all of the positive integers
      }                    #
      (n)                  # Get the nth sieve
      [n,n-1]              # Get the difference between the nth and (n-1)th elements (via the [-] reduction operator above)
    ) / 2                  # and divide by 2;
    ==                     # We want the number that equals
    grep o %% *, 1..o      # the number of divisors of o.
  }
  ,^Inf
}

1

05AB1E ,35 34 39 байт

1Qi4ë[N3*¹+NÑg·¹D>‚vyy<LRvy/>îy*}}‚Æ(Q#

Це виглядає жахливо, так це і виконання. На введення знадобиться кілька секунд, які дають невеликі значення. Не намагайтеся цифри, як 14; вона врешті-решт знайде результат, але це займе віки.

Пояснення

Він працює як 2 послідовно названі програми. Перший обчислює F п + 1 - Р п , а другий визначає , а п , заснований на визначенні його, використовуючи BruteForce підхід.

F n + 1 - F n оцінюється для кожної ітерації, хоча вона є інваріантною петлею. Це робить час коду неефективним, але робить код коротшим.

Спробуйте в Інтернеті!


Я не впевнений, що розумію. Чому він не може обчислити сито вище 65 536?
Денніс

Це випливає з того, що він генерує всі цілі числа від 0 до 65536 ( žHL), а потім фільтрує значення, які не відповідають обмеженням сита. Я думаю, що першу частину цієї програми слід повністю переписати із зовсім іншим підходом, щоб зробити її пограбуючою.
Доступний

Якщо немає обмежень (наприклад, цілих чисел із фіксованою шириною), які не дозволяють вам це робити, очікується, що відповіді працюватимуть на будь-які дані, якщо буде достатньо часу та пам'яті.
Денніс

Тому я придумав ще один алгоритм сита. Це може бути збитково, але я не знайшов кращого в 05AB1E. Однак є контрприклад given enough time and memory, оскільки я вже бачив декілька відповідей на інші запитання, які проходили так повільно, що майже неможливо було сказати, чи дали вони правильний результат чи ні. З цієї причини я відклав обчислення сита в сторону від циклу, і це коштувало мені 2 байти.
Доступний

Не потрібно робити свій код ефективним. Ви можете зробити заявку на гольф / повільну реалізацію і включити більш швидкий / довший в якості бічної записки. Боюся, що мені доведеться наполягати на динамічній межі, навіть якщо це коштує в байті.
Денніс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.