Colore-moi un pôle

22

Disons que votre travail consiste à peindre des poteaux, et un client vous demande de peindre un poteau avec 4 sections rouges et 3 sections jaunes. Vous pouvez le faire assez facilement comme suit:

r y r y r y r

Avec juste des rayures jaunes et rouges. Supposons maintenant que votre client vous demande de peindre un poteau avec 2 sections rouges, 2 sections jaunes et 1 section verte . Il y a deux façons de peindre votre poteau

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

Plus précisément, c'est 12 façons de peindre le poteau. Cela fait exploser le plus de couleurs et de sections impliquées

Maintenant, si votre client dit qu'il veut 3 sections rouges et 1 section jaune, il n'y a aucun moyen de peindre un poteau comme ça. Parce que peu importe comment vous essayez d'organiser les sections, deux sections rouges se toucheront et lorsque deux sections rouges se toucheront, elles deviendront une seule section rouge.

Et c'est à peu près notre seule règle pour peindre les poteaux

Les sections adjacentes peuvent ne pas être de la même couleur

Tâche

Étant donné une liste de couleurs et de sections requises, affichez le nombre de façons possibles de peindre un poteau comme demandé. Vous pouvez représenter les couleurs de toute manière raisonnable (entiers, caractères, chaînes), mais vous ne recevrez jamais plus de 255 couleurs différentes à la fois. Si vous le souhaitez, vous pouvez même choisir de ne pas attribuer de noms aux couleurs et simplement prendre une liste des sections si cela est plus facile.

Cas de test

Celles-ci sont assez difficiles à calculer à la main, d'autant plus qu'elles grossissent. Si quelqu'un a un cas de test suggéré, je l'ajouterai.

[4,3]    -> 1
[2,2,1]  -> 12
[3,1]    -> 0
[8,3,2]  -> 0
[2,2,1,1]-> 84
Assistant de blé
la source
Pouvons-nous prendre l'entrée comme, par exemple, "rrrryyy" pour [4,3]?
Leo
@Leo Bien sûr, c'est tout à fait raisonnable.
Wheat Wizard
Puis-je obtenir une entrée en tant que [1, 1, 1, 1, 2, 2, 2]? Je suppose.
Erik the Outgolfer
4
Pas super important, mais mettre le mot Pole en majuscule donne l'impression que vous parlez d'une personne originaire de Pologne.
NH.

Réponses:

9

Mathematica, 37 44 48 60 62 octets

Prenez l'entrée comme une liste d'entiers {1, 1, 1, 2, 2}. Essayez-le sur Wolfram Sandbox .

Méthode de correspondance de motifs, merci @Not a tree!

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

Splitdivise une seule liste en sous-listes d'éléments consécutifs, par exemple {1, 1, 2, 3, 4, 4}en{{1, 1}, {2}, {3}, {4, 4}}

{{_}..}est, à savoir {{_}, {_}, {_}, ...}. Le motif correspond à une liste de sous-listes unaires.

Differences méthode, 48 octets:

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

Le code utilise Differencespour déterminer si les éléments adjacents sont identiques.

Pas à pas:

  1. Permutations@# génère toutes les permutations de la liste d'entrée vers une liste N! * N.
  2. Differences/@ calcule la différence entre N éléments et donne une liste N! * (N-1).
  3. 1##&@@@calcule la multiplication de toutes les listes. Si une liste contient 0(deux éléments adjacents sont les mêmes), le résultat sera 0, sinon différent de zéro, en N! liste.
  4. Clip[]agit comme Sign[], transformer la liste de (-inf, inf) en [-1, 1]
  5. Tr@Abstransforme tout -1en 1et maintenant la liste de longueur N! contient seulement 0(invalide) et 1(valide). Nous résumons donc simplement la liste.
Keyu Gan
la source
4
Vous pouvez enregistrer 4 octets avec une correspondance de motif: Permutations@#~Count~Except@{___,x_,x_,___}&.
Pas un arbre
2
J'en ai un autre: Count[Split/@Permutations@#,{{_}..}]&37 octets!
Pas un arbre le
7

Gelée , 7 octets

Œ!QIẠ€S

Essayez-le en ligne!

Prend l'entrée comme par exemple [1,1,1,1,2,2,2]pour [4,3]. Le [8,3,2]testcase prend trop de temps pour fonctionner sur TIO.

Comment ça marche

Œ!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
la source
Vous avez abusé de la période de grâce ...;)
Erik the Outgolfer
Ça Œ!QIẠ€Smarche? Essayez-le en ligne!
nmjcman101
@ nmjcman101 Cela semble fonctionner. Belle trouvaille! J'ai préféré l' Patome à tout atome pour sa simplicité.
fireflame241
@ fireflame241 Techniquement, ce n'est pas l'atome universel, c'est tout l'atome.
Erik the Outgolfer
BTW P€au lieu de Ạ€fonctionnerait toujours.
Erik the Outgolfer
5

Mathematica, 50 octets

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

Essayez-le en mathématiques ou au bac à sable Wolfram !

Prend la saisie comme dans les cas de test - par exemple {4,3}signifie "4 bandes rouges, 3 bandes jaunes".

Il s'agit d'une mise en œuvre naïve d'une formule que j'ai trouvée ici . "Naïve" signifie "Je n'ai aucune idée du fonctionnement des mathématiques, alors ne me demandez pas d'explication ..."

Pas un arbre
la source
1
Pouvons-nous avoir une explication des mathématiques données dans cette réponse?
TheLethalCoder
@TheLethalCoder Appuyé, quelqu'un peut-il m'expliquer les mathématiques?
Pas un arbre le
3

Ruby 2.4, 47 octets

L' entrée est une liste de caractères: Pour le cas de test [4,3], l' entrée peut être %w[a a a a b b b], "1111222".charsou une autre méthode mise en forme de tableau qui est valable dans Ruby.

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

Nécessite 2.4 pour Enumerator#uniq(les versions antérieures ne le proposaient que sur la Arrayclasse). En tant que tel, le lien TIO ajoute 5 octets pour convertir d'abord l'énumérateur de permutation en un tableau to_a, car il n'a pas la fonction ci-dessus.

Essayez-le en ligne!

Encre de valeur
la source
3

R, 72 octets

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

Crée la fonction

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

Prend entrée dans le formulaire [1,1,1,1,2,2,2]selon le commentaire d'Erik le Outgolfer. Utilise combinatla permnfonction pour créer une liste de toutes les permutations, puis uniquepour obtenir toutes les entrées distinctes. sapplyapplique ensuite la fonction suivante à toutes les entrées:

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

Qui évalue à

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

Notez que ce xn'est pas la même chose que xdans l'entrée de la grande fonction. Utiliser un autre caractère dans cette fonction serait dupe de pryr::fcroire que la grande fonction a besoin d'un autre argument.

Quoi qu'il en soit, quand donné une permutation, cette fonction prend la différence entre le vecteur: 2 1 3 4 2 1 -> -1 2 1 -2 -1. !convertit des FALSEzéros et des zéros en TRUE, de sorte que le vecteur devient FALSE FALSE FALSE FALSE FALSE. En sommant cela pour vérifier s'il y a des TRUEs ( TRUEcela impliquerait diff=0-> deux les mêmes nombres consécutifs). Nous pouvons à nouveau inverser ceci avec !pour obtenir un booléen sur la présence ou non de valeurs consécutives dans la permutation.

La somme de ces booléens nous donne le nombre total de permutations où ce n'est pas le cas.

Ne fonctionne pas pour le [8,3,2]testcase car il nécessite un vecteur de 46 Go pour stocker ces permutations.

JAD
la source
2

Python 2 , 140 89 octets

Le format d'entrée est 'aaaabbb'pour le cas de test [4,3].

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

Essayez-le en ligne!

Felipe Nardi Batista
la source
2

Husk , 8 octets

#ȯ¬ṁtguP

Essayez-le en ligne! Prend l'entrée au format "aaabb"pour [3,2]. Expire le plus long cas de test.

Explication

Rien d'extraordinaire ici, juste compter les permutations uniques où tous les groupes d'éléments adjacents ont une longueur 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
la source
2

Rubis, 84 76 octets

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}

Une fonction lambda récursive. Examine chaque couleur possible et dose une recherche d'arborescence récursive, en comptant le nombre de fois où elle utilise toutes les rayures.

Explication (pour l'ancienne 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 
}
MegaTom
la source
x=pcomme condition initiale? pagit comme un alias nildans ce cas et doit satisfaire la vérification pour laquelle il est utilisé.
Value Ink
1

MATL , 11 8 octets

Y@Xu!dAs

Le format d'entrée est [1 1 1 1 2 2 2]pour [4 3], etc.

Manque de mémoire pour le dernier cas de test.

Essayez-le en ligne!

Explication

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
la source