Узагальнені довжини відрізка Cantor


17

Проблема

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

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

Приклад 3,1,1,1,2

Приклад: Ітеративно видалити 4 та 6 восьму

Вхід:

n - кількість ітерацій, індексованих починаючи від 0 або 1

l- список довжин відрізків як натуральних цілих чисел gcd(l)=1і непарних довжин, що представляють відносну довжину частин, які залишаються такими, як вони є, або видаляються, починаючи з сегмента, який не видаляється. Оскільки довжина списку непарна, перший та останній сегменти ніколи не видаляються. Наприклад, для звичайного набору Кантора це буде [1,1,1] для однієї третини, яка залишається, третина, яка видаляється, і знову одна третина, яка не відповідає.

Вихід:

Список цілих чисел o, gcd(o)=1відносної довжини сегмента в nітерації, коли сегменти, які не були видалені в попередній ітерації, замінюються зменшеною копією списку l. Перша ітерація якраз [1]. Ви можете використовувати будь-який однозначний спосіб виведення , навіть унітарний.

Приклади

n=0, l=[3,1,1,1,2] →                 [1]
n=1, l=[3,1,1,1,2] →     [3,    1,    1,    1,    2]
n=2, l=[3,1,1,1,2] → [9,3,3,3,6,8,3,1,1,1,2,8,6,2,2,2,4]

n=3, l=[5,2,3]     → [125,50,75,100,75,30,45,200,75,30,45,60,45,18,27]
n=3, l=[1,1,1]     → [1,1,1,3,1,1,1,9,1,1,1,3,1,1,1]

Ви можете припустити, що введення дійсне. Це , тому виграє найкоротша програма, виміряна в байтах.


Чи було б прийнятно вводити та виводити індекси видалених сегментів замість довжин? Наприклад, [0, 1, 2, 4, 6, 7]замість [3, 1, 1, 1, 2]?

@Mnemonic це не надто далеко від одинарного, тому я б сказав, що це добре.
Ангс

Чи можете ви додати один (або кілька) тестових випадків для рівних вхідних списків?
Кевін Круїссен

1
@KevinCruijssen вхідні списки гарантовано будуть непарного розміру
Angs

Відповіді:


6

Желе ,  15 13  12 байт

-2 завдяки Деннісу (використання Посилання, а не ланцюжка дозволяє використовувати право неявно ¡; Не потрібно загортати 1список у зв'язку з тим, що Jelly друкує списки одного елемента так само, як і предмет)
-1 завдяки Erik the Outgolfer (використовуйте Ɗдля збереження нового рядка від використання Ç)

1×€³§JḤ$¦ẎƊ¡

Повна програма, що друкує список у форматі Jelly (так [1]друкується як 1)

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

Як?

1×€³§JḤ$¦ẎƊ¡ - Main link: segmentLengths; iterations
1            - literal 1 (start with a single segment of length 1)
           ¡ - repeat...
             - ...times: implicitly use chain's right argument, iterations
          Ɗ  - ...do: last 3 links as a monad (with 1 then the previous output):
   ³         - (1) program's 3rd argument = segmentLengths
 ×€          -  1  multiply €ach (e.g. [1,2,3] ×€ [1,2,1] = [[1,4,3],[2,4,2],[3,6,3]])
        ¦    -  2  sparse application... 
       $     - (2) ...to: indices: last two links as a monad:
     J       - (2)          range of length = [1,2,3,...,numberOfLists]
      Ḥ      - (2)          double            [2,4,6,...] (note: out-of bounds are ignored by ¦)
    §        - (2) ...of: sum each (i.e. total the now split empty spaces)
         Ẏ   -  3  tighten (e.g. [[1,2,3],4,[5,6,7]] -> [1,2,3,4,5,6,7])
             - implicit print



4

Haskell , 76 58 байт

l%0=[1]
l%n=do(x,m)<-l%(n-1)`zip`cycle[l,[sum l]];map(*x)m

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

Функція (%)приймає список довжин рядків lяк перший аргумент, а кількість повторень - nяк другий вхід.

Дякуємо Angs та Ørjan Johansen за -18 байт!


Ви повинні мати можливість зберегти щонайменше 7 байт, перемкнувшись на рекурсію nта впавши #зовсім
Angs

Незалежно від пропозиції @Angs, оригінал %можна скоротити до l%a=do(x,m)<-zip a$a>>[l,[sum l]];(*x)<$>m .
Ørjan Johansen

3

JavaScript (Firefox 42-57), 80 байт

f=(n,l,i=0)=>n--?[for(x of l)for(y of(i^=1)?f(n,l):[eval(l.join`+`)**n])x*y]:[1]

Потрібні ці конкретні версії, оскільки він використовує як розуміння масиву, так і експоненцію.



2

Java 10, 261 байт

L->n->{if(n<1){L.clear();L.add(1);}else if(n>1){var C=new java.util.ArrayList<Integer>(L);for(int l=C.size(),i,x,t,s;n-->1;)for(i=x=0;i<L.size();){t=L.remove(i);if(i%2<1)for(;i%-~l<l;)L.add(i,C.get((i++-x)%l)*t);else{x++;s=0;for(int c:C)s+=c;L.add(i++,t*s);}}}}

Змінює вхідний список замість повернення нового для збереження байтів.

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

L->n->{                       // Method with List and integer parameters and no return-type
  if(n<1){                    //  If `n` is 0:
    L.clear();                //   Remove everything from the List
    L.add(1);}                //   And only add a single 1
                              //  Else-if `n` is 1: Leave the List as is
  else if(n>1){               //  Else-if `n` is 2 or larger:
    var C=new java.util.ArrayList<Integer>(L);
                              //   Create a copy of the input-List
    for(int l=C.size(),       //   Set `l` to the size of the input-List
        i,x,t,s;              //   Index and temp integers
        n-->1;)               //   Loop `n-1` times:
      for(i=x=0;              //    Reset `x` to 0
          i<L.size();){       //    Inner loop `i` over the input-List
        t=L.remove(i);        //     Remove the current item, saving its value in `t`
        if(i%2<1)             //     If the current iteration is even:
          for(;i%-~l<l;)      //      Loop over the copy-List
            L.add(i,C.get((i++-x)%l)*t);
                              //       And add the values multiplied by `t`
                              //       at index `i` to the List `L`
        else{                 //     Else (the current iteration is odd):
          x++;                //      Increase `x` by 1
          s=0;for(int c:C)s+=c;
                              //      Calculate the sum of the copy-List
          L.add(i++,t*s);}}}} //      Add this sum multiplied by `t`
                              //      at index `i` to the List `L`



2

К (нг / к) , 27 байт

{x{,/y*(#y)#x}[(y;+/y)]/,1}

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

{ }є функцією з аргументами xіy

(y;+/y)пара yта її сума

{ }[(y;+/y)]проекція (aka currying або часткове застосування) діадичної функції з одним аргументом. xбуде (y;+/y)і yбуде аргументом при застосуванні.

,1 одномісний список, що містить 1

x{ }[ ]/застосувати прогнозні xчаси

(#y)#x змінити форму в довжину поточного результату, тобто чергувати зовнішній y і його суму

y* помножте кожен елемент вищезазначеного на відповідний елемент поточного результату

,/ з'єднати



1

Pyth , 20 байт

us.e?%k2*bsQ*LbQGE]1

Вхід - це сегментний масив l, потім ітерації n. Спробуйте в Інтернеті тут або одразу підтвердіть усі тестові випадки тут .

us.e?%k2*bsQ*LbQGE]1   Implicit, Q=1st arg (segment array), E=2nd arg (iterations)
u                E     Execute E times, with current value G...
                  ]1   ... and initial value [1]:
  .e            G        Map G, with element b and index k:
        *bsQ               Multiply b and the sum of Q {A}
            *LbQ           Multiply each value of Q by b {B}
    ?%k2                   If k is odd, yield {A}, otherwise yield {B}
 s                       Flatten the resulting nested array
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.