Виберіть-вирівняйте список


20

Розглянемо процес "вибору" вкладеного списку. Вибір визначається наступним чином:

  • Якщо аргументом є список, візьміть елемент зі списку навмання (рівномірно) та виберіть із нього.
  • Якщо аргумент не є списком, просто поверніть його.

Приклад реалізації в Python:

import random
def pick(obj):
    if isinstance(obj, list):
        return pick(random.choice(obj))
    else:
        return obj

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

З огляду на будь-який перелік, можна створити сплющену версію, яку не відрізнити pick, тобто вибір з неї дає ті ж результати, з однаковою ймовірністю.

Наприклад, "вирівнювання" списку

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

дає список

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

. Причина просто вирівнювання недійсна в тому, що елементи підсписів мають меншу ймовірність вибору, наприклад, у списку [1, [2, 3]]1 є 2/4 = 1/2 шанс бути обраним, тоді як 3 і 4 мають 1/4 шанс кожен.

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

Змагання

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

Це , тому найкоротша відповідна відповідь (вимірюється в байтах) виграє.

Технічні умови

  • Вхідні дані [2, 3, 4], [2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]і [2, [3, 3], [[4]]]еквівалентні (тобто вони повинні дати рівноцінні результати).
  • Виходи [2, 2, 2, 2, 3, 3, 3, 3]і [2, 3]еквівалентні (тобто або один може бути виведений).
  • Ви можете припустити, що в списках будуть присутні лише числа в межах 1-100.
  • Ви можете припустити, що вхід верхнього рівня буде списком, тобто 2не є коректним вводом.
  • Ви можете використовувати будь-який розумний уявлення вкладених списків, наприклад:
    [1, [2, 3]], 1 {2 3}, "[ 1 [ 2 3 ] ]"і т.д.
  • Замість списку можна вивести мультисети або відображення, або, оскільки дозволені лише числа в діапазоні 1-100, список цілих чисел, що представляють величини.

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

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

format:
input -> output
[3]                          -> [3]
[1, [1, 1]]                  -> [1]
[1, [2, 3]]                  -> [1, 1, 2, 3]
[2, 3, [4, [5, 5, 6], 6, 7]] -> [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7]
[[1, 1, 2], [2, 3, 3]]       -> [1, 2, 3]
[[1, 1, 2], [2, 3, 3, 3]]    -> [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3]

Враховуючи параметр кодування довжини та обмежений діапазон, можемо ми альтернативно вивести список із 100 елементів, що зображують події кожного цілого числа? (що призведе до багатьох нулів для наведених прикладів)
Уріель

@Uriel Sure; Я переформулюю це.
Esolanging Fruit

Відповіді:


8

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

Flatten@*Tuples//@#&

Спробуйте в Інтернеті! Ігноруйте безліч попереджень, все в результаті виходить.

Як це працює

Для списку глибини 2, такого як {{1,2},{3},{4,5,6}}, Tuplesбуде генерувати список, що {{1,3,4},{1,3,5},{1,3,6},{2,3,4},{2,3,5},{2,3,6}}відповідає всім способам вибору елемента {1,2} та вибору елемента з {3} та вибору елемента {4,5,6}.

Якщо ми Flattenце робимо , то ми отримуємо всі елементи з правильними частотами, тому що вибір елемента з одного з них {1,2}, {3}або {4,5,6}еквівалентний вибору елемента з усіх них, а потім вибору, який з них зберегти.

Ми //@застосовуємо це для всіх рівнів вводу. В процесі, Mathematica скаржиться багато, тому що це перетворення атомів , такі , як 17в Tuples[17], який дійсно не повинен бути річчю. Але згодом вони спрощують правильний результат ( Tuplesіз задоволенням Tuples[17]вважають, що це список 1 довжини, навіть якщо він має іншу голову List), тому скарги не мають значення.



4

Желе , 9 8 байт

߀Œp$¬¡F

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

Як це працює

߀Œp$¬¡F  Main link. Argument: x (array or positive integer)

     ¬    Compute elementwise logical NOT of x: a non-empty array for a non-empty array, 0 for a positive integer.
      ¡   Apply the link to the left once if ¬ returned a non-empty
          array, zero timed if it returned 0.
    $     Monadic chain:
߀            Map the main link over x.
  Œp          Take the Cartesian product.
       F  Flatten the result.


1

Python 2 , 128 байт

def f(l,p=0):m=reduce(int.__mul__,[i*0<[]or len(i)for i in l]);return p*(p==l)or f(sum([(([i],i)[i*0>0]*m)[:m]for i in l],[]),l)

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

Порт моєї відповіді на желе.

-12 завдяки Джонатану Фреху .


Я думаю, що type(i)==intможе бути i*0<[].
Джонатан Фрех

@JonathanFrech Впевнений, 0<[]... і type(i)==listможе бути i*0>0;)
Ерік Позакореневий

1

C (gcc) , 234 223 байт

h[9][101];o[101];n[9];l;L;e;main(x){for(;(x=scanf("%d",&e))>=0;x?++h[l][e],++n[l]:(e=getchar())-'['?e-']'?0:--l:++l>L&&++L);for(e=1,l=L+1;l--;){for(x=101;--x;o[x]+=e*h[l][x]);e*=n[l];}while(o[x]--?printf("%d ",x):++x<101);}

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

Пояснення:

h[9][101];  // <- number occurences per nesting level
o[101];     // <- number occurences in "flattened" array
n[9];       // <- number of entries per nesting level
l;          // <- current nesting level
L;          // <- max nesting level
e;          // <- multi-purpose temporary
main(x){    // x: multi-purpose temporary
    for(;
            // while not EOF try reading number
            (x=scanf("%d",&e))>=0;

            // number was read?
            x

                // then increment occurence and # entries in level
                ?++h[l][e],++n[l]

                // else read any character ... if not [
                :(e=getchar())-'['

                    // if not ]
                    ?e-']'

                        // do nothing
                        ?0

                        // else decrement nesting level
                        :--l

                    // else increment nesting level and adjust max level
                    :++l>L&&++L);

    // init factor in e to 1, iterate over nesting level from innermost
    for(e=1,l=L+1;l--;){

        // iterate over all numbers
        for(x=101;
                --x;

                // add factor times occurence on current level to output
                o[x]+=e*h[l][x]);

        // multiply factor by number of entries on current level
        e*=n[l];
    }

    // iterate over all numbers and output count times
    while(o[x]--?printf("%d ",x):++x<101);
}



0

JavaScript (ES6), 132 131 байт

f=A=>(_=(a,m)=>[].concat(...a.map(m)),n=1,A=A.map(a=>a.map?f(a):[a]),_(A,a=>n*=a.length),_(A,a=>_(a.map(x=>Array(n/a.length).fill(x)))))

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