Wybierz spłaszcz listę

20

Rozważ proces „wybierania” zagnieżdżonej listy. Wybór jest definiowany następująco:

  • Jeśli argumentem jest lista, weź element z listy losowo (jednolicie) i wybierz z niego.
  • Jeśli argumentem nie jest lista, po prostu ją zwróć.

Przykładowa implementacja w Pythonie:

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

Dla uproszczenia zakładamy, że listy zagnieżdżone zawierają tylko liczby całkowite lub dalsze listy zagnieżdżone.

Na dowolnej liście można utworzyć spłaszczoną wersję, której nie można odróżnić pick , tzn. Wybranie z niej daje te same wyniki z takim samym prawdopodobieństwem.

Na przykład „spłaszczanie” listy

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

daje listę

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

. Powodem, dla którego po prostu spłaszczanie jest nieprawidłowe, jest to, że elementy list podrzędnych mają mniejsze prawdopodobieństwo wyboru, np. Na liście[1, [2, 3]] 1 ma szansę wyboru 2/4 = 1/2, podczas gdy 3 i 4 mają 1/4 przypadek każdy.

Zauważ również, że wybieranie z listy singletonów jest równoważne z wybieraniem z jego elementu i że wybieranie z pustej listy nie ma znaczenia.

Wyzwanie

Biorąc pod uwagę zagnieżdżoną listę nieujemnych liczb całkowitych, zwróć spłaszczoną listę nieujemnych liczb całkowitych, z których wybranie daje te same wyniki z takim samym prawdopodobieństwem.

To jest , więc wygrywa najkrótsza ważna odpowiedź (mierzona w bajtach).

Dane techniczne

  • Wejścia [2, 3, 4], [2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]i [2, [3, 3], [[4]]]są równoważne (tj powinni dać równoważne wyniki).
  • Wyjścia [2, 2, 2, 2, 3, 3, 3, 3]i [2, 3]są równoważne (tzn. Jedno z nich może być wyjściem).
  • Możesz założyć, że na listach będą znajdować się tylko liczby z przedziału 1-100.
  • Możesz założyć, że wejściem najwyższego poziomu będzie lista, tzn. Że 2nie jest to poprawne wejście.
  • Można użyć dowolnego rozsądną reprezentację zagnieżdżonych listach, na przykład:
    [1, [2, 3]], 1 {2 3}, "[ 1 [ 2 3 ] ]", itd.
  • Zamiast listy można wyprowadzić multiset lub mapowanie, lub, ponieważ dozwolone są tylko liczby z zakresu 1-100, listę liczb całkowitych o długości 100 reprezentujących ilości.

Przypadki testowe

Zauważ, że wymienione dane wyjściowe są tylko jedną poprawną możliwością; zobacz specyfikację tego, co stanowi prawidłowy wkład lub wynik.

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]
Esolanging Fruit
źródło
Biorąc pod uwagę opcję kodowania długości i ograniczony zakres, czy możemy alternatywnie wypisać listę 100 elementów przedstawiających wystąpienia każdej liczby całkowitej? (co da wiele zer dla podanych przykładów)
Uriel,
@Uriel Sure; Przeredaguję to.
Esolanging Fruit

Odpowiedzi:

8

Wolfram Language (Mathematica) , 41 20 bajtów

Flatten@*Tuples//@#&

Wypróbuj online! Zignoruj ​​wiele ostrzeżeń, wszystko się ostatecznie kończy.

Jak to działa

W przypadku listy o głębokości 2, takiej jak {{1,2},{3},{4,5,6}}, Tupleswygenerowana zostanie lista {{1,3,4},{1,3,5},{1,3,6},{2,3,4},{2,3,5},{2,3,6}}odpowiadająca wszystkim sposobom pobrania elementu {1,2} i pobrania elementu {3} oraz pobrania elementu z{4,5,6} .

Jeśli mamy Flattento, to możemy uzyskać wszystkie elementy z odpowiednich częstotliwości, ponieważ zbieranie element z jednego dnia {1,2}, {3}czy {4,5,6}jest równoważne zbieranie element z wszystkich z nich, a następnie wybiera, który z nich zachować.

Używamy tego, //@aby zastosować to na wszystkich poziomach danych wejściowych. W tym czasie Mathematica bardzo narzeka, ponieważ zamienia atomy takie jak 17w Tuples[17], co tak naprawdę nie powinno być niczym. Ale upraszczają one później właściwy wynik (z Tuplesprzyjemnością traktuje Tuples[17]jako listę długości 1, nawet jeśli ma głowę inną niż List), więc narzekanie jest bez znaczenia.

Misza Ławrow
źródło
6

Python 2 , 105 102 99 bajtów

g=lambda y=[],*z:[w+[n]for n in y for w in g(*z)]or[y]
f=lambda x:x<[]and[x]or sum(g(*map(f,x)),[])

Wypróbuj online!

Dennis
źródło
4

Galaretka , 9 8 bajtów

߀Œp$¬¡F

Wypróbuj online!

Jak to działa

߀Œ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.
Dennis
źródło
1

Galaretka , 10 bajtów

L€P⁸ṁ€ẎµÐL

Wypróbuj online!

Erik the Outgolfer
źródło
@ Challenger5 przepraszam, nie ma na to wczoraj czasu
Erik the Outgolfer
1

Python 2 , 128 bajtów

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)

Wypróbuj online!

Port mojej galaretki odpowiedzi.

-12 dzięki Jonathan Frech .

Erik the Outgolfer
źródło
Myślę, że type(i)==intmoże być i*0<[].
Jonathan Frech,
@JonathanFrech Pewnie, 0<[]... i type(i)==listmoże być i*0>0;)
Erik Outgolfer
1

C (gcc) , 234 223 bajty

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);}

Wypróbuj online!

Wyjaśnienie:

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);
}
Felix Palmen
źródło
216 bajtów
ceilingcat
0

Python 2 , 144 139 bajtów

def f(A,p):[F.append((len(A)*p,a))if a*0<[]else f(a,len(A)*p)for a in A]
F=[];f(input(),1);R=[]
for v in F:R+=max(F)[0]/v[0]*[v[1]]
print R

Wypróbuj online!

Jonathan Frech
źródło
0

JavaScript (ES6), 132 131 bajtów

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)))))

darrylyeo
źródło