Un jeu de serrures et de clés

12

Il y a n cases, numérotées de 1 à n . Chaque boîte est verrouillée, de sorte qu'elle peut être ouverte par un seul type de clé correspondant (également numéroté 1-n ). Ces clés sont dispersées au hasard dans les boîtes (une boîte peut avoir n'importe quel nombre de clés, une clé peut avoir un nombre quelconque de doublons), puis toutes les boîtes sont fermées. Un trésor (numéroté 0 ) a également été enfermé dans de nombreuses boîtes.

Vous avez engagé un serrurier pour récupérer tous les trésors. Il facture pour chaque boîte qu'il ouvre. L'ouverture d'une boîte pour laquelle la clé est déjà disponible est gratuite.

L'entrée est le contenu de chaque boîte. Vous pouvez décider du format de l'entrée.

Produisez le coût minimum requis pour obtenir les trésors.

Remarques

  1. Votre algorithme peut prendre beaucoup de temps, mais ce n'est pas pertinent.
  2. Le code le plus court gagne.
  3. Pas besoin de s'inquiéter d'une entrée invalide.

Exemples de données

Ici, la ligne i représente les clés présentes dans la case i .

Contribution

2 0
3
4 0
5 6 0
6
0

Production

1

Contribution

2 0
3 0

4 0
6
5 0

Production

3

Contribution

2 4 0
3 0

1 0
6
5 0

Production

2

Contribution

1
3 4


2 6
5

Production

0
ghosts_in_the_code
la source
2
Est-ce peut-être lié à cela ?
Addison Crump
Toujours en rapport avec : puzzling.stackexchange.com/questions/23150/...
Leif Willerts
@VoteToClose Belle vidéo. Il est similaire, sauf qu'il parle d'un puzzle mathématique et d'un algorithme spécifique, plutôt que d'un algorithme généralisé.
ghosts_in_the_code
1
Cela semble lié à ce casse - tête sur les 100 boîtes verrouillées de bois et d' acier: puzzling.stackexchange.com/q/17852/4551
XNOR
4
@ghosts_in_the_code Il ne s'agit pas de simplicité mais de flexibilité. Généralement, les défis qui nécessitent une entrée structurée permettent tout format de liste pratique, tant que les données ne sont pas prétraitées. Selon la langue, cela pourrait signifier un fichier séparé par des espaces comme vous, ou cela pourrait signifier [[1] [3 4] [] [] [2 6] [5]]ou peut-être {{1},{3,4},{},{},{2,6},{5}}. De cette façon, la plupart des langues peuvent réduire la lecture de l'entrée à quelque chose d'aussi trivial i=eval(read())et se concentrer sur la partie amusante du défi.
Martin Ender

Réponses:

6

CJam, 59 52 50 49 45 43 42 octets

qN/ee::~e!{_0+{0a&}#>W%_{1$|(z@-},,\;}%:e<

Merci à @ MartinBüttner pour avoir joué au golf sur 3 octets et ouvert la voie à 4 autres!

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça fonctionne

qN/      e# Read all input and split it at linefeeds.
ee       e# Enumerate the lines.
         e# STACK: [[0 "i0 i1 ..."] [1 "j0 j1 ..."] ...]
::~      e# Apply ~ (bitwise NOT/evaluate) to each item of the pairs.
         e# STACK: [[-1 i0 i1 ...] [-2 j0 j1 ...] ...]
e!       e# Push all unique permutations of the resulting array.
{        e# For each permutation:
  _0+    e#   Push a copy and append 0 to it.
  {0a&}# e#   Find the first index of an element that contains 0.
  >      e#   Discard all previous elements of the array.
  W%     e#   Reverse the resulting array.
         e#   We now have a (partial) permutation that contains
         e#   all treasures and ends with a treasure.
  _      e#   Push a copy. The original (which contains lists, but no 
              numbers) will serve as accumulator.
  {      e#   Filter; for each list in the array:
    1$|  e#     Push a copy of the accumulator and perform set union.
    (    e#     Shift out the first element (bitwise NOT of 0-based index).
    z    e#     Apply absolute value to push the 1-based index.
    @-   e#     Perform set difference with the former state of the 
         e#     accumulator. This pushes an empty list iff the 1-based
         e#     index was already in the accumulator, i.e., iff we already
         e#     had a key.
  },     e#   Keep the element if we did not have the key.
  ,      e#   Count the kept elements.
  \;     e#   Discard the accumulator from the stack.
}%       e#
:e<      e# Get the minimum of all results.
Dennis
la source
2
Pourriez-vous ajouter une explication pour nous sans le don de la compréhension de CJam? : D Je voudrais savoir comment cela fonctionne.
Addison Crump
2
@VoteToClose Regardez ce CJAM101
user41805
array long &travaux, de sorte que vous pouvez supprimer le ade 0a&. Malheureusement, cela rend un peu plus difficile de vous attraper.
Peter Taylor
@PeterTaylor Malheureusement, si je remplace 0a&par 0&, je dois aussi remplacer 0+par 0aa+, car 0 0&c'est de la falsification.
Dennis
@VoteToClose J'ai modifié ma réponse.
Dennis
2

CJam (53 octets)

Nq+N/:a::~:A,_m*_.&{,}$_{{_Af=e_|}:PA,*A,,^0-P0&!}#=,

C'est un peu trop lent pour l'interprète en ligne.

Dissection

Nq+N/:a::~:A      e# Parse the input into arrays and store in A
,_m*_.&           e# Generate (with duplicates) a powerset of [0 1 ... n]
{,}$              e# Sort by size
_{                e# Create a copy and search for first index satisfying...
  {_Af=e_|}:P     e#   Store in P a block which does a reachability expansion
  A,*             e#   Apply it n times (no path can be longer than n)
  A,,^0-          e#   Invert to get the unreached nodes (except 0)
  P               e#   Apply P again to see what's reached from the unreached nodes
  0&!             e#   Check that it doesn't include [0]
}#
=,                e# Look up the powerset element at that index and find length
Peter Taylor
la source
J'ai reçu java.lang.OutOfMemoryError: Java heap spaceavec votre programme.
ŽaMan
@qumonio, ce n'est pas particulièrement évolutif. Je ne l'ai pas testé avec des entrées plus grandes que les entrées de test dans la question, donc je ne sais pas jusqu'où cela peut aller sur un tas standard de 1 Go.
Peter Taylor
J'essayais la ligne 6 ici montrée comme un tableau dans JS: [ [4,0], [1,3,4], [0], [6,0], [3,0], [5]]bien sûr avec le style d'entrée comme indiqué dans le post original.
ŽaMan
@qumonio, sur mon ordinateur, il gère très bien cette entrée avec seulement 128 Mo de tas, ce qui est inférieur à ce qu'il a par défaut.
Peter Taylor
0

Haskell, 173 octets

l est celui que tu veux appeler.

Je ne sais pas si je ne devrais pas utiliser un pseudo- à la Mapplace ( [(Int,[Int])]au lieu de [[Int]]).

l=o[].map(map read).map words.lines
o[]b|0`notElem`concat b=0|0<1=1+minimum[o[n]b|n<-[1..length b],b!!(n-1)/=[]]
o(n:k)b=o(filter(/=0)(k++b!!(n-1)))(take(n-1)b++[]:drop n b)
Leif Willerts
la source