Seleziona un elenco


20

Considera il processo di "raccolta" di un elenco nidificato. La raccolta è definita come segue:

  • Se l'argomento è un elenco, prendi un elemento dall'elenco in modo casuale (uniformemente) e scegli da quello.
  • Se l'argomento non è un elenco, è sufficiente restituirlo.

Un'implementazione di esempio in Python:

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

Per semplicità, supponiamo che gli elenchi nidificati contengano solo numeri interi o ulteriori elenchi nidificati.

Dato qualsiasi elenco, è possibile creare una versione appiattita che è indistinguibile da pick, vale a dire prelevandola da essa produce gli stessi risultati, con la stessa probabilità.

Ad esempio, "spianare" l'elenco

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

restituisce l'elenco

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

. Il motivo per cui semplicemente l'appiattimento non è valido è perché gli elementi delle sotto-liste hanno una probabilità inferiore di essere scelti, ad es. Nella lista [1, [2, 3]]1 ha una probabilità di 2/4 = 1/2 di essere scelta mentre 3 e 4 hanno entrambi un 1/4 possibilità ciascuno.

Si noti inoltre che la selezione da un elenco singleton equivale alla selezione dal suo elemento e che il prelievo da un elenco vuoto non ha alcun significato.

La sfida

Dato un elenco nidificato di numeri interi non negativi, restituisce un elenco appiattito di numeri interi non negativi da cui il prelievo produce gli stessi risultati con la stessa probabilità.

Questo è , quindi vince la risposta valida più breve (misurata in byte).

specificazioni

  • Gli input [2, 3, 4], [2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]e [2, [3, 3], [[4]]]sono equivalenti (cioè dovrebbero dare risultati equivalenti).
  • Le uscite [2, 2, 2, 2, 3, 3, 3, 3]e [2, 3]sono equivalenti (cioè uno dei due potrebbe essere prodotto).
  • Puoi presumere che negli elenchi siano presenti solo numeri compresi nell'intervallo compreso tra 1 e 100.
  • Si può presumere che l'input di livello superiore sarà un elenco, ovvero che 2non sia un input valido.
  • È possibile utilizzare qualsiasi ragionevole rappresentazione di liste nidificate, ad esempio:
    [1, [2, 3]], 1 {2 3}, "[ 1 [ 2 3 ] ]", etc.
  • Invece di un elenco, è possibile generare un multiset o un mapping oppure, poiché sono consentiti solo numeri nell'intervallo 1-100, un elenco di numeri interi di lunghezza 100 che rappresentano le quantità.

Casi test

Si noti che le uscite elencate sono solo una possibilità valida; vedere le specifiche per ciò che costituisce un input o output valido.

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]

Data l'opzione di codifica della lunghezza e l'intervallo limitato, possiamo in alternativa generare un elenco di 100 elementi che rappresentano le occorrenze di ogni numero intero? (che risulterà con molti zeri per gli esempi forniti)
Uriel

@Uriel Sure; Lo riformulerò.
Esolanging Fruit

Risposte:


8

Wolfram Language (Mathematica) , 41 20 byte

Flatten@*Tuples//@#&

Provalo online! Ignora i molti avvertimenti, alla fine tutto funziona.

Come funziona

Per un elenco di profondità 2 come {{1,2},{3},{4,5,6}}, Tuplesgenererà l'elenco {{1,3,4},{1,3,5},{1,3,6},{2,3,4},{2,3,5},{2,3,6}}corrispondente a tutti i modi per selezionare un elemento {1,2} e scegliere un elemento {3} e scegliere un elemento da {4,5,6}.

Se lo facciamo Flatten, otteniamo tutti gli elementi con le frequenze corrette, perché scegliere un elemento da uno di {1,2}, {3}o {4,5,6}equivale a scegliere un elemento da tutti, quindi scegliere quale mantenere.

Usiamo //@per applicare questo a tutti i livelli dell'input. Nel processo, Mathematica si lamenta molto, perché sta trasformando atomi come 17in Tuples[17], che in realtà non dovrebbe essere una cosa. Ma questi semplificano al risultato giusto in seguito ( Tuplesè felice di trattare Tuples[17]come un elenco di lunghezza 1, anche se ha una testa diversa da quella List), quindi la lamentela è irrilevante.



4

Gelatina , 9 8 byte

߀Œp$¬¡F

Provalo online!

Come funziona

߀Œ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

C (gcc) , 234 223 byte

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

Provalo online!

Spiegazione:

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 byte

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.