Warnai saya tiang

22

Katakanlah tugas Anda adalah melukis tiang, dan klien meminta Anda melukis tiang dengan 4 bagian merah dan 3 bagian kuning. Anda dapat melakukannya dengan mudah sebagai berikut:

r y r y r y r

Hanya dengan garis-garis kuning dan merah. Sekarang katakanlah klien Anda meminta Anda untuk melukis sebuah tiang dengan 2 bagian merah, 2 bagian kuning, dan 1 bagian hijau . Ada beberapa cara Anda bisa mengecat tiang Anda

g y r y r
y g r y r
y r g y r
y r y g r
y r y r g
g r y r y
r g y r y
r y g r y
r y r g y
r y r y g
y r g r y
r y g y r

Lebih tepatnya itulah 12 cara untuk melukis tiang. Ini memunculkan lebih banyak warna dan bagian yang terlibat

Sekarang jika klien Anda mengatakan mereka ingin 3 bagian merah dan 1 bagian kuning tidak ada cara untuk melukis tiang seperti itu. Karena tidak peduli bagaimana Anda mencoba mengatur bagian dua bagian merah akan menyentuh, dan ketika dua bagian merah menyentuh mereka menjadi bagian merah tunggal.

Dan itu adalah aturan kami untuk mengecat tiang

Bagian yang berdekatan mungkin tidak memiliki warna yang sama

Tugas

Diberi daftar warna dan bagian yang diperlukan, output jumlah cara yang mungkin untuk melukis tiang seperti yang diminta. Anda dapat mewakili warna dengan cara yang masuk akal (bilangan bulat, karakter, string), tetapi Anda tidak akan pernah diberikan lebih dari 255 warna berbeda sekaligus. Jika mau, Anda bahkan dapat memilih untuk tidak memiliki warna yang ditetapkan nama dan hanya mengambil daftar jumlah bagian jika itu lebih mudah.

Uji Kasus

Ini agak sulit untuk dihitung dengan tangan, terutama karena semakin besar. Jika ada yang memiliki test case yang disarankan, saya akan menambahkannya.

[4,3]    -> 1
[2,2,1]  -> 12
[3,1]    -> 0
[8,3,2]  -> 0
[2,2,1,1]-> 84
Wisaya Gandum
sumber
Bolehkah kita mengambil input sebagai, misalnya, "rrrryyy" untuk [4,3]?
Leo
@ Leo Yakin itu sangat masuk akal.
Wheat Wizard
Bisakah saya mendapatkan input [1, 1, 1, 1, 2, 2, 2]? Saya rasa begitu.
Erik the Outgolfer
4
Bukan super penting, tetapi menggunakan huruf besar untuk kata Pole membuatnya terdengar seperti Anda berbicara tentang seseorang dari Polandia.
NH.

Jawaban:

9

Mathematica, 37 44 48 60 62 byte

Ambil input sebagai daftar bilangan bulat {1, 1, 1, 2, 2}. Cobalah di Wolfram Sandbox .

Metode pencocokan pola, terima kasih @Tidak pohon!

Count[Split/@Permutations@#,{{_}..}]&

Splitmembagi satu daftar menjadi sub daftar elemen yang berurutan, misalnya {1, 1, 2, 3, 4, 4}menjadi{{1, 1}, {2}, {3}, {4, 4}}

{{_}..}adalah, yaitu {{_}, {_}, {_}, ...},. Pola ini cocok dengan daftar sub daftar yang tidak disadari.

Differences metode, 48 byte:

Tr@Abs@Clip[1##&@@@Differences/@Permutations@#]&

Kode digunakan Differencesuntuk menentukan apakah elemen yang berdekatan adalah sama.

Selangkah demi selangkah:

  1. Permutations@# menghasilkan semua permutasi dari daftar input ke daftar N! * N.
  2. Differences/@ menghitung perbedaan antara elemen N, dan menghasilkan daftar N! * (N-1).
  3. 1##&@@@menghitung penggandaan semua daftar. Jika daftar berisi 0(dua elemen yang berdekatan adalah sama), hasilnya akan 0, jika tidak nol, ke N! daftar.
  4. Clip[]bertindak seperti Sign[], mentransformasikan daftar dari (-inf, inf) ke [-1, 1]
  5. Tr@Absmengubah semua -1menjadi 1dan sekarang daftar panjang N hanya berisi 0(tidak valid) dan 1(valid). Jadi kami hanya menjumlahkan daftarnya.
Keyu Gan
sumber
4
Anda dapat menyimpan 4 byte dengan beberapa pencocokan pola: Permutations@#~Count~Except@{___,x_,x_,___}&.
Bukan sebatang pohon
2
Saya punya satu lagi Count[Split/@Permutations@#,{{_}..}]&:, 37 byte!
Bukan pohon
7

Jelly , 7 byte

Œ!QIẠ€S

Cobalah online!

Mengambil input sebagai contoh [1,1,1,1,2,2,2]untuk [4,3]. The [8,3,2]testcase waktu terlalu lama untuk berjalan di TIO.

Bagaimana itu bekerja

Œ!QIẠ€S - main link, input as a list
Œ!      - all permutations
  Q     - remove duplicates
   I    - take increments (returns a 0 for two adjacent identical numbers)
    Ạ€  - apply “all” atom to each: 0 for containing 0 and 1 otherwise
      S - sum
fireflame241
sumber
Anda menyalahgunakan masa tenggang ...;)
Erik the Outgolfer
Apakah Œ!QIẠ€Sbekerja? Cobalah online!
nmjcman101
@ nmjcman101 Tampaknya berhasil. Temuan yang bagus! Saya lebih suka Patom apa saja daripada semua karena kesederhanaannya.
fireflame241
@ fireflame241 Secara teknis itu bukan atom apa saja, itu semua atom.
Erik the Outgolfer
BTW P€bukannya Ạ€tetap bekerja.
Erik the Outgolfer
5

Mathematica, 50 byte

Expand[1##&@@(LaguerreL[#,-1,x](-1)^#)]/._^i_:>i!&

Cobalah dalam Matematika , atau di kotak pasir Wolfram !

Mengambil input seperti pada kasus uji - mis. {4,3}Berarti "4 garis merah, 3 garis kuning".

Ini adalah implementasi naif dari formula yang saya temukan di sini . "Naïve" berarti "Aku tidak tahu bagaimana matematika bekerja jadi tolong jangan tanya saya untuk penjelasan ..."

Bukan pohon
sumber
1
Bisakah kita memiliki penjelasan tentang matematika yang diberikan dalam jawaban ini?
TheLethalCoder
@TheLethalCoder Disokong, dapatkah seseorang menjelaskan matematika kepada saya?
Bukan sebatang pohon
3

Ruby 2.4, 47 byte

Input adalah daftar karakter: Untuk kasus uji [4,3], masukan bisa %w[a a a a b b b], "1111222".chars, atau berbagai format metode lain yang berlaku di Ruby.

->x{x.permutation.uniq.count{|a|a*''!~/(.)\1/}}

Membutuhkan 2,4 untuk Enumerator#uniq(versi sebelumnya hanya tersedia di Arraykelas). Dengan demikian, tautan TIO menambahkan 5 byte untuk mengkonversi enumerator permutasi menjadi array terlebih dahulu to_a, karena tidak memiliki fungsi di atas.

Cobalah online!

Nilai Tinta
sumber
3

R, 72 byte

pryr::f(sum(sapply(unique(combinat::permn(x)),pryr::f(!sum(!diff(x))))))

Menciptakan fungsi

function (x) 
{
    sum(sapply(unique(combinat::permn(x)), pryr::f(!sum(!diff(x)))))
}

Mengambil input dalam formulir [1,1,1,1,2,2,2]sesuai komentar Erik the Outgolfer. Penggunaan combinat's permnfungsi untuk membuat daftar semua permutasi, dan kemudian uniqueuntuk mendapatkan semua entri yang berbeda. sapplykemudian menerapkan fungsi berikut pada semua entri:

pryr::f(!sum(!diff(x)))

Yang dievaluasi menjadi

function (x) 
!sum(!diff(x))

Perhatikan bahwa ini xtidak sama dengan xinput dalam fungsi besar. Menggunakan karakter lain dalam fungsi ini akan membodohi pryr::fpercaya bahwa fungsi besar membutuhkan argumen lain.

Anyways, ketika diberi permutasi, fungsi ini mengambil perbedaan antara vektor: 2 1 3 4 2 1 -> -1 2 1 -2 -1. !mengubah bukan nol menjadi FALSEdan nol menjadi TRUE, sehingga vektor menjadi FALSE FALSE FALSE FALSE FALSE. Menjumlahkan itu untuk memeriksa apakah ada TRUEs ( TRUEakan menyiratkan diff=0-> dua angka berurutan yang sama). Kita dapat kembali membalikkan ini dengan !untuk mendapatkan boolean pada apakah ada nilai berturut-turut dalam permutasi.

Penjumlahan dari boolean ini memberi kita jumlah total permutasi di mana ini bukan masalahnya.

Tidak berfungsi untuk [8,3,2]testcase karena membutuhkan vektor 46GB untuk menyimpan permutasi tersebut.

JAD
sumber
2

Jelly , 11 byte

Œ!Q⁻2\Ạ$ÐfL

Cobalah online!

Erik the Outgolfer
sumber
2

Python 2 , 140 89 byte

Format input 'aaaabbb'untuk test case [4,3].

lambda s:len({p for p in permutations(s)if all(map(cmp,p,p[1:]))})
from itertools import*

Cobalah online!

Felipe Nardi Batista
sumber
2

Sekam , 8 byte

#ȯ¬ṁtguP

Cobalah online! Mengambil input dalam format "aaabb"untuk [3,2]. Waktu habis pada test case terpanjang.

Penjelasan

Tidak ada yang mewah di sini, hanya menghitung permutasi unik di mana semua kelompok elemen yang berdekatan memiliki panjang 1.

#ȯ¬ṁtguP
       P  Permutations.
      u   Remove duplicates.
#ȯ        Count how many satisfy the following condition:
     g    group adjacent elements,
   ṁt     concatenate tails of groups
  ¬       and negate.
Zgarb
sumber
2

Ruby, 84 76 byte

f=->a,x=p{i=s=0;a.map{a[i-=1]-=1;a[i]<0||i!=x&&s+=f[a,i];a[i]+=1}.max>0?s:1}

Fungsi lambda rekursif. Lihatlah setiap kemungkinan warna dan dosis pencarian pohon rekursif, menghitung berapa kali menggunakan semua garis.

Penjelasan (untuk versi lama):

f=->
  a, # a is the input array in [3,3,4] form
  x = -1 # x is the last color placed (-1 when run normaly, used in recursive calls)
{
  j = i = s = 0;
  # i is the index
  # s is the sum of valid final patterns (the answer)
  # j is used to count the total stripes

  a.map{|e| # Iterate over array of colors

    a[i] -= 1; # remove a stripe of current color (the array will be used in recursive call)

    s += f[a,i] if i!=x && e>0;
      # add to sum recursively if:
        # we are not using the same color as the last color AND
        # we have stripes of the current color left to paint

    a[i] += 1; # replace the stripe we removed above 

    j += a[i]; # add stripes to j

    i+=1 # increment the index

  }; # End loop

  j == 0 ? 1 : s
  # if we had stripes, give the recursive sum, otherwise return 1 
}
MegaTom
sumber
x=psebagai kondisi awal? pbertindak sebagai alias nildalam kasus ini dan harus memenuhi cek yang digunakannya.
Nilai Tinta
1

MATL , 11 8 byte

Y@Xu!dAs

Format input [1 1 1 1 2 2 2]untuk [4 3], dll.

Kehabisan memori untuk test case terakhir.

Cobalah online!

Penjelasan

Y@    % Implicit input. Matrix of all permutations. Each row is a permutation
Xu    % Unique rows
!     % Transpose
d     % Consecutive differences along each column
A     % All: true for columns such that all its entries are nonzero
s     % Sum. Implicitly display
Luis Mendo
sumber