Partiziona un elenco!


10

In questa sfida, è necessario partizionare un elenco, in cui le partizioni hanno una dimensione massima, una dimensione minima e una dimensione preferita. Userò la notazione (min,pref,max) per indicare le dimensioni in questa sfida.

Per coloro che non hanno familiarità con il partizionamento, il seguente elenco è stato partizionato in parti di 3:
[0..9] -> [[0,1,2],[3,4,5],[6,7,8]]

Quando l'elenco non è divisibile, è necessario le partizioni di essere il più vicino alla dimensione preferita possibile: [0..10], (2,4,5) -> [[0,1,2,3],[4,5,6],[7,8,9]]. È preferibile questo partizionamento [[0,1,2,3],[4,5,6,7],[8,9]], anche se quest'ultimo ha una lunghezza maggiore. Formalmente, dobbiamo ridurre al minimo la somma di (partitionLength-preferredSize)^2per ogni partizione.

L'ordine delle lunghezze delle partizioni non ha importanza: per [0..5], (2,3,3), o [[0,1,2],[3,4]]o [[0,1],[2,3,4]]funziona. Se nessuna partizione è possibile restituire un array vuoto: [0..7], (4,4,5) -> [].

Puoi presumere che 1<=min<=pref<=maxe che l'array passato a te sia un array di numeri interi non vuoto. L'array sarà sempre il primo argomento. Puoi accettare min, max e pref in qualsiasi ordine e come tupla o come argomenti separati.

Il programma deve essere eseguito in un paio di secondi. Fondamentalmente, non è consentito scorrere ogni possibile dimensione della partizione all'interno dei limiti.

Casi test:

[1], (1,3,4)         -> [[1]]
[100], (1,2,3)       -> [[100]]
[1,2], (1,1,2)       -> [[1],[2]]
[1,2], (1,2,2)       -> [[1,2]]
[1,2], (1,3,3)       -> [[1,2]]
[1,2,3], (1,2,3)     -> [[1,2],[3]] or [[1,2,3]]
[1,2,3,4], (1,3,4)   -> [[1,2,3,4]]
[1,2,3,4,5], (3,3,4) -> []
[1,2,3,4,5], (2,2,2) -> []
[1,2,3,4,5], (3,3,5) -> [[1,2,3,4,5]]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49], (2,6,6) -> [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24],[25,26,27,28,29],[30,31,32,33,34],[35,36,37,38,39],[40,41,42,43,44],[45,46,47,48,49]]

Questo è un , quindi mira al minor numero di byte possibile nella tua lingua preferita!


La notazione che stai utilizzando [a..b]include aed esclude b, corretta?
Alex A.

A compresa, B esclusiva.
Nathan Merrill,

Nota che la tua interpretazione di a non è la stessa di una partizione dalla teoria degli insiemi ...
agtoever

Ma è effettivamente equivalente al partizionamento intero.
Nathan Merrill,

E se non ci fosse soluzione?
feersum

Risposte:


2

Haskell, 152

_%0=[]
s%k|(a,b)<-splitAt(div(z s)k)s=a:b%(k-1)
z=length
f s n p x=snd$minimum$(z s*p^2,[]):[(sum[(z x-p)^2|x<-s%k],s%k)|k<-[-div(-z s)x..div(z s)n]]

In qualsiasi partizione, se ci sono due elenchi che hanno una lunghezza che differisce di due o più, sarà sempre utile ridurre l'elenco più grande e ingrandire l'elenco più piccolo. pertanto, dobbiamo solo considerare le partizioni con solo due dimensioni di elenco, il che semplifica il calcolo.

il programma viene quindi eseguito su tutte le possibili quantità di elenchi nella partizione. data la quantità di liste nella partizione, il punteggio è determinato in modo univoco. il programma calcola una partizione adatta e il suo punteggio.

quindi trova il minimo complessivo e lo restituisce.

Utilizzo: input like f [1,2,3,4,5] 1 3 4( fè la funzione che risolve la sfida)

Sebbene sia possibile calcolare l'opzione migliore in modo completamente numerico e solo successivamente partizionando l'elenco di conseguenza, sono stati necessari troppi byte. tuttavia, la mia ultima versione di questo approccio è:

_%0=[]
s%k|(a,b)<-splitAt(div(length s)k)s=a:b%(k-1)
f s n p x|l<-length s=(s%)$snd$minimum$(l*p^2,0):[(k*j^2+mod l k*(1-2*j),k)|k<-[1..div l n],k*x>=l,j<-[p-div l k]]

1

CJam, 70

q~:S;_,[0L]a{_S2=e<),S0=>f{[__S1=-_*\]@@-j.+}[esL]a+:e<}j1={/(\e_}/;]p

Provalo online

Il codice trova una sequenza ottimale di dimensioni delle partizioni in base alle dimensioni dell'elenco, utilizzando la programmazione dinamica (tramite ricorsione memorizzata), quindi procede e suddivide l'elenco.

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.