Bersenang-senang dengan string dan angka

13

Inilah teka-teki pemrograman untuk Anda:

Diberikan daftar pasangan string dan angka yang sesuai, misalnya [[A,37],[B,27],[C,21],[D,11],[E,10],[F,9],[G,3],[H,2]],, menampilkan daftar lain yang hanya memiliki string dengan cara berikut:

  1. Jumlah total dari string apa pun harus sama persis dengan angka terkait dalam data input.

  2. Tidak ada string yang harus diulang berdekatan dalam urutan, dan setiap string harus muncul dalam daftar output.

  3. Pemilihan string selanjutnya harus dilakukan secara acak selama mereka tidak melanggar dua aturan di atas. Setiap solusi harus memiliki probabilitas yang tidak nol untuk dipilih.

  4. Jika tidak ada kombinasi yang memungkinkan, hasilnya harus adil 0.

Daftar input dapat diberikan dalam urutan apa pun (diurutkan atau tidak disortir), dan string dalam daftar mungkin panjang.


Output sampel untuk input sampel di atas 1

[A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,B,A,C,A,C,A,C,A,C,A,C,A,C,A,C,A,C,A,C,A,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,D,C,E,F,E,F,E,F,E,F,E,F,E,F,E,F,E,F,E,F,E,G,H,G,H,G]


Masukkan sampel 2:

[[A,6],[B,1],[C,1]]

Output untuk input kedua:

0

karena tidak ada daftar yang mungkin berdasarkan aturan.


Masukan sampel 3:

[[AC,3],[BD,2]]

output yang valid: [AC,BD,AC,BD,AC]

keluaran tidak valid: [AC,BD,AC,AC,BD]


Jika klarifikasi lebih lanjut diperlukan, tolong, jangan ragu untuk memberi tahu saya di komentar dan saya akan segera bertindak sesuai.

Ini adalah , jadi kode terpendek dalam byte untuk setiap bahasa akan menang!

Stupid_Intern
sumber
Tantangan yang bagus! Saya pikir itu sedikit kurang ditentukan oleh standar kami. Saya sangat merekomendasikan penggunaan The Sandbox untuk mendapatkan banyak umpan balik sebelum memposting tantangan sehingga Anda tidak mendapatkan downvotes atau menutup suara! :-) Saya menantikan untuk melihat lebih banyak tantangan baik dari Anda!
Giuseppe
@ Giuseppe terima kasih, saya akan mencoba melewati itu. Beri tahu saya jika saya perlu menambahkan detail apa pun jika ada yang terlewat.
Stupid_Intern
1
Bisakah kita mengambil 2 input, hanya string dan hanya angka?
FrownyFrog
mungkin ada ambiguitas dalam penggunaan frasa 'acak', beberapa solusi ini menggunakan pustaka "acak" yang sebenarnya hanya pseudorandom.
don cerah

Jawaban:

6

Jelly , 11 byte

Œṙ'Œ!⁻ƝẠ$ƇX

Cobalah online!

Œṙ'Œ!⁻ƝẠ$ƇX Arguments: z
  '         Flat: Apply link directly to x, ignoring its left and right depth properties
Œṙ            Run-length decode
   Œ!       Permutations of x
         Ƈ  Filter; keep elements of x for which the link returns a truthy result
        $     ≥2-link monadic chain
      Ɲ         Apply link on overlapping pairs (non-wrapping)
     ⁻            x != y
       Ạ        Check if all elements of x have a truthy value (+vacuous truth)
          X Pick a random element of x; return 0 if the list is empty.
Erik the Outgolfer
sumber
Jika Œṙtidak vectorize itu akan bekerja tanpa'
dylnan
5

Jeli , 17 byte

Wẋ¥Ɲ€ẎẎŒ!Œɠ’SƊÐḟX

Cobalah online!

HyperNeutrino
sumber
Ketika saya mencobanya ["A", 100], ["B", 3]tidak menghasilkan apa-apa itu macet saya pikir.
Stupid_Intern
1
@newguy Membuat semua permutasi dari 103 item tidak terkenal karena kecepatannya. Untuk referensi, hasilnya setelah Œ!akan memiliki 99029007164861804075467152545817733490901658221144924830052805546998766658416222832141441073883538492653516385977292093222882134415149891584000000000000
Erik the Outgolfer
@newguy Solusi ini O(n!)singkat tapi kecepatannya tidak masalah. Jangan mencobanya dengan apa pun di mana jumlahnya bertambah hingga sekitar 6-8 atau lebih: P
HyperNeutrino
Dapat Œṙmembantu
Arnauld
1
@dylnan Saya tidak berpikir ini berfungsi untuk string yang saya coba ["AT", 3], ["B", 3]dan dapatkan TBATATBABsebagai output yang salah
Stupid_Intern
5

Python 2 , 114 189 185 174 bytes

from random import*
a=input()
s=u=[]
while a:x,y=a.pop(a.index(next((w for w in a if w[1]>sum(v[1]for v in a+u)/2),choice(a))));s=s+[x];a+=u;u=[[x,y-1]]*(y>1)
print[s,0][y>1]

Cobalah online!

Aduh! Jauh lebih sulit dengan aturan 3 ... :). Masih berusaha menghindariO(n!) pendekatan, sehingga dapat menangani semua kasus uji sebelum kematian panas alam semesta ...

Algoritma: anggap jumlah total jumlah string adalah t. Jika string memiliki jumlah ndengan 2*n>t+1, maka tidak mungkin untuk memenuhi kendala. Oleh karena itu, jika string (tidak termasuk orang yang dipilih sebelumnya) memiliki count ndengan 2*n=t+1, maka kita harus memilih string yang berikutnya. Jika tidak, kita dapat memilih secara acak string apa pun yang bukan string yang dipilih sebelumnya.

Chas Brown
sumber
1
@Arnauld: benar-benar ketinggalan! diperbaiki sekarang.
Chas Brown
4

R , 148 141 byte

function(x,y,p=combinatXXpermn(rep(seq(y),y)),q=which(sapply(lapply(p,diff),all)))"if"(n<-sum(q|1),"if"(n-1,x[p[[sample(q,1)]]],x[p[[q]]]),0)

Cobalah online! (Saya sudah menyalin combinat::permndan memanggilnya di combinatXXpermnsana.)

Solusi Brute force O (n!).

Penggunaan permndari combinatpaket untuk menghasilkan semua kemungkinan pemesanan. Kemudian periksa untuk melihat apakah ada yang mengikuti aturan, dan mengambil salah satu dari mereka secara acak.

ngm
sumber
n<-sum(n|1)byte lebih pendek saya percaya. Tetapi kekhasan sampledengan input panjang-satu cukup frustasi di sini.
Giuseppe
golf turun sedikit juga, coba di sini - saya harus menghapus combinatXXpermn dari header untuk mendapatkan tautan yang cukup kecil ...
Giuseppe
Saya memiliki sesuatu yang sangat mirip dengan mengambil input sebagai kerangka data. Masalah dengan bruteforce adalah tidak akan menangani input yang terlalu besar ...
JayCe
@ Jayaye adalah algoritma non-brute force bahkan mungkin, diberikan aturan 3 dari tantangan ini?
ngm
Saya setuju mungkin tidak. Akan lebih menarik tanpa aturan 3.
JayCe
3

JavaScript, 112 byte

Pass pertama di ini, lebih banyak golf untuk (mudah-mudahan) mengikuti.

f=([i,...a],o=[])=>a.sort((x,y)=>(y[1]-x[1])*Math.random()-n*.5,n=--i[1],o.push(i[0]))+a?f(n?[...a,i]:a,o):n?0:o

Cobalah online

Shaggy
sumber
1
Terima kasih, @Arnauld, saya melewatkan itu. Seharusnya sudah dua kali memeriksa spec daripada hanya membabi buta mengikuti jejak Chas. Diimplementasikan perbaikan cepat, harus kembali lagi nanti untuk melihat apakah saya bisa bermain golf lebih baik.
Shaggy
Ya, aturan ke-3 adalah OK untuk esolang yang dengan mudah dapat memaksa semua solusi, tapi itu membuatnya lebih sulit untuk mengimplementasikan algoritma yang lebih pendek dalam bahasa lain ... BTW: sekarang ini tampaknya mengembalikan 0 pada entri yang valid dari waktu ke waktu.
Arnauld
Menerapkan perbaikan cepat lain, @Arnauld - jika itu tidak mengatasinya, saya harus menghapus lagi sampai saya punya lebih banyak waktu untuk memeriksanya. Catatan: Saya telah mengambil spek pada kata-katanya bahwa string berikutnya harus dipilih secara acak, menyiratkan pilihan pertama tidak perlu acak.
Shaggy
1
@Shaggy - Saya setuju, Anda tidak boleh secara membabi buta mengikuti apa pun yang saya lakukan! :)
Chas Brown
3

J, 60 53 byte

-7 Terima kasih kepada FrownyFrog

(?@#{])@(#~*/@(2~:/\])"1)@(]i.@!@#@;A.;) ::0(#~>)/&.>

asli

(?@#{])@(#~2&([:*/~:/\)"1)@(A.~i.@!@#)@;@:(([#~>@])/&.>) ::0

ungolfed

(?@# { ])@(#~ 2&([: */ ~:/\)"1)@(A.~ i.@!@#)@;@:(([ #~ >@])/&.>) ::0

Saran untuk penyambutan selamat datang.

Cobalah online!

Jonah
sumber
Bermain golf ke 53
FrownyFrog
tyvm mengagumkan @FrownyFrog, saya akan memperbarui pos nanti
Jonah
oops, [:*/2~:/\|:dua lebih pendek
FrownyFrog
2

JavaScript (ES6), 160 byte

a=>(g=(a,m=[])=>a.map((v,n)=>v==m[0]||g(a.filter(_=>n--),[v,...m]))>[]?0:r=m)(a.reduce((p,[v,n])=>[...p,...Array(n).fill(v)],r=[]).sort(_=>Math.random()-.5))||r

Cobalah online!

Arnauld
sumber
2

Arang , 38 byte

WΦθ§κ¹«≔‽Φ∨Φι›⊗§κ¹ΣEι§μ¹ι¬⁼κυυ§υ⁰⊞υ⊖⊟υ

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

WΦθ§κ¹«

Ulangi sementara setidaknya ada satu hitungan bukan nol.

Φι›⊗§κ¹ΣEι§μ¹

Temukan hitungan yang membentuk lebih dari setengah sisanya.

∨...ι

Jika tidak ada, maka ambil saja hitungan non-nol yang difilter sebelumnya.

Φ...¬⁼κυ

Memfilter string yang keluar terakhir kali.

≔‽∨...υ

Tetapkan elemen acak dari non-kosong pertama dari dua daftar di atas ke string keluaran terakhir. Perhatikan bahwa jika kombinasi mustahil dimasukkan, program akan macet pada saat ini.

§υ⁰

Cetak string.

⊞υ⊖⊟υ

Kurangi jumlahnya.

Neil
sumber
Ini menghasilkan output yang tidak valid, seperti dalam contoh Anda dengan ["h4x0r", 1337]dimasukkan sebagai string.
ngm
@ ngm Saya telah menata ulang kode dan sekarang macet jika Anda melakukan itu ... sayangnya validasi akan dikenakan biaya lebih banyak byte sayangnya.
Neil
2

Ruby , 85 byte

Pendekatan brute force (terima kasih kepada Jonah atas idenya).

->l{l.flat_map{|a,b|[a]*b}.permutation.select{|p|r=0;p.all?{|a|a!=r&&r=a}}.sample||0}

Cobalah online!

Ruby , 108 100 96 byte

Sebelumnya, pendekatan Bogosort

->l{w=[];l.map{|a,b|w+=[a]*b;b}.max*2>w.size+1?0:(w.shuffle!until(r='';w.all?{|a|a!=r&&r=a});w)}

Cobalah online!

GB
sumber
ini satu untuk 93: Cobalah online!
Jonah
2

Karat 633 byte

Apa yang membuat ini sedikit berbeda dari yang lain adalah bahwa itu dimulai dengan ide untuk mengatur ulang string dengan mensimulasikan sistem fisik. Setiap string pertama kali diduplikasi sesuai jumlah kali. Kemudian setiap string individu diperlakukan sebagai Partikel dalam ruang. Dua partikel dengan nilai string yang sama "saling tolak", sementara dua partikel dengan nilai yang berbeda saling menarik. Sebagai contoh jika kita mulai dengan AAAAAAABBBBCC, As akan saling mencabut, menjauh satu sama lain, memungkinkan B untuk bergerak di antara mereka. Seiring waktu, ini mencapai campuran partikel yang bagus. Setelah setiap iterasi dari 'gerakan partikel', program memeriksa bahwa tidak ada partikel yang sama berbatasan, kemudian berhenti dan mencetak keadaan sistem, yang hanya daftar string dalam urutan, karena mereka muncul dalam ruang 1 dimensi.

Sekarang, ketika benar-benar menerapkan sistem fisik itu, ia mulai menggunakan teknik demo / game PC kuno, untuk menyimpan setiap posisi dan kecepatan partikel sebagai angka, kemudian melalui iterasi untuk memperbarui posisi dan kecepatan. Pada setiap iterasi, kami menambahkan kecepatan ke posisi (gerakan), dan menambahkan akselerasi ke kecepatan (perubahan laju gerakan), dan menghitung akselerasi (menemukan gaya pada partikel). Untuk menyederhanakan, sistem tidak menghitung kekuatan pada setiap partikel berdasarkan pada semua partikel lain - hanya memeriksa partikel yang berdekatan. Ada juga efek 'redaman' sehingga partikel tidak akan berakselerasi terlalu banyak dan terbang hingga tak terbatas (kecepatan berkurang oleh x persentase setiap langkah, misalnya).

Namun, melalui proses bermain golf, semua ini ditebang dan disederhanakan secara drastis. Sekarang, alih-alih dua partikel yang sama saling tolak, mereka hanya 'berteleportasi'. Partikel yang berbeda hanya 'bergeser' sedikit untuk mencegah stagnasi dalam sistem. Sebagai contoh jika A di sebelah A ia akan teleport. Jika A di sebelah B hanya sedikit bergeser. Kemudian memeriksa apakah kondisi terpenuhi (tidak seperti partikel yang berdekatan) dan mencetak string secara berurutan, berdasarkan posisi mereka dalam ruang 1-d. Ini hampir lebih seperti algoritma penyortiran daripada simulasi - sekali lagi, orang bisa melihat algoritma penyortiran sebagai bentuk simulasi 'drifting' berdasarkan 'massa'. Saya ngelantur.

Bagaimanapun, ini adalah salah satu program Rust pertama saya jadi saya menyerah setelah beberapa jam bermain golf, meskipun mungkin masih ada peluang di sana. Agak sulit bagi saya. Bunyinya string input dari input standar. Jika diinginkan, itu bisa diganti dengan "let mut s =" [[A, 3], [B, 2]] ". Tetapi sekarang saya melakukan 'echo [[A, 3], [B, 2]] | kargo berjalan 'di baris perintah.

Perhitungan berhenti sedikit masalah. Bagaimana cara mendeteksi jika keadaan sistem yang valid tidak akan pernah tercapai? Rencana pertama adalah untuk mendeteksi apakah keadaan 'saat ini' pernah mengulangi keadaan lama, misalnya jika ACCC berubah menjadi CACC tetapi kemudian kembali ke ACCC, kita tahu program tidak akan pernah berakhir, karena itu hanya pseudo-acak. Maka harus menyerah dan mencetak 0 jika itu terjadi. Namun ini tampaknya seperti sejumlah besar kode Rust, jadi alih-alih saya hanya memutuskan bahwa jika melewati banyak iterasi, mungkin macet dan tidak akan pernah mencapai kondisi mapan, sehingga mencetak 0 dan berhenti. Berapa banyak? Jumlah partikel kuadrat.

Kode:

extern crate regex;
struct P {s:String,x:i32,v:i32}
fn main() {
    let (mut i,mut j,mut p,mut s)=(0,0,Vec::new(),String::new());
    std::io::stdin().read_line(&mut s);
    for c in regex::Regex::new(r"([A-Z]+),(\d+)").unwrap().captures_iter(&s) {
        for _j in 0..c[2].parse().unwrap() {p.push(P{s:c[1].to_string(),x:i,v:0});i+=1;}
    }
    let l=p.len(); while i>1 {
        j+=1;i=1;p.sort_by_key(|k| k.x);
        for m in 0..l {
            let n=(m+1)%l;
            if p[m].s==p[n].s {p[m].v=p[m].x;if n!=0 {i=2}} else {p[m].v=1}
            p[m].x=(p[m].x+p[m].v)%l as i32;
        }
        if j>l*l{p.truncate(1);p[0].s="0".to_string();i=1}
    }
    for k in &p{print!("{}",k.s)};println!();
}
jangan cerah
sumber
Itu cara berpikir yang menarik tentang masalah ini, saya menyukainya. Seberapa baik praktiknya? Saya merasa seperti itul2batas mungkin terlalu rendah, bahwa mungkin ada terlalu banyak negatif palsu di mana algoritma berpikir tidak ada output yang valid ketika ada - tapi saya tidak bisa menguji teori itu karena TIO tampaknya tidak memiliki regexpeti.
sundar - Reinstate Monica
itu lulus contoh saya memberinya makan, meskipun saya tidak fuzz itu. saya telah memodifikasinya untuk bekerja di TIO, Anda perlu memodifikasi 'let s = [("A", 3), ("B", 2), ("ZZ", 4)];' line, bit.ly/2LubonO
don bright
1

JavaScript (Node.js) , 249 byte

l=>(a=[],g=(r,s)=>s.length?s.forEach((x,i)=>g([...r,x],s.filter((y,j)=>j-i))):a.push(r),g([],l.reduce(((a,x)=>[...a, ...(x[0]+' ').repeat(x[1]).split(' ')]),[]).filter(x=>x)),p=a.filter(a=>a.every((x,i)=>x!=a[i+1])),p[~~(Math.random()*p.length)]||0)

Cobalah online!

WaffleCohn
sumber
1

Java (JDK 10) , 191 byte

S->N->{var l=new java.util.Stack();int i=0,j;for(var s:S)for(j=N[i++];j-->0;)l.add(s);for(;i>0;){i=0;java.util.Collections.shuffle(l);for(var s:S)if(s.join("",l).contains(s+s))i++;}return l;}

Cobalah online!

Ini tidak pernah kembali jika tidak ada solusi.

Olivier Grégoire
sumber