Скільки у мене розділів?


16

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

[[1, 1, 1, 1], [1, 1, 2], [1, 3], [2, 2], [4]]

Отже, у нього є 5перегородки. Це OEIS A000041 .


Завдання

По даному натуральному числу N визначте його номер розділу.

  • Діють усі стандартні правила.

  • Введення та вихід можуть оброблятися за допомогою будь-якого розумного значення.

  • Це , тому виграє найкоротший код у байтах.


Випробування

Введення | Вихідні дані

1 | 1
2 | 2
3 | 3
4 | 5
5 | 7
6 | 11
7 | 15
8 | 22
9 | 30
10 | 42

1
Я майже впевнений, що це дублікат ...
DJMcMayhem

@DJMcMayhem Umm, добре. Повідомте мене, якщо ви знайдете дублікат. Вибачте, я новачок у всьому цьому!

1
@DJMcMayhem, можливо, це питання, яке ви задали, оскільки це короткий крок від "генерації" до "підрахунку", але вам не обов'язково генерувати всі розділи, щоб їх порахувати ...
Джузеппе

1
ця - дупа, ВСЕ, що є попконом (?) і закрита як занадто широка. ІМХО, це ШЛОШЕ пишуть і його слід тримати відкритим, тоді як старий повинен бути (повторно відкритий і) закритий як дуп
стрижень

2
@Rod, це поганий поп-кон, але переключення близької причини на дурня не було б покращенням. Вимога щодо продуктивності може бути перешкодою для перенесення деяких відповідей (ніхто не збирається генерувати 24061467864032622473692149727991 розділи 1000 за пару хвилин); і реалізація Харді-Рамануджана-Радемачера не зовсім гольф ... Однак, можливо, варто відкрити дискусію в мета про те, що робити з цим питанням.
Пітер Тейлор

Відповіді:


13

Pyth , 3 байти

l./

Спробуйте тут! або Спробуйте тестовий набір.

Форматування відповіді зайняло набагато більше часу, ніж написання самого коду: P.


Як?

Піт - це правильний інструмент для роботи.

л. / Повна програма з неявним введенням.

 ./ Цілі розділи. Повернути всі відсортовані списки натуральних чисел, які додаються до вхідних даних.
l Довжина.
      Неналежне виведення результату.


8

Python 2 , 85 83 байт

-2 байти завдяки @notjagan

lambda n:n<1or sum(sum(i*((n-k)%i<1)for i in range(1,n+1))*p(k)for k in range(n))/n

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

Використовуючи рекурсивну формулу від OEIS A000041 .



84 байти . ==0еквівалентно <1в цьому випадку. EDIT: Використовуйте підхід
Notjagan

@ Mr.Xcoder Оригінальний код насправді мав <1замість ==0, але код TIO - ні.
notjagan


8

Emojicode 0,5, 204 201 байт

🐋🚂🍇🐖🅰️➡🚂🍇🍊⬅🐕1🍇🍎1🍉🍮s 0🔂k⏩0🐕🍇🍦t➖🐕k🍮r t🔂i⏩1 t🍇🍊😛🚮t i 0🍇🍮➕r i🍉🍉🍮➕s✖r🅰️k🍉🍎➗s🐕🍉🍉

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

-3 байти, використовуючи "менше або дорівнює 1" замість "менше 2", оскільки емодзі "менше, ніж" має досить довге кодування UTF-8. Також зробив tзаморожене, щоб замовкнути попередження, не впливаючи на кількість байтів.

Розширює клас 🚂 (ціле число) методом, який називається 🅰️. Ви можете написати просту програму, яка приймає число з введення, дзвонить 🅰️ на номер і друкує результат таким чином:

🏁🍇
 🍦str🔷🔡😯🔤Please enter a number🔤
 🍊🍦num🚂str 10🍇
  😀🔡🅰️num 10
 🍉🍓🍇
  😀🔤Learn what a number is, you moron!🔤
 🍉
🍉

Цю частину можна було б багато пограти, пропустивши повідомлення та обробляти помилки, але вона не включена в рахунок, тому я вважаю за краще показувати більше можливостей Emojicode, в той час як покращуючи читабельність по дорозі.

Безумовно

🐋🚂🍇
 🐖🅰️➡🚂🍇
  🍊◀️🐕2🍇
   🍎1
  🍉
  🍮sum 0
  🔂k⏩0🐕🍇
   🍦nmk➖🐕k
   🍮sig nmk
   🔂i⏩1 nmk🍇
    🍊😛🚮nmk i 0🍇
     🍮➕sig i
    🍉
   🍉
   🍮➕sum✖sig🅰️k
  🍉
  🍎➗sum🐕
 🍉
🍉

Пояснення

Зауважте: багато емоцій вибору не має великого сенсу в емоджикоде 0,5. Зрештою, це 0.x. 0,6 це виправить.

Emojicode - це об'єктно-орієнтована мова програмування, що містить дженерики, протоколи, необов’язкові та закриття, але ця програма не використовує закриття, і всі дженерики та протоколи можна вважати неявними, тоді як єдиний необов'язковий відображається в заглушці вводу / виводу.

Програма працює лише на декілька типів: 🚂 цілий тип, type тип рядка і ⏩ тип діапазону. З'являється також кілька булевих (appear), але вони використовуються лише в умовах. Булеви можуть приймати значення 👍 або 👎, що відповідають істинному та хибному відповідно.

Наразі в Emojicode немає операторів, тому додавання, порівняння та інші операції, які зазвичай є операторами, реалізуються як функції, ефективно змушуючи вирази використовувати позначення префікса . Операторів також планується в 0,6.

Розглянемо спочатку програму тестування.

🏁

Це блок 🏁, який можна порівняти з основним з інших мов.

🍇 ... 🍉

Виноград і кавуни оголошують кодові блоки в еможикоді.

🍦str🔷🔡😯🔤Please enter a number🔤

Це оголошує "заморожене" ім'я strта встановлює його для нової рядки, створеної за допомогою ініціалізатора (конструктора) 😯, який приймає підказку як рядок і потім вводить рядок від користувача. Навіщо використовувати заморожений замість змінної? Він не зміниться, тому змінна може надсилати попередження.

🍊🍦num🚂str 10

Давайте розбимо його. 🚂str 10викликає метод 🚂 на strзамороженому з аргументом 10. За умовою , методи, названі з іменем типу, перетворюють об'єкт у цей тип. 10 є базовою для цілочислового перетворення. Цей метод повертає необов'язковий, 🍬🚂. Необов’язкові можуть містити значення базового типу або небуття, ⚡. Якщо рядок не містить числа, ⚡ повертається. Щоб використовувати значення, слід розгортати необов'язковий за допомогою 🍺, що призводить до помилки виконання, якщо значення is. Тому корисною практикою перевірити наявність нічого, перш ніж розгортати необов’язковий. Насправді настільки поширене, що Емоджікод має для цього скорочення. Зазвичай, 🍊це "якщо".🍊🍦 variable expressionозначає: оцінити вираз. Якщо необов'язково містить нічого, умова оцінюється на 👎 (false). В іншому випадку заморожений ім'я variableстворюється з розпакованим значенням необов'язкового, і умова оцінюється на 👍, (вірно). Тому при звичайному використанні 🍇 ... 🍉вводиться блок, що відповідає умовному.

😀🔡🅰️num 10

🅰️ - метод, який основний код додає до 🚂, використовуючи 🐋, який обчислює кількість розділів. Це викликає 🅰️ на numзамороженому, який ми оголосили в умовному, і перетворює результат у рядок, використовуючи базу 10 методом 🔡. Потім 😀 друкує результат.

🍓🍇 ... 🍉

🍓 означає "else", тому цей блок вводиться, коли користувач неправильно ввів номер.

😀🔤Learn what a number is, you moron!🔤

Друкує рядковий літерал.

Тепер давайте розглянемо основну програму. Я поясню неперевершений варіант; у версії для гольфу просто було видалено пробіли, а змінні перейменовано на назви з однієї літери.

🐋🚂🍇 ... 🍉

Розширити клас 🚂. Це особливість, яка часто не зустрічається в мовах програмування. Замість створення нового класу з 🚂 як суперкласу, 🐋 змінює fies безпосередньо.

🐖🅰️➡🚂🍇 ... 🍉

Створює новий метод під назвою 🅰️, який повертає 🚂. Він повертає кількість розділів, обчислених за формулоюa(n) = (1/n) * Sum_{k=0..n-1} sigma(n-k)*a(k)

🍊⬅🐕1🍇
 🍎1
🍉

🐕 подібний thisабо selfз інших мов і відноситься до об'єкта, до якого був викликаний метод. Ця реалізація є рекурсивною, тому це умова завершення: якщо число, за яким було викликано метод, менше або дорівнює 1, поверніть 1.

🍮sum 0

Створіть нову змінну sumта встановіть її на 0. Неодмінно передбачається тип 🚂.

🔂k⏩0🐕

Повторює будь-що, що реалізує протокол,, тоді як ⏩ є літералом діапазону, який трапляється реалізувати Діапазон має початкове значення, стоп-значення та значення кроку, яке вважається рівним 1, якщо start < stopінше -1. Можна також вказати значення кроку, використовуючи ⏭ для створення літералу діапазону. Стартове значення включно, тоді як стоп-значення є виключним, тому це еквівалентно for k in range(n)або Sum_{k=0..n-1}формулою.

🍦nmk➖🐕k

Нам потрібно обчислити сигму (n - k) або суму дільників n - kіншими словами, і аргумент потрібен кілька разів, тому це зберігається n - kу змінній, nmkщоб зберегти деякі байти.

🍮sig nmk
🔂i⏩1 nmk

Це встановлює sigзмінну до аргументу сигми та ітералізує всі числа від 1 до nmk - 1. Я міг би ініціалізувати змінну до 0 і ітератувати більше 1..nmk, але робити це таким чином коротше.

🍊😛🚮nmk i 0

🚮 обчислює залишок, або модуль і 😛 перевіряє рівність, тож умовою буде 👍, якщо iце дільник nmk.

🍮➕sig i

Це призначення за викликом, подібне до += -= >>=сімейства операторів у деяких із нижчих мов, вільних від емодзі. Цей рядок можна також записати як 🍮 sig ➕ sig i. Тому після завершення внутрішнього циклу sigбуде міститися сума дільників n - k, абоsigma(n - k)

🍮➕sum✖sig🅰️k

Ще одне завдання за викликом, так що це додає sigma(n - k) * A(k)до загального, так само, як у формулі.

🍎➗sum🐕

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



3

Октава, 18 байт

partcnt(input(''))

Використовує вбудовану функцію partcnt.

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


3

Сітківка , 34 байти

.+
$*
+%1`\B
;$'¶$`,
,

%O`1+
@`.+

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

Пояснення

.+
$*

Перетворити вхід в одинаковий.

+%1`\B
;$'¶$`,

Тут обчислюються всі 2 n-1 розділи списку одинарних знаків. Ми робимо це шляхом повторного ( +) узгодження першої ( 1) межі слова ( \Bтобто позиції між двома 1) у кожному рядку ( %) і замінивши її на ;все, що є після нього ( $'), виведення рядка ( ), усе перед це ( $`) і ,. Приклад:

1;1,111

Стає

      vv
1;1,1;11
1;1,1,11
^^^^^

Де vвідмічає результат $'і ^відмічає результат $`. Це загальна ідіома, щоб отримати результат відразу двох різних замін (ми в основному вставляємо ;і ,заміну, і заміну, а також відсутні "половинки" рядка, щоб виконати дві повні заміни).

Ми будемо розглядатись ;як фактичні розділи і так ,само, як заповнювачі, які не дають змоги згодом їх \Bвідповідати. Тож далі ...

,

... ми видаляємо ці коми. Це дає нам усі розділи. Наприклад для введення 4ми отримуємо:

1;1;1;1
1;1;11
1;11;1
1;111
11;1;1
11;11
111;1
1111

Ми не дбаємо про замовлення:

%O`1+

Це сортує пробіли 1s у кожному рядку, щоб ми отримали не упорядковані розділи.

@`.+

Нарешті, ми підраховуємо унікальні ( @) збіги .+, тобто скільки отриманих нами ліній / розділів. Цю @опцію я додав ще віки тому, тоді повністю забув про неї і лише нещодавно її знову відкрив. У цьому випадку він економить байт на першому дедупликації рядків з D`.


3

Python 2 , 54 53 байти

f=lambda n,k=1:1+sum(f(n-j,j)for j in range(k,n/2+1))

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

Як це працює

Кожен розділ n може бути представлений у вигляді списку x = [x 1 , ⋯, x m ] таким, що x 1 + ⋯ + x m = n . Це подання стає унікальним, якщо нам потрібно, щоб x 1 ≤ ⋯ ≤ x m .

Визначимо допоміжну функцію f (n, k), яка рахує перегородки з нижньою межею k , тобто списки x такі, що x 1 + ⋯ + x m = n і k ≤ x 1 ≤ ⋯ ≤ x m . Для введення n виклик, таким чином, запитує вихід f (n, 1) .

Для позитивних цілих чисел n і k, таких, що k ≤ n , існує принаймні одна секція з нижньою границею k : список однорогів [n] . Якщо n = k (зокрема, якщо n = 1 ), це єдиний придатний розділ. З іншого боку, якщо k> n , рішень взагалі немає.

Якщо k <n , ми можемо рекурсивно підраховувати решту розділів, будуючи їх зліва направо, наступним чином. Для кожного j такого, що k ≤ j ≤ n / 2 , ми можемо побудувати перегородки [x 1 , ⋯, x m ] = [j, y 1 , ⋯, y m-1 ] . Маємо, що x 1 + ⋯ + x m = n тоді і тільки тоді, коли y 1 + ⋯ + y m-1 = n - j . Крім того, x 1 ≤ ⋯ ≤ x m тоді і тільки тоді, коли j ≤ y 1 ≤ ⋯ ≤ y m-1 .

Тому розділи x з n, які починаються з j, можна обчислити як f (n - j, j) , що рахує дійсні розділи y . Вимагаючи, що j ≤ n / 2 , ми запевняємо, що j ≤ n - j , тому існує принаймні одне y . Таким чином, ми можемо порахувати всі розділи з n шляхом підсумовування 1 (для [n] ) і f (n - j, j) для всіх дійсних значень j .

Код - це просто реалізація математичної функції f . Крім того, вона робить k за замовчуванням до 1 , тому f(n)обчислює значення f (n, 1) для введення n .


Ох вау, це неймовірно! Чи можете ви додати пояснення, як це працює?

Я відредагував свою відповідь. Якщо щось незрозуміле, будь ласка, повідомте мене про це.
Денніс

3

J , 37 35 байт

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:

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

Пояснення

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:  Input: n
                                 1:  Constant 1
  ]                                  Get n
   1&(                          )    Repeat n times on x = [1]
                          \            For each prefix
                         #               Length
                      q:@                Prime factors
                 /.~&                    Group equal factors
              #.~                        Compute p+p^2+...+p^k for each group
           >:@                           Increment
                    &.q:                 Product
                           %           Divide
                            #          Length
         ]                             Get x
          *                            Times
   1   #.                              Sum
                              ,        Joim
                               ]       Get x
                                       Set this as next value of x
0{                                   Select value at index 0

Я тупий і ошелешений, розум публікує пояснення?
коул

1
@cole Це ітеративний підхід, який починається з рішення для p (0) = 1, і будує наступне, використовуючи формулу p(n) = sum(sigma(n-k) * p(k) for k = 0 to n-1) / n. Пояснення коду я додам пізніше, коли вважаю, що його не можна суттєво скоротити.
миль

2

JavaScript, 125 121 байт

n=>(z=(a,b)=>[...Array(a)].map(b))(++n**n,(_,a)=>z[F=z(n,_=>a%(a/=n,n)|0).sort().join`+`]=b+=eval(F)==n-1&!z[F],b=0)|b||1

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

Попередження: складність часу та простору експоненціальна. Працює дуже повільно для великої кількості.


2

Python 2 , 89 байт

-9 байт Mr.Xcoder -1 байт notjagan

lambda n:len(p(n))
p=lambda n,I=1:{(n,)}|{y+(x,)for x in range(I,n/2+1)for y in p(n-x,x)}

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



@ Mr.Xcoder Навіть не знаю, чому я не використовував лямбда D:
Dead Possum

Хе-хе, ¯\_(ツ)_/¯- BTW, якщо ви хочете зберегти його повноцінною функцією, вам не знадобиться змінна, 94 байти
Містер Xcoder

@ Mr.Xcoder Так ... я відчуваю себе іржавим через деякий час відсторонений від codegolf: c
Dead Possum



0

Java 8 (229 байт)

import java.util.function.*;class A{static int j=0;static BiConsumer<Integer,Integer>f=(n,m)->{if(n==0)j++;else for(int i=Math.min(m,n);i>=1;i--)A.f.accept(n-i,i);};static Function<Integer,Integer>g=n->{f.accept(n,n);return j;};}

Безголівки:

import java.util.function.*;

class A {
    static int j = 0;
    static BiConsumer<Integer, Integer> f = (n, m) -> {
        if (n == 0)
            j++;
        else
            for (int i = Math.min(m, n); i >= 1; i--)
                A.f.accept(n - i, i);
    };
    static Function<Integer, Integer> g = n -> {
        f.accept(n, n);
        return j;
    };
}



0

JavaScript ES7, 69 байт

n=>(f=(i,s)=>i?[for(c of Array(1+n))f(i-1,s,s-=i)]:c+=!s)(n,n,c=0)&&c

JavaScript ES6, 71 байт

n=>(f=(i,s)=>i?[...Array(1+n)].map(_=>f(i-1,s,s-=i)):c+=!s)(n,n,c=0)&&c

Часова складність O (n ^ n), тому будьте обережні (явна затримка з'являється на моєму комп’ютері для F(6))

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