Un gioco di serrature e chiavi


12

Ci sono n caselle, numerate 1-n . Ogni casella è bloccata, in modo che possa essere aperta da un solo tipo di chiave corrispondente (anch'essa numerata 1-n ). Queste chiavi sono sparse casualmente nelle caselle (una casella può avere un numero qualsiasi di chiavi, una chiave può avere un numero qualsiasi di duplicati) e quindi tutte le caselle vengono chiuse. Un tesoro (numerato 0 ) è stato anche bloccato in molte caselle.

Hai assunto un fabbro per recuperare tutto il tesoro. Fa pagare per ogni scatola che apre. Non ci sono costi per l'apertura di una scatola per la quale la chiave è già disponibile.

L'input è il contenuto di ogni casella. Puoi decidere il formato dell'input.

Output il costo minimo richiesto per ottenere i tesori.

Appunti

  1. Il tuo algoritmo potrebbe richiedere molto tempo, ma questo è irrilevante.
  2. Il codice più corto vince.
  3. Non è necessario preoccuparsi di input non validi.

Dati di esempio

Qui la riga i rappresenta le chiavi presenti nella casella i .

Ingresso

2 0
3
4 0
5 6 0
6
0

Produzione

1

Ingresso

2 0
3 0

4 0
6
5 0

Produzione

3

Ingresso

2 4 0
3 0

1 0
6
5 0

Produzione

2

Ingresso

1
3 4


2 6
5

Produzione

0

2
Questo è forse legato a questo ?
Addison Crump,


@VotoToChiudi Bel video. È simile, tranne per il fatto che parla di un puzzle matematico e di un algoritmo specifico, piuttosto che uno generalizzato.
ghosts_in_the_code

1
Questo sembra legato a questo puzzle di circa 100 scatole chiuse di legno e acciaio: puzzling.stackexchange.com/q/17852/4551
xnor

4
@ghosts_in_the_code Non si tratta di semplicità ma di flessibilità. Comunemente, le sfide che richiedono input strutturati consentono qualsiasi formato elenco conveniente, a condizione che i dati non siano preelaborati. A seconda della lingua che potrebbe significare un file separato da spazi bianchi come te, o potrebbe significare [[1] [3 4] [] [] [2 6] [5]]o forse {{1},{3,4},{},{},{2,6},{5}}. In questo modo, la maggior parte delle lingue può ridurre la lettura dell'input a qualcosa di così banale i=eval(read())e concentrarsi sulla parte divertente della sfida.
Martin Ender,

Risposte:


6

CJam, 59 52 50 49 45 43 42 byte

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

Grazie a @ MartinBüttner per il golf off 3 byte e spianando la strada per altri 4!

Provalo online nell'interprete CJam .

Come funziona

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.

2
Potresti aggiungere una spiegazione per noi senza il dono della comprensione di CJam? : D Mi piacerebbe sapere come funziona.
Addison Crump,

2
@VotoToChiudi Guarda questo CJAM101
user41805

array long &funziona, quindi puoi rimuovere ada 0a&. Purtroppo questo rende leggermente più difficile catturarti.
Peter Taylor,

@PeterTaylor Sfortunatamente, se sostituisco 0a&con 0&, devo anche sostituire 0+con 0aa+, poiché 0 0&è falso.
Dennis,

@VotoToChiudi Ho modificato la mia risposta.
Dennis,

2

CJam (53 byte)

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

Questo è piuttosto lento per l'interprete online.

Dissezione

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

Ho ricevuto java.lang.OutOfMemoryError: Java heap spacecon il tuo programma.
ŽaMan,

@qumonio, non è particolarmente scalabile. Non l'ho testato con input più grandi degli input di test nella domanda, quindi non sono sicuro di quanto possa andare lontano su un heap standard da 1 GB.
Peter Taylor,

Stavo provando la 6 riga qui mostrata come un array in JS: [ [4,0], [1,3,4], [0], [6,0], [3,0], [5]]ovviamente con lo stile di input come mostrato nel post originale.
ŽaMan il

@qumonio, sul mio computer gestisce bene l'input con solo 128 MB di heap, che è inferiore a quello predefinito.
Peter Taylor,

0

Haskell, 173 byte

l è quello che vuoi chiamare.

Non sono sicuro se non dovrei usare uno pseudo- Mapinvece ( [(Int,[Int])]invece di [[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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.