Aplatissez une liste

20

Considérez le processus de "sélection" d'une liste imbriquée. Le prélèvement est défini comme suit:

  • Si l'argument est une liste, prenez un élément de la liste au hasard (uniformément) et choisissez-le.
  • Si l'argument n'est pas une liste, renvoyez-le simplement.

Un exemple d'implémentation en Python:

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

Pour simplifier, nous supposons que les listes imbriquées ne contiennent que des entiers ou d'autres listes imbriquées.

Étant donné n'importe quelle liste, il est possible de créer une version aplatie qui ne se distingue pas pick, c'est-à-dire que sa cueillette donne les mêmes résultats, avec la même probabilité.

Par exemple, "aplatir" la liste

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

donne la liste

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

. La simple raison pour laquelle l'aplatissement n'est pas valide est parce que les éléments des sous-listes ont une probabilité plus faible d'être choisis, par exemple, dans la liste, [1, [2, 3]]le 1 a 2/4 = 1/2 chance d'être choisi tandis que 3 et 4 ont tous deux 1/4 chance chacun.

Notez également que la sélection dans une liste singleton est équivalente à la sélection dans son élément, et que la sélection dans une liste vide n'a aucune signification.

Le défi

Étant donné une liste imbriquée d'entiers non négatifs, renvoyez une liste aplatie d'entiers non négatifs à partir de laquelle la sélection donne les mêmes résultats avec la même probabilité.

Il s'agit de , donc la réponse valide la plus courte (mesurée en octets) l'emporte.

Caractéristiques

  • Les entrées [2, 3, 4], [2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]et [2, [3, 3], [[4]]]sont équivalentes (ils devraient donner des résultats équivalents).
  • Les sorties [2, 2, 2, 2, 3, 3, 3, 3]et [2, 3]sont équivalentes (c'est-à-dire que l'une ou l'autre pourrait être sortie).
  • Vous pouvez supposer que seuls les nombres compris entre 1 et 100 seront présents dans les listes.
  • Vous pouvez supposer que l'entrée de niveau supérieur sera une liste, c'est 2-à- dire qu'elle n'est pas une entrée valide.
  • Vous pouvez utiliser une représentation raisonnable des listes imbriquées, par exemple:
    [1, [2, 3]], 1 {2 3}, "[ 1 [ 2 3 ] ]", etc.
  • Au lieu d'une liste, vous pouvez générer un multiset ou un mappage, ou, puisque seuls les nombres compris entre 1 et 100 sont autorisés, une liste de 100 entiers de longueur représentant des quantités.

Cas de test

Notez que les sorties répertoriées ne sont qu'une seule possibilité valide; voir les spécifications pour ce qui constitue une entrée ou une sortie valide.

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
la source
Compte tenu de l'option de codage de longueur et de la plage bornée, pouvons-nous alternativement afficher une liste de 100 éléments décrivant les occurrences de chaque entier? (qui se traduira par de nombreux zéros pour les exemples donnés)
Uriel
@Uriel Sure; Je vais le reformuler.
Esolanging Fruit

Réponses:

8

Wolfram Language (Mathematica) , 41 20 octets

Flatten@*Tuples//@#&

Essayez-le en ligne! Ignorez les nombreux avertissements, tout fonctionne à la fin.

Comment ça fonctionne

Pour une liste de profondeur 2 telle que {{1,2},{3},{4,5,6}}, Tuplesva générer la liste {{1,3,4},{1,3,5},{1,3,6},{2,3,4},{2,3,5},{2,3,6}}correspondant à toutes les façons de choisir un élément {1,2} et de choisir un élément {3} et de choisir un élément {4,5,6}.

Si nous le faisons Flatten, alors nous obtenons tous les éléments avec les fréquences correctes, parce que choisir un élément de l' un de {1,2}, {3}ou {4,5,6}équivaut à choisir un élément de tous, puis choisir celui à garder.

Nous utilisons //@pour appliquer cela à tous les niveaux de l'entrée. Dans le processus, Mathematica se plaint beaucoup, car il transforme des atomes comme 17en Tuples[17], ce qui n'est vraiment pas censé être une chose. Mais ceux-ci simplifient le bon résultat plus tard ( Tuplesest heureux de traiter Tuples[17]comme une liste de longueur 1, même si elle a une tête autre que List), de sorte que la plainte n'est pas pertinente.

Misha Lavrov
la source
6

Python 2 , 105 102 99 octets

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)),[])

Essayez-le en ligne!

Dennis
la source
4

Gelée , 9 8 octets

߀Œp$¬¡F

Essayez-le en ligne!

Comment ça fonctionne

߀Œ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
la source
1

Gelée , 10 octets

L€P⁸ṁ€ẎµÐL

Essayez-le en ligne!

Erik le Outgolfer
la source
@ Challenger5 désolé, pas de temps pour ça hier
Erik the Outgolfer
1

Python 2 , 128 octets

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)

Essayez-le en ligne!

Port de ma réponse Jelly.

-12 merci à Jonathan Frech .

Erik le Outgolfer
la source
Je pense que c'est type(i)==intpossible i*0<[].
Jonathan Frech
@JonathanFrech Bien sûr, 0<[]... et type(i)==listpeut l'être i*0>0;)
Erik the Outgolfer
1

C (gcc) , 234 223 octets

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

Essayez-le en ligne!

Explication:

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
la source
216 octets
plafondcat
0

Python 2 , 144 139 octets

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

Essayez-le en ligne!

Jonathan Frech
la source
0

JavaScript (ES6), 132 131 octets

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
la source