Compiti di matematica di quarta elementare per la settimana: un commesso viaggiatore inefficiente


10

Mia figlia aveva il seguente incarico per i compiti di matematica. Immagina sei amici che vivono su una linea, chiamati E, F, G, H, J e K. Le loro posizioni sulla linea sono come indicato (non in scala) di seguito:

Pertanto, F vive cinque unità da E e due unità da G, e così via.

Il tuo compito: crea un programma che identifica un percorso che visita ogni amico esattamente una volta con una lunghezza totale di n unità, prendendo le posizioni degli amici e n come input. Dovrebbe riportare il percorso se lo trova (ad esempio, per la lunghezza 17 potrebbe riportare "E, F, G, H, J, K" e dovrebbe uscire con grazia se non esiste una soluzione. Per quello che vale, ho completato una soluzione non golfata in Mathematica in 271 byte. Sospetto che sia possibile molto più concisa di così.


3
Potrebbe essere meglio come un programma che accetta input (es. [0, 5, 7, 13, 16, 17]E 62) in modo che tu possa assicurarti che non sia specificamente codificato in questo caso.
Maniglia della porta

@Doorknob, buon punto. Ho modificato di conseguenza l'incarico.
Michael Stern,

1
Il percorso inizia da qualche amico?
xnor

1
Posso definire il formato delle stringhe di input e output? Un input simile "[0, 5, 7, 13, 16, 17], 62"e un output sono "(7, 16, 0, 17, 5, 13)"ok?
Logic Knight,

1
@Geobits solo sciatta da parte mia. Corretto.
Michael Stern,

Risposte:


1

J, 54 byte

Emette un percorso corretto. Se non esiste alcun percorso, non viene emesso nulla.

   f=.4 :'{.(x=+/|:2|@-/\"#.s A.y)#(s=.i.!6)A.''EFGHJK'''

   62 f 0 5 7 13 16 17
GJEKFH

Codice a 52 byte che emette tutti i percorsi (uno per riga):

f=.4 :'(x=+/|:2|@-/\"#.s A.y)#(s=.i.!6)A.''EFGHJK'''

Codice a 38 byte che genera posizioni anziché lettere:

f=.4 :'p#~x=+/|:2|@-/\"#.p=.(i.!6)A.y'

Non riesco a controllare il codice, ma secondo il tuo riepilogo, questa sembra essere la voce più breve che fa tutto ciò che il problema richiede.
Michael Stern,

6

Mathematica, 55 o 90 byte

Mathematica hai detto? ;)

FirstCase[Permutations@#,p_/;Tr@Abs@Differences@p==#2]&

Questa è una funzione anonima che prende prima le posizioni degli amici (in qualsiasi ordine) e poi la lunghezza del bersaglio. Restituisce Missing[NotFound], se non esiste tale percorso.

FirstCase[Permutations@#,p_/;Tr@Abs@Differences@p==#2]&[{0, 5, 7, 13, 16, 17}, 62]
(* {7, 16, 0, 17, 5, 13} *)

Posso salvare quattro byte se è consentito restituire tutti i percorsi validi ( FirstCase-> Cases).

Restituire una matrice di stringhe è un po 'più complicato:

FromCharacterCode[68+#]&/@Ordering@FirstCase[Permutations@#,p_/;Tr@Abs@Differences@p==#2]&

Potresti adattarti in modo che risponda alle lettere anziché solo alle posizioni?
Michael Stern,

@MichaelStern Non è davvero chiaro dalla domanda quanto dovrebbe essere hardcoded e quanto dovrebbe essere parte dei parametri? L'input dovrebbe essere qualcosa come una mappatura dalle lettere alle posizioni?
Martin Ender,

Supponiamo che le lettere siano sempre nell'ordine indicato nella riga numerica sopra (E, F, G, H, J, K). Le distanze tra loro dovrebbero essere passate alla funzione come si fa nella soluzione.
Michael Stern,

@MichaelStern Ho aggiunto una versione che restituisce una matrice di stringhe. Supporta un numero qualsiasi di posizioni nell'elenco, ma dopo Zcontinuerà con i caratteri ASCII successivi (non che tu voglia eseguire comunque il mio codice per n> 20: D).
Martin Ender,

5

Python 2, 154 148 byte

(o 118 byte per la soluzione generale)

Questo programma accetta una riga con un elenco e un numero intero come '[0, 5, 7, 13, 16, 17], n' su stdin e stampa un percorso sull'output di lunghezza n o niente se impossibile.

# echo "[0, 5, 7, 13, 16, 17], 62" | python soln.py 
['G', 'J', 'E', 'K', 'F', 'H']

È difficile scrivere piccoli programmi in Python che richiedono permutazioni. L'importazione e l'uso sono molto costosi.

from itertools import*
a,c=input()
for b in permutations(a):
 if sum(abs(p-q)for p,q in zip(b[1:],b))==c:print['EFGHJK'[a.index(n)]for n in b];break

La fonte per il requisito OP prima del minificatore:

from itertools import*

puzzle, goal = input()
for option in permutations(puzzle):
    if sum(abs(p-q) for p,q in zip(option[1:], option)) == goal :
        print ['EFGHJK'[puzzle.index(n)] for n in option];
        break

La soluzione generale (non minimizzata):

from itertools import*

puzzle, goal = input()
for option in permutations(puzzle):
    if sum(abs(p-q) for p,q in zip(option[1:], option)) == goal :
        print option;
        break

Grazie al semplice algoritmo e al vasto numero di combinazioni, l'esecuzione per più di 20 posizioni iniziali sarà molto lenta.


È possibile salvare alcuni byte con from itertools import*. Inoltre, Python 3 potrebbe essere più breve con input()e *a,c=map(...)se può funzionare con il resto del programma.
grc

Grazie per il suggerimento sull'importazione. Sto resistendo a un'installazione py3 e alla conversione della mia base di codice. Sto aspettando che ogni modulo di terze parti che uso sia disponibile e stabile sotto py3 (io uso molti di quelli vecchi e oscuri).
Logic Knight,

Potresti adattarti in modo che risponda alle lettere anziché solo alle posizioni?
Michael Stern,

chr(a.index(n)+69)?
Martin Ender,

Bella ottimizzazione. Ma penso che @MichaelStern voglia davvero vedere "EFGHJK", ed è stato abbastanza facile, quindi ho scritto il codice in quel modo.
Logic Knight,

4

J (48 o 65)

Ipotizzo che questo possa essere giocato a golf molto di più. Sentiti libero di usarlo come punto di partenza per giocare a golf

]A.~[:I.(=([:([:+/}:([:|-)}.)"1(A.~([:i.[:!#))))

O con lettere:

([:I.(=([:([:+/}:([:|-)}.)"1(A.~([:i.[:!#)))))A.[:(a.{~65+[:i.#)]

Cosa fa:

   62 (]A.~[:I.(=([:([:+/}:([:|-)}.)"1(A.~([:i.[:!#))))) 0 5 7 13 16 17
 7 16  0 17  5 13
 7 16  5 17  0 13
 7 17  0 16  5 13
 7 17  5 16  0 13
13  0 16  5 17  7
13  0 17  5 16  7
13  5 16  0 17  7
13  5 17  0 16  7

(Spero che questo formato I / O sia a posto ...)

Come lo fa:

(A.~([:i.[:!#))

Genera tutte le permutazioni dell'input

([:+/}:([:|-)}.)"1

Calcola la distanza

(]A.~[: I. (= ([:distance perms)))

Vede che i risultati sono gli stessi dell'input e genera nuovamente quelle permutazioni (sospetto che alcuni personaggi possano essere rasati qui)

Con lettere:

((a.{~65+[:i.#))

Crea un elenco delle prime n lettere, dove n è la lunghezza dell'elenco di input

indices A. [: letters ]

fa lo stesso come sopra


Puoi modificarlo per segnalare la risposta in termini di lettere?
Michael Stern,

@MichaelStern Potrei, ma ciò aggiungerebbe un po 'al conteggio dei personaggi (J è terribile con le stringhe). Ci proverò ora, per vedere quale potrebbe essere il danno.
ɐɔıʇǝɥʇuʎs

3

Ottava, 73

function r=t(l,d,s)r=perms(l)(find(sum(abs(diff(perms(d)')))==s,1),:);end

Non c'è davvero nulla da non giocare a questo, quindi lasciami provare a spiegare ... dall'interno verso l'esterno, permettiamo tutte le distanze, quindi per ogni permutazione, prendiamo le differenze tra le case, prendiamo il valore assoluto come distanza, aggiungili in alto, trova l'indice della prima permutazione con la distanza desiderata e permuta le lettere e trova quella particolare permutazione delle lettere.

octave:15> t(["E" "F" "G" "H" "J" "K"],[0 5 7 13 16 17],62)
ans = HEJFKG

che è 13-0-16-5-17-7 => 13 + 16 + 11 + 12 + 10 = 62.

octave:16> t(["E" "F" "G" "H" "J" "K"],[0 5 7 13 16 17],2)
ans = 

(vuoto per input impossibili)


Non so quale sia l'accordo, ma perms()in Octave 3.6.2 su ideone.com si verificano problemi con il vettore di stringhe.
Alex A.

Interessante. Ho 3.8.1 a livello locale.
dcsohl,

2

Matlab (86)

x=input('');X=perms(1:6);disp(char(X(find(sum(abs(diff(x(X).')))==input(''),1),:)+64))

Esempio in cui esiste una soluzione:

>> x=input('');X=perms(1:6);disp(char(X(find(sum(abs(diff(x(X).')))==input(''),1),:)+64))
[0, 5, 7, 13, 16, 17]
62
DBFAEC
>>

Esempio in cui non esiste una soluzione:

>> x=input('');X=perms(1:6);disp(char(X(find(sum(abs(diff(x(X).')))==input(''),1),:)+64))
[0, 5, 7, 13, 16, 17]
100
>> 

Matlab (62)

Se il formato di output può essere rilassato producendo posizioni anziché lettere e producendo una matrice vuota se non esiste alcuna soluzione:

X=perms(input(''));X(find(sum(abs(diff(X.')))==input(''),1),:)

Esempio in cui esiste una soluzione:

>> X=perms(input(''));X(find(sum(abs(diff(X.')))==input(''),1),:)
[0, 5, 7, 13, 16, 17]
62
ans =
    13     5    17     0    16     7

Esempio in cui non esiste una soluzione:

>> X=perms(input(''));X(find(sum(abs(diff(X.')))==input(''),1),:)
[0, 5, 7, 13, 16, 17]
62
ans =
   Empty matrix: 0-by-6

Matlab (54)

Se è accettabile per il programma fornire tutti i percorsi validi :

X=perms(input(''));X(sum(abs(diff(X.')))==input(''),:)

Esempio in cui esiste una soluzione:

>> X=perms(input(''));X(sum(abs(diff(X.')))==input(''),:)
[0, 5, 7, 13, 16, 17]
62
ans =
    13     5    17     0    16     7
    13     5    16     0    17     7
    13     0    17     5    16     7
    13     0    16     5    17     7
     7    16     5    17     0    13
     7    16     0    17     5    13
     7    17     5    16     0    13
     7    17     0    16     5    13

1

Haskell, 109 byte

import Data.List
a%b=abs$snd a-snd b
n#l=[map(fst)p|p<-permutations(zip['E'..]l),n==sum(zipWith(%)p(tail p))]

Esempio di utilizzo: 17 # [0, 5, 7, 13, 16, 17]che genera tutti i percorsi validi, ad es ["EFGHIJ","JIHGFE"]. Se non esiste un percorso valido, []viene restituito l'elenco vuoto .

L'elenco delle lettere include I(spero che vada bene).

Come funziona: crea un elenco di (name, position)coppie, permuta e prendi quelle in cui la lunghezza del percorso è uguale ne rimuovi la parte di posizione.

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.