Розфарбуй мене поляком


22

Скажімо, ваша робота - фарбувати стовпи, а клієнт просить вас пофарбувати полюс з 4 червоними секціями та 3 жовтими секціями. Ви можете зробити це досить легко так:

r y r y r y r

З просто жовтими та червоними смужками. Тепер скажемо, що ваш клієнт просить вас намалювати полюс з 2 червоними секціями, 2 жовтими секціями та 1 зеленою секцією . Є кілька способів, як ви могли намалювати свій жердину

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

Точніше, це 12 способів пофарбувати полюс. Це вибухує більше кольорів та секцій, які задіяні

Тепер, якщо ваш клієнт каже, що вони хочуть 3 червоних секції та 1 жовту секцію, немає ніякого способу намалювати такий жерлик. Тому що, як би ви не намагалися впорядкувати секції, два червоні секції будуть торкатися, і коли два червоних секції торкаються, вони стають єдиним червоним.

І це майже наше одне правило для фарбування стовпів

Суміжні секції можуть бути не одного кольору

Завдання

Враховуючи список необхідних кольорів та ділянок, виведіть кількість можливих способів пофарбувати стовп, як вимагається. Ви можете представляти кольори будь-яким розумним способом (цілі числа, символи, рядки), але вам ніколи не буде надано більше 255 різних кольорів одночасно. Якщо ви хочете, ви навіть можете вибрати, щоб кольорам не було призначено імен, а просто взяти список підрахунків розділів, якщо це простіше.

Випробування

Це досить важко обчислити вручну, тим більше, що вони збільшуються. Якщо у когось є запропонований тестовий випадок, я додам його.

[4,3]    -> 1
[2,2,1]  -> 12
[3,1]    -> 0
[8,3,2]  -> 0
[2,2,1,1]-> 84

Чи можемо ми сприйняти введення як, наприклад, "rrrryyy" для [4,3]?
Лев

@Leo Звичайно, це цілком розумно.
Пшеничний майстер

Чи можу я отримати вхід як [1, 1, 1, 1, 2, 2, 2]? Я теж так думаю.
Ерік Аутгольфер


4
Не надто важливо, але великі літери слова «Поляк» звучать так, ніби ви говорите про людину з Польщі.
NH.

Відповіді:


9

Математика, 37 44 48 60 62 байт

Візьміть введення як список цілих чисел {1, 1, 1, 2, 2}. Спробуйте це на Wolfram Sandbox .

Метод відповідності шаблонів, дякую @Не дерево!

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

Splitрозбиває єдиний список на підсписи послідовних елементів, наприклад, {1, 1, 2, 3, 4, 4}на{{1, 1}, {2}, {3}, {4, 4}}

{{_}..}це, в зокрема, {{_}, {_}, {_}, ...}. Шаблон відповідає списку одинарних списків.

Differences метод, 48 байт:

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

Код використовується Differencesдля визначення того, чи однакові суміжні елементи.

Крок за кроком:

  1. Permutations@# створює всі перестановки вхідного списку до списку N! * N.
  2. Differences/@ обчислює різницю між N елементами і отримує список N! * (N-1).
  3. 1##&@@@обчислює множення всіх списків. Якщо список містить 0(два суміжні елементи однакові), результат буде 0, інакше не нульовим, до N! список.
  4. Clip[]такі дії, як Sign[], перетворіть список із (-inf, inf) у [-1, 1]
  5. Tr@Absперетворює все -1на 1тепер і список N! -length містить лише 0(недійсні) та 1(дійсні). Тому ми просто підсумовуємо список.

4
Ви можете зберегти 4 байта з деяким зіставленням з зразком: Permutations@#~Count~Except@{___,x_,x_,___}&.
Не дерево

2
I have another one: Count[Split/@Permutations@#,{{_}..}]&, 37 bytes!
Not a tree

7

Jelly, 7 bytes

Œ!QIẠ€S

Try it online!

Takes input as e.g. [1,1,1,1,2,2,2] for [4,3]. The [8,3,2] testcase takes too long to run on TIO.

How it Works

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

You abused grace period...;)
Erik the Outgolfer

Does Œ!QIẠ€S work? Try it online!
nmjcman101

@nmjcman101 That appears to work. Nice find! I preferred the P over the any and all atom for its simplicity.
fireflame241

@fireflame241 Technically that's not the any-and-all atom, it's the all atom.
Erik the Outgolfer

BTW P€ instead of Ạ€ would still work.
Erik the Outgolfer


5

Mathematica, 50 bytes

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

Try it in Mathics, or at the Wolfram sandbox!

Takes input like in the test cases — e.g. {4,3} means "4 red stripes, 3 yellow stripes".

This is a naïve implementation of a formula I found here. "Naïve" means "I have no idea how the maths works so please don't ask me for an explanation…"


1
Can we have an explanation of the maths given in this answer?
TheLethalCoder

@TheLethalCoder Seconded, can someone please explain the maths to me?
Not a tree


3

Ruby 2.4, 47 bytes

Input is a list of characters: For the test case [4,3], input can be %w[a a a a b b b], "1111222".chars, or some other array formatting method that's valid in Ruby.

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

Requires 2.4 for Enumerator#uniq (earlier versions only had it available on the Array class). As such, the TIO link adds 5 bytes to convert the permutation enumerator to an array first via to_a, since it does not have the above function.

Try it online!


3

R, 72 bytes

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

Creates the function

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

Takes input in the form [1,1,1,1,2,2,2] as per Erik the Outgolfer's comment. Uses combinat's permn function to create a list of all permutations, and then unique to get all distinct entries. sapply then applies the following function on all entries:

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

Which evaluates to

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

Note that this x is not the same as the x in the big function's input. Using another character in this function would fool pryr::f into believing the big function needs another argument.

Anyways, when given a permutation, this function takes the difference between the vector: 2 1 3 4 2 1 -> -1 2 1 -2 -1. ! converts nonzero's into FALSE and zeros into TRUE, so the vector becomes FALSE FALSE FALSE FALSE FALSE. Summing that to check if there are any TRUEs (TRUE would imply diff=0 --> two the same consecutive numbers). We can again invert this with ! to get a boolean on whether or not there are consecutive values in the permutation.

Summing over these booleans gives us the total number of permutations where this is not the case.

Doesn't work for the [8,3,2] testcase because it requires a vector of 46GB to store those permutations.




2

Husk, 8 bytes

#ȯ¬ṁtguP

Try it online! Takes input in the format "aaabb" for [3,2]. Times out on the longest test case.

Explanation

Nothing fancy here, just counting the unique permutations where all groups of adjacent elements have length 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.

2

Ruby, 84 76 bytes

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}

A recursive lambda function. Looks at each possible color and dose a recursive tree search, counting the number of times it uses all stripes.

Explanation (for old version):

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 
}

x=p as the initial condition? p acts as an alias of nil in this case and should satisfy the check it's being used for.
Value Ink

1

MATL, 11 8 bytes

Y@Xu!dAs

Input format is [1 1 1 1 2 2 2] for [4 3], etc.

Runs out of memory for the last test case.

Try it online!

Explanation

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.