Risolvi il problema del carrello


14

I filosofi hanno riflettuto a lungo sul problema del carrello . Sfortunatamente, nessun essere umano ha ancora risolto questo problema. Fortunatamente, come programmatori possiamo usare i computer per risolvere il problema per noi!

Ingresso

Il programma prenderà come input un grafico diretto (finito) (con al massimo un bordo da xa y, per qualsiasi xe y), con un nodo designato e un numero intero non negativo collegato a ciascun bordo (che rappresenta il numero di persone legate a quella traccia) . Inoltre, ogni nodo ha almeno un bordo di uscita.

Il carrello inizia nel nodo designato. Ad ogni giro, se il carrello si trova sul nodo x, l'utilitario seleziona un bordo (x,y). Le persone su quel bordo muoiono e il carrello ora è al limite y. Questo processo continua per sempre.

Nota che le persone possono morire solo una volta, quindi se il bordo (x,y)ha delle npersone legate ad esso, e il carrello vi scorre sopra, diciamo 100 volte, causerà comunque solo nmorti.

Produzione

L'utilitario fa le sue scelte in modo tale da ridurre al minimo il numero di persone che muoiono (che è garantito per essere finito, poiché ci sono solo persone finite). Il tuo programma genererà questo numero.

Formato di input

Puoi prendere il grafico di input in qualsiasi modo ragionevole tu voglia. Ad esempio, potresti prenderlo come una matrice e contare il nodo designato come quello etichettato 0. Oppure potresti usare qualcosa di simile x1,y1,n1;x2,y2,n2;.... Ad esempio 0,a,0;a,b,5;a,c,1;b,b,0;c,c,0per rappresentare il problema del carrello standard (con anelli all'estremità).

Casi test

  • 0,a,0;a,b,5;a,c,1;b,b,0;c,c,0 -> 1 (vai da 0 a a, da a a c (uccidendo una persona), quindi continua ad avvolgere il carrello da c a c).
  • 0,0,1;0,a,5;a,a,0 -> 1 (continua da 0 a 0, investendo 1 persona per l'eternità),
  • 0,a,5;0,b,1;a,a,1;b,b,6 -> 6 (0 -> a -> a -> a -> a -> ... (nota che la soluzione golosa di andare a b sarebbe errata))
  • 0,a,1;0,b,5;a,b,1;b,a,1 -> 3 (0 -> a -> b -> a -> b -> ...)
  • 0,a,1;0,b,1;a,a,0;b,b,0 -> 1 (Nota che ci sono due diverse opzioni che l'utilitarista potrebbe prendere che uccidono solo una persona)

Questo è , quindi vince la risposta più breve! In bocca al lupo.

Note: Non ci saranno loop de loops malati e la deriva multitraccia è vietata. Inoltre, anche se preferisco pensare a questo problema in termini di tre leggi (e) di Asimov, Peter Taylor ha notato nella sandbox che questo problema è matematicamente equivalente a quello di trovare il rho (percorso dei loop su se stesso) di minor peso .



2
@BetaDecay sì, ma a causa di aggiornamenti al carrello, si comportano allo stesso modo delle persone normali ai fini di questa domanda.
PyRulez,

Risposte:


6

Gelatina , 27 23 byte

ṗL$µṭ0FIm2ASµÐḟµQ⁴ySµ€Ṃ

Provalo online! (ultimo caso di test)

Versione crudele (Mutilare il maggior numero di persone)

Accetta input come numeri. Per l'ultimo esempio, 1è aed 2è b. 0è il nodo iniziale. Il primo argomento è l'elenco dei bordi (ad esempio [0,1],[0,2],[1,1],[2,2]) e il secondo argomento è un elenco dei bordi e il numero di persone su di essi (ad esempio [[0,1],[0,2],[1,1],[2,2]],[1,1,0,0]).

Come funziona

ṗL$µṭ0FIm2ASµÐḟµQ⁴ySµ€Ṃ
ṗL$                       - on the first argument, get the Cartesian power of it to its length.
                            this gives all paths of the length of the input. Cycles are implicit
   µ        µÐḟ           - get valid paths starting with 0 -- filter by:
    ṭ0                      - prepend 0
      F                     - flatten
       I                    - get the difference between elements
        m2                  - every second difference: 0 for each edge that starts at the node the previous edge ended at, nonzero otherwise.
          AS                - 0 iff all elements are 0
               µ    µ€    - on each path:
                Q           - remove repeat edges.
                 ⁴y         - translate according to the mapping in the second program argument
                   S        - Sum
                      Ṃ   - get the minimum of these.

@Shaggy Umm, non sei sicuro di cosa intendi? Jelly ti fa male agli occhi o qualcosa del genere?
Erik the Outgolfer,

1
@EriktheOutgolfer si riferisce alla versione del programma che cerca di mutilare la maggior parte delle persone.
fireflame241

@Shaggy Sarebbe una sfida interessante.
PyRulez,

9

Python 3 , 80 byte

y=lambda d,s=0,p=[],f=0:f in p and s or min(y(d,s+d[f][t],p+[f],t)for t in d[f])

Provalo online!

Accetta l'input come dizionario digitato dall'ID nodo. Le voci sono un dizionario di vicini e il numero di persone sulla traccia tra un nodo e il vicino. Ad esempio, per il primo caso di test:

{0: {1: 0}, 1: {2: 5, 3: 1}, 2: {2: 0}, 3: {3: 0}}

0 è il nodo iniziale, 1 è il nodo 'a', 2 è il nodo 'b', ecc.


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.