Створення базових елементів алгебри Стіенрода


16

Алгебра Стіенрода - важлива алгебра, що виходить в алгебраїчній топології. Алгебра Стіродрода генерується операторами, які називаються "квадрати Стіенрода", по одному існує для кожного натурального числа i. Існує основа алгебри Стіенрода, що складається з "допустимих одночленів" в операціях квадратування. Наша мета створити цю основу.

Послідовність натуральних чисел називається допустимою, якщо кожне ціле число є щонайменше вдвічі наступним. Так, наприклад [7,2,1], допустимо, тому що і . З іншого боку, це неприпустимо, оскільки . (У топології ми запишемо для послідовності ).722221[3,2]3<22Sq7Sq2Sq1[7,2,1]

Ступінь послідовності є сумою її записів. Так, наприклад, ступінь [7,2,1]становить . Перевищення припустимої послідовності є першим елементом мінус сума інших елементів, так що має надлишок .7+2+1=10[7,2,1]7-2-1=4

Завдання

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

Приклади:

 Input: 3,1
 Output: [[2,1]]

Тут ми шукаємо допустимі послідовності із загальною кількістю 3. Є два варіанти [3]та [2,1]. ( [1,1,1]і [1,2]мають суму 3, але вони неприпустимі). Надлишок [3]становить 3, а надлишок [2,1]- . Таким чином, тільки послідовність з надлишком є .2-1=11[2,1]

Input: 6, 6
Output: [[6], [5, 1], [4, 2]] (or any reordering, e.g., [[5,1],[4,2],[6]])

Оскільки перевищення завжди менше або дорівнює ступеню, ми не маємо надлишкової умови. Таким чином, ми просто намагаємося знайти всі допустимі послідовності ступеня 6. Параметри є [6], [5, 1]і [4, 2]. (Вони мають перевищення , та )65-1=44-2=2

Input: 10, 5
Output: [[7,3], [7,2,1], [6,3,1]]

Допустимими послідовностями ступеня 10 є:

[[10], [9,1], [8,2], [7,3], [7,2,1], [6,3,1]]

Вони мають перевищення , , , , і відповідно, тому останні три працюють.109-1=88-2=67-3=47-2-1=46-3-1=2

Оцінка балів

Це код гольфу: найкоротше рішення в байтах.

Тестові приклади:

Будь-яке упорядкування результатів однаково добре, тому для введення (3, 3), виведення [[3],[2,1]]або [[2,1],[3]]однаково прийнятного (однак, [[1,2],[3]]це не так).

Input: 1, 1
Output: [[1]]

Input: 3, 3
Output: [[2,1], [3]]

Input: 3, 1
Output: [[2,1]]

Input: 6, 6
Output: [[6], [5, 1], [4, 2]]

Input: 6, 4
Output: [[5,1], [4,2]]

Input: 6, 1
Output: []

Input: 7, 7
Output: [[7], [6,1], [4,2,1], [5,2]]

Input: 7,1
Output: [[4,2,1]]

Input: 10, 10
Output: [[10], [9,1], [7,2,1], [6,3,1], [8,2], [7,3]]

Input: 10, 5
Output: [[7,3], [7,2,1], [6,3,1]]

Input: 26, 4
Output: [15, 7, 3, 1]

Input: 26, 6
Output: [[16, 7, 2, 1], [16, 6, 3, 1], [15, 7, 3, 1], [16, 8, 2], [16, 7, 3]]

1
Гаразд, я надам коротке пояснення.
Гуд

Відповіді:


6

05AB1E , 16 12 байт

Збережено 4 байти завдяки Grimy

Åœíʒx¦@P}ʒÆ@

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

Пояснення

Ŝ              # integer partitions
  í             # reverse each
   ʒ    }       # filter, keep only elements true under:
    x           # each element doubled
     ¦          # remove the first element in the doubled list
      @         # compare with greater than or equal with the non-doubled
       P        # product
         ʒ      # filter, keep only elements true under:
          Æ     # reduce by subtraction
           @    # compare with greater than or equal to second input

ćsO-є вбудованим Æ.
Grimmy

Також À@¨може бути ¦@.
Гріммі

1
@Grimy: О, вау, як я пропустив це :) Дякую!
Емінья

5

Мова Вольфрама (Mathematica) , 67 62 байт

Cases[IntegerPartitions@#,a_/;2a[[1]]-#<=#2>Max@Ratios@a<=.5]&

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

-4 байти від @attinat

  • IntegerPartitions@d : Отримайте всі списки цілих чисел, які підсумовуються d
  • Cases[,...]: Фільтр за наступною умовою:
    • 2#& @@# - d <= e &&: Двічі перший елемент мінус сума менша за e, і ...
    • Max@Ratios@#<=.5: Співвідношення послідовних елементів списку менше ніж 1/2.

Оскільки eменше 0,5, ми можемо перетворити це на ланцюгову нерівність.

Для кількох зайвих байтів це значно швидше: спробуйте в Інтернеті!



5

Желе ,  16  15 байт

-1 завдяки Еріку Outgolfer (розумне регулювання перевірки, що дозволяє отримати єдиний фільтр)

:Ɲ;_/>¥’Ạ
ŒṗUçƇ

Дьядичне посилання, що приймає додатне ціле число, dзліва та додатне ціле число, eправоруч, яке дає список списків натуральних чисел.

Спробуйте в Інтернеті! (колонтитул форматує результати, щоб уникнути списку неявного форматування списку Jelly, як повноцінної програми)

Як?

:Ɲ;_/>¥’Ạ - Link 1: admissible and within excess limit? descending list, L; excess limit, e
 Ɲ        - neighbour-wise:
:         -   integer division  -- admissible if all these are >1
      ¥   - last two links as a dyad - i.e. f(L,e):
    /     -   reduce (L) by:
   _      -     subtraction
     >    -   greater than (e)? (vectorises)  -- within excess if all these are ==0
  ;       - concatenate
       ’  - decrement (vectorises)
        Ạ - all (non-zero)?

ŒṗUçƇ - Main link: integer, d; integer, e
Œṗ    - partitions (of d)
  U   - reverse each
    Ƈ - filter keep those (v in that) for which:
   ç  -   call last Link (1) as a dyad - i.e. f(v, e)

Ви можете зберегти байт розумним трюком . Може знадобитися трохи часу, щоб зрозуміти, чому це працює. : P
Ерік Аутгольфер

@EriktheOutgolfer приголомшливо, я спробував кілька подібних способів включити два фільтри (включаючи конкатенацію), але все виходило як 16, оскільки я не думав одночасно використовувати трюк декременту.
Джонатан Аллан


3

JavaScript (V8) ,  88 87  81 байт

Вводиться як " (e)(d). Друкує послідовності в STDOUT.

e=>g=(d,s=x=d,a=[])=>s>0?d&&g(d-1,s,a,g(d>>1,s-d,[...a,d])):a[s]*2-x<=e&&print(a)

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

Прокоментував

e =>                  // e = maximum excess
  g = (               // g is a recursive function taking:
    d,                //   d   = expected degree; actually used as the next candidate
                      //         term of the sequence in the code below
    s =               //   s   = current sum, initialized to d; we want it to be equal
                      //         to 0 when a sequence is complete
    x = d,            //   x   = copy of the expected degree
    a = []            //   a[] = current sequence
  ) =>                //
    s > 0 ?           // if s is positive:
      d &&            //   if d is not equal to 0:
        g(            //     outer recursive call:
          d - 1,      //       decrement d
          s,          //       leave s unchanged
          a,          //       leave a[] unchanged
          g(          //       inner recursive call:
            d >> 1,   //         update d to floor(d / 2)
            s - d,    //         subtract d from s
            [...a, d] //         append d to a[]
          )           //       end of inner recursive call
        )             //     end of outer recursive call
    :                 //   else:
      a[s] * 2 - x    //     s if either 0 (success) or negative (failure)
                      //     if s is negative, a[s] is undefined and this expression
                      //     evaluates to NaN, forcing the test to fail
      <= e            //     otherwise, we test whether the excess is valid
      && print(a)     //     and we print a[] if it is

3

Pyth , 23 байти

f!>-FTvzf!<#2/MCtBT_M./

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

f!>-FTvzf!<#2/MCtBT_M./Q   Implicit: Q=input 1, vz=input 2
                           Trailing Q inferred
                     ./Q   Generate partitions of Q (ordered lists of integers which sum to Q)
                   _M      Reverse each
        f                  Filter keep elements of the above, as T, where:
               CtBT          Pair the set with itself without the first element and transpose
                             This yields all adjacent pairs of values
             /M              Integer divide each pair
           #                 Filter keep elements...
          < 2                ... less than 2
                             For admissible sequences this will be empty
         !                   Logical NOT - maps [] to true, populated lists to false
                           Result of filter are all admissible sequences
f                          Filter keep the above, as T, where:
   -FT                       Reduce T by subtraction to get degree
 !>   vz                     Is the above not greater than vz?
                           Implicit print

3

Python 3 , 213 байт

Розуміння гігантського списку. Швидше за все, це не найкращий спосіб зробити це, але я не можу зрозуміти, як пропустити заяви if

import itertools as z
f=lambda d,e:[c for c in [[b for b in list(z.permutations(range(1,d+1),i)) if sum(b)==d and b[0]-sum(b[1:i])<=e and all([b[i]>=b[i+1]*2 for i in range(len(b)-1)])] for i in range(1,5)] if c]

Пітон 3 , 172 байти

from itertools import*
r=range
f=lambda d,e:filter(len,[[b for b in permutations(r(1,d+1),i)if d==sum(b)and~e<d-2*b[0]and all(i>=j*2for i,j in zip(b,b[1:]))]for i in r(5)])

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

Як за редакціями @Jonas Ausevicius


2
Ласкаво просимо на сайт. Кілька порад: я схоже, що ви не надто добре знайомі з тим, де потрібен інтервал у python. У вас є кілька місць, які просто можна було б видалити пробілами, тож я б задумався про це. Також такі функції, як, allможе приймати генератор, так що ви можете просто робити all(...)замість цього all([...]). Нарешті, оскільки ваше подання є абсолютно анонімною функцією, ви не накладаєте штрафних санкцій за призначення ( f=) і, таким чином, можете вирахувати його з вашої оцінки (-2 байти).
Опублікувати Rock Garf Hunter


Так, а також у python3 ви можете подавати список, [*(...)]замість list(...)якого зазвичай зберігає байт, але у вашому випадку зберігає 2, оскільки він також дозволяє видалити пробіл.
Опублікувати Rock Garf Hunter

2
189 байт, якщо добре повернути об’єкт фільтра, інакше 192 с [*filter(...)]. Також ласкаво просимо :)
Моніку


2

Вугілля деревне , 42 байти

Fθ⊞υ⟦⊕ι⟧FυF…·⊗§ι⁰θ⊞υ⁺⟦κ⟧ιIΦυ›⁼Σιθ‹η⁻⊗§ι⁰Σι

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

Fθ⊞υ⟦⊕ι⟧

Спочатку створіть список зі списків [1]..[d].

FυF…·⊗§ι⁰θ⊞υ⁺⟦κ⟧ι

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

IΦυ›⁼Σιθ‹η⁻⊗§ι⁰Σι

Виведіть лише ті списки, ступінь яких dі перевищення яких не перевищує e. (Сума ступеня і перевищення дорівнює подвоєному першому номеру списку.)


2

Пітон 3 , 156 байт

lambda d,e:[x for y in range(5)for x in permutations(range(1,d+1),y)if all(i>=j*2for i,j in zip(x,x[1:]))and d==sum(x)and~e<d-2*x[0]]
from itertools import*

приймає d,eяк вхід; виводить список кортежів

Подібно до @OrangeCherries відповіді та допомоги у коментарях; але більше байтів збережено

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



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