Dilemme du conservateur

9

introduction

Vous êtes l'ami d'un conservateur pour un musée d'art, qui a récemment eu le plaisir d'obtenir de l'art moderne de quatre artistes (dont certains peuvent donner au conservateur zéro œuvres d'art, de jeunes scélérats ). Comme il s'agit d'art moderne, toutes les pièces d'un artiste donné se ressemblent exactement. Votre ami veut utiliser un ordinateur pour décider dans quel ordre placer ces pièces.

Exigences du programme

Votre programme doit prendre cinq entiers (passés à une fonction ou entrés via stdin (ou d'une autre manière)). Les quatre premiers sont le nombre de tableaux fournis par chacun des quatre artistes. La dernière valeur est un indice de permutation i(à partir de 1, pas de 0). Le conservateur souhaite voir la ipermutation par ordre lexicographique des tableaux.

Votre programme doit produire cette permutation dans n'importe quel format raisonnable: par exemple abbccdou [0 1 1 2 2 3]. Le temps d'exécution pour une saisie totalisant moins de dix tableaux doit prendre moins d'une heure (cela ne devrait pas poser de problème, espérons-le).

Vous n'êtes pas autorisé à utiliser des fonctions intégrées pour élaborer des permutations

Exemples

Entrée: 0 1 2 0 2

Étant donné que nous avons un tableau de l'artiste B et deux de l'artiste C (et ils se ressemblent tous), les permutations dans l'ordre lexicographique sont:

['bcc', ' cbc ', 'ccb']

La permutation mise en évidence serait la sortie correcte, car elle est la deuxième dans l'ordre lexicographique.

Entrée: 1 2 0 1 5

['abbd', 'abdb', 'adbb', 'babd', ' badb ', 'bbad', 'bbda', 'bdab', 'bdba', 'dabb', 'dbab', 'dbba']

Essai

Voici quelques tests qui devraient être corrects.

1 2 4 1 5    - ABBDCCCC
2 2 3 1 86   - ABBCACDC
4 1 2 0 24   - AACACBA
1 4 3 2 65   - ABBCBBDCDC

Un court morceau de code en Python3 qui devrait générer aléatoirement des entrées et des sorties est disponible ici (non valide pour l'entrée, il utilise l'importation Python de permutations):

from itertools import permutations
from random import randint
a,b,c,d,n = randint(1,2),randint(1,2),randint(1,3),randint(1,3),randint(1,15)
print(str(a) + " " + str(b) + " " + str(c) + " " + str(d) + " " + str(n) + " - " + str(sorted(set([''.join(p) for p in permutations(a * "a" + b * "b" + c * "c" + d * "d")]))[n-1]))

Tableau d'affichage

Optimizer - CJam       - 39  - Confirmed - Bruteforce
EDC65     - JavaScript - 120 - Confirmed - Bruteforce
Jakube    - Python2    - 175 - Confirmed - Algorithmic
Alexander Craggs
la source
1
Vous dites: "toutes les pièces se ressemblent exactement". Voulez-vous dire "toutes les pièces d'un artiste donné se ressemblent exactement, mais les pièces de différents artistes sont différentes"?
DavidC
Ce ne serait pas une entrée valide, mais je pense que cela pourrait encore être utile pour quelqu'un: {:A.a.{~97+[:I.}:est un J valide et fonctionne, mais utilise A.pour la plupart du travail, il n'est donc pas valide. Si vous pouviez écrire une fonction qui la remplace A.et la remplace dans cette fonction, vous auriez une réponse valide.
ɐɔıʇǝɥʇuʎs
@ ɐɔıʇǝɥʇuʎs - Vous n'avez pas besoin d'utiliser "ABCD", vous pouvez utiliser n'importe quel système de caractères / numérique / symbolique. J'ai peur de ne pas connaître J, et je ne peux donc pas dire le problème exact, mais j'espère que cela aide =)
Alexander Craggs
@PopeyGilbert Eh bien, une version qui ne fait que cracher des chiffres serait {:A.[:I.}:... Le problème est que, mais je ne pense toujours pas que ce A.serait valide: jsoftware.com/help/dictionary/dacapdot.htm
ɐɔıʇǝɥʇuʎs
Que faire si la permutation requise n'existe pas? 1 0 0 0 100?
edc65

Réponses:

5

Python 2: 175 163 caractères

Ce n'est pas une réponse sérieuse au golf. Avec un algorithme différent, j'ai atteint 138 octets. Je voulais juste poster ceci ici, car il n'utilise pas la force brute. La complexité est Theta (#pictures).

f=lambda x:0**x or x*f(x-1)
def g(Q,n):
 while sum(Q):
  for j in 0,1,2,3:
   p=f(sum(Q)-1)*Q[j]
   for k in Q:p/=f(k)
   if p<n:n-=p
   else:print j;Q[j]-=1;break

Usage:

g([1, 4, 3, 2], 65)

Éditer:

Même algorithme, juste du golf: n'importez pas la méthode factorielle et peu de changements dans l'ordre des calculs.

Traduction Pyth: 61 caractères

Lu*GhHUb1WsPQV4J*@QNytsPQFZPQ=J/JyZ)I<JeQ XQ4-eQJ)EN XQNt@QNB

Rien de spécial ici, traduction exacte de mon code python. Bien trop long cependant. Je devais aussi utiliser quelques choses (longues) moches. La 9 première lettre seule est la définition de la factorielle.

Lu*GhHUb1    def y(b): G=1; for H in range(b): G*= H+1; return G

Des trucs comme Q[j]-=1c'est beaucoup trop long: XQNt@QN(1 caractère de plus que Python !!!)

Usage:

Essayez-le ici: Pyth Compiler / Executor . Désactivez le mode de débogage et utilisez-le [2, 2, 3, 1, 86]comme entrée.

Jakube
la source
Ça marche! Félicitations pour avoir proposé la première solution Python! Cependant, j'ai trouvé que dans mon environnement, je dois from math import*sortir de la fonction. Vous ajouter au classement!
Alexander Craggs
Wow ... Votre solution est incroyablement efficace - Pour 32 peintures, cela ne prend que 0,034 seconde o.0.
Alexander Craggs
3

CJam, 50 43 39 octets

q~(])\{W):Wa*}%s:X{Xm*:s_&}X,(*{$X=},$=

Cela peut être beaucoup joué au golf.

Prend l'entrée de STDIN dans le format suivant:

4 1 2 0 24

Sort la peinture. Par exemple pour l'entrée ci-dessus:

0020210

Essayez-le en ligne ici

Notez que le compilateur en ligne abandonne pour les plus grandes tailles de peinture. Vous devrez essayer de plus grandes entrées sur la version Java

Optimiseur
la source
Félicitations d'être le premier solveur! 50 octets est certainement une valeur difficile à battre. Je vous ajouterai en haut du classement!
Alexander Craggs
@PopeyGilbert, vous devez au moins attendre environ 1 semaine avant d'accepter une réponse
Optimizer
Ah, d'accord, je suis vraiment désolé! Dans mon défi précédent, je viens de changer la réponse acceptée lorsque quelqu'un a été battu. Ma faute.
Alexander Craggs
1
@PopeyGilbert C'est très noble de votre part (et j'aimerais que tous les auteurs de challenger le fassent), et en principe, il n'y a rien de mal à accepter tôt si vous le faites, mais certaines personnes semblent offensées si un défi ici accepte une réponse plus tôt (parce que, je devinez, personne ne s'attend à ce que l'auteur modifie la réponse acceptée).
Martin Ender
Je pense personnellement qu'il devrait y avoir au moins 2 réponses parmi lesquelles choisir avant d'accepter, même si c'est fait tôt. Bien sûr, s'il n'y a qu'une seule réponse jusqu'à environ une semaine, acceptez-la.
Optimizer
3

JavaScript (ES6) 120 138 147

En fonction des cinq paramètres requis, sortie via console.
Utilisation de symboles 0,1,2,3. Je calcule le total des symboles, puis je crée et vérifie chaque numéro de base 4 ayant le nombre de chiffres requis. Les numéros avec le mauvais numéro de n'importe quel chiffre sont rejetés.
Remarque: avec JavaScript 32 bits, cela fonctionne pour jusqu'à 15 peintures.

Modifier plus court (éviter .toString) et beaucoup plus rapide (condition de sortie modifiée). Temps pour chaque test en dessous de 1 sec.

Edit2 aucun changement d'algorithme, plus de golf (indentation ajoutée pour plus de lisibilité)

F=(w,x,y,z,n)=>{
  for(a=0;n;n-=l=='0,0,0,0')
    for(l=[w,x,y,z],t=w+x+y+z,v='',b=a++;t--;b/=4)--l[d=b&3],v=d+v;
  console.log(v)
}

Non golfé et aucun FireFox requis

F=function(w,x,y,z,n) {
  for(a=0; n; a++) // exit when solution found (if wrong parameters, run forever)
  {
    l=[w,x,y,z]; // required number of each symbol
    t=w+x+y+z; // total of digits
    v=''; // init output string
    for(b=a;
      t--; // digit count down
      b >>= 2) // shift for next digit
    {
        d = b & 3; //get digit
        --l[d]; // decrement for the current digit
        v = d + v; // add to output string         
    }
    l[0]|l[1]|l[2]|l[3] // if digits ok
    ||--n // decrement counter
  }
  console.log(v) // when found, exit for and print the answer
}

Test dans la console FireBug / FireFox

F(1, 2, 4, 1, 5) 
F(2, 2, 3, 1, 86)
F(4, 1, 2, 0, 24)
F(1, 4, 3, 2, 65)

Production

01132222
01120232
0020210
0112113232
edc65
la source
salut! Ayant un peu de mal à l'exécuter. Je télécharge FireFox pour voir si cela peut aider. Je t'ajouterai au classement!
Alexander Craggs
J'ai trouvé un joli tableau ici - je suppose que Firefox est nécessaire. Testé et ça marche! Changement du classement en confirmé.
Alexander Craggs
Classement mais pas de vote positif ... vous n'aimez vraiment pas ça! :(
edc65
Ah! Je suis vraiment désolé = (Il a été voté maintenant =)
Alexander Craggs
Je me demande combien de temps cet algorithme sera dans CJam. Mais pour l'instant, je n'ai aucune idée de comment cela fonctionne: P
Optimizer
2

Pyth , 20

@fqPQm/TdU4^U4sPQteQ

Essayez-le ici.

L'entrée est sous forme de liste Python, par exemple [1, 2, 4, 1, 5]

La sortie est également sous forme de liste Python, par exemple [0, 1, 1, 3, 2, 2, 2, 2]pour l'entrée ci-dessus.

La solution est la force brute et prend environ 10 secondes, le pire des cas, sur ma machine.

Comment ça fonctionne:

@fqPQm/TdU4^U4sPQteQ
           ^U4sPQ         All permutations of [0, 1, 2, 3] with length equal to the number
                          of paintings.
     m/TdU4               Find the count (/) of paintings by painter in the input list.
 fqPQ                     Filter the permutations on the counts being the desired counts
                          in the input.
                          This gives all possible orderings of the paintings.
@                teQ      Index into this list at the given location - 1. (0-indexing)
isaacg
la source