Pilih-ratakan daftar

20

Pertimbangkan proses "memilih" daftar bersarang. Memilih didefinisikan sebagai berikut:

  • Jika argumennya adalah daftar, ambil elemen dari daftar secara acak (seragam), dan pilih dari sana.
  • Jika argumennya bukan daftar, kembalikan saja.

Contoh implementasi dengan Python:

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

Untuk mempermudah, kami menganggap bahwa daftar bersarang hanya berisi bilangan bulat atau daftar bersarang lebih lanjut.

Diberikan daftar apa pun, dimungkinkan untuk membuat versi rata yang tidak dapat dibedakan dengan pick, yaitu memilih dari itu menghasilkan hasil yang sama, dengan probabilitas yang sama.

Misalnya, "pilih rata" daftar

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

menghasilkan daftar

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

. Alasan hanya meratakan tidak valid adalah karena unsur-unsur sub-daftar memiliki probabilitas yang lebih rendah untuk dipilih, misalnya dalam daftar [1, [2, 3]]1 memiliki peluang 2/4 = 1/2 dipilih sementara 3 dan 4 keduanya memiliki 1/4 kesempatan masing-masing.

Perhatikan juga bahwa memilih dari daftar tunggal sama dengan memilih dari elemennya, dan memilih dari daftar kosong tidak ada artinya.

Tantangan

Diberikan daftar bertumpuk dari bilangan bulat negatif, kembalikan daftar bulat bilangan bulat negatif yang dari situ memilih menghasilkan hasil yang sama dengan probabilitas yang sama.

Ini adalah , sehingga jawaban terpendek yang valid (diukur dalam byte) menang.

Spesifikasi

  • Input [2, 3, 4],, [2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]dan [2, [3, 3], [[4]]]setara (yaitu mereka harus memberikan hasil yang setara).
  • Keluaran [2, 2, 2, 2, 3, 3, 3, 3]dan [2, 3]setara (yaitu salah satu yang bisa menjadi keluaran).
  • Anda dapat mengasumsikan hanya angka dalam kisaran inklusif 1-100 yang akan ada dalam daftar.
  • Anda dapat mengasumsikan input tingkat atas akan menjadi daftar, yaitu 2bukan input yang valid.
  • Anda dapat menggunakan representasi yang wajar dari daftar bersarang, misalnya:
    [1, [2, 3]], 1 {2 3}, "[ 1 [ 2 3 ] ]", dll
  • Alih-alih daftar, Anda dapat menampilkan multiset atau pemetaan, atau, karena hanya angka dalam kisaran 1-100 yang diizinkan, daftar panjang-bilangan bulat 100 yang mewakili jumlah.

Uji Kasus

Perhatikan bahwa output yang terdaftar hanya satu kemungkinan yang valid; lihat spesifikasi untuk apa yang merupakan input atau output yang valid.

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]
Buah Esolanging
sumber
Dengan diberikan opsi pengkodean panjang dan rentang terbatas, dapatkah kita secara alternatif menampilkan daftar 100 elemen yang menggambarkan kemunculan setiap integer? (yang akan menghasilkan banyak nol untuk contoh yang diberikan)
Uriel
@Uriel Sure; Saya akan reword itu.
Buah Esolanging

Jawaban:

8

Bahasa Wolfram (Mathematica) , 41 20 byte

Flatten@*Tuples//@#&

Cobalah online! Abaikan banyak peringatan, semuanya berhasil pada akhirnya.

Bagaimana itu bekerja

Untuk daftar kedalaman 2 seperti {{1,2},{3},{4,5,6}}, Tuplesakan menghasilkan daftar yang {{1,3,4},{1,3,5},{1,3,6},{2,3,4},{2,3,5},{2,3,6}}sesuai dengan semua cara untuk mengambil elemen dari {1,2} dan memilih elemen dari{3} dan memilih elemen dari {4,5,6}.

Jika kita Flattenini, maka kita mendapatkan semua elemen dengan frekuensi yang benar, karena memilih elemen dari salah satu {1,2},{3} atau {4,5,6}setara dengan memilih elemen dari semuanya, lalu memilih yang mana yang akan disimpan.

Kami menggunakan //@untuk menerapkan ini di semua level input. Dalam prosesnya, Mathematica banyak mengeluh, karena itu mengubah atom seperti 17menjadi Tuples[17], yang sebenarnya tidak seharusnya menjadi suatu hal. Tetapi ini disederhanakan untuk hasil yang benar nanti ( Tuplessenang diperlakukan Tuples[17]sebagai daftar panjang 1, bahkan jika ia memiliki kepala selain List), sehingga keluhan tidak relevan.

Misha Lavrov
sumber
6

Python 2 , 105 102 99 byte

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

Cobalah online!

Dennis
sumber
4

Jelly , 9 8 byte

߀Œp$¬¡F

Cobalah online!

Bagaimana itu bekerja

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

Jelly , 10 byte

L€P⁸ṁ€ẎµÐL

Cobalah online!

Erik the Outgolfer
sumber
@ Challenger5 maaf, tidak ada waktu untuk itu kemarin
Erik the Outgolfer
1

Python 2 , 128 byte

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)

Cobalah online!

Port jawaban Jelly-ku.

Terima kasih untuk Jonathan Frech .

Erik the Outgolfer
sumber
Saya pikir type(i)==intbisa i*0<[].
Jonathan Frech
@ JonathanFrech Tentu, 0<[]... dan type(i)==listbisa i*0>0;)
Erik the Outgolfer
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);}

Cobalah online!

Penjelasan:

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
sumber
216 byte
ceilingcat
0

Python 2 , 144 139 byte

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

Cobalah online!

Jonathan Frech
sumber
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)))))

Darrylyeo
sumber