Skip to content

Instantly share code, notes, and snippets.

@benstopford
Created February 15, 2014 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benstopford/9020659 to your computer and use it in GitHub Desktop.
Save benstopford/9020659 to your computer and use it in GitHub Desktop.
Hacknight code for creating a spotify playlist for a search term with a desired length (boxpacking algorithm)
package boxpacking;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class SpotifyBoxpacking {
public static void main(String[] args) throws Exception {
new SpotifyBoxpacking("badger", 10 * 60);
}
public SpotifyBoxpacking(String searchString, int desiredPlaylistLength) throws Exception {
Map<String, Double> playlist;
playlist = boxpack(desiredPlaylistLength, downloadTracksWithLengths(searchString));
System.out.println(playlist);
System.out.printf("Looking for a track of length %s, created a playlist of length %s\n", desiredPlaylistLength, totalLength(playlist));
}
private Map<String, Double> boxpack(int desiredPlaylistLength, Map<String, Double> tracks) {
Map<String, Double> playlist = new HashMap<String, Double>();
for (String track : tracks.keySet()) {
double length = tracks.get(track);
double currentTotalLength = totalLength(playlist);
if (currentTotalLength + length <= desiredPlaylistLength) {
//step 1: fill up the playlist with tracks until it is the desired length
playlist.put(track, length);
} else {
//step2: once the playlist is full iterate over it for each unconsidered track making the first substitution that improves the playlist length
ArrayList<String> pickedSoFar = new ArrayList<String>(playlist.keySet());
for (int i = 0; i < pickedSoFar.size(); i++) {
String pickedTrack = pickedSoFar.get(i);
double pickedTrackLength = playlist.get(pickedTrack);
currentTotalLength = totalLength(playlist);
double lengthWithoutThisPickedTrack = currentTotalLength - pickedTrackLength;
if (lengthWithoutThisPickedTrack + length > currentTotalLength && lengthWithoutThisPickedTrack + length < desiredPlaylistLength) {
System.out.println("Switch out " + pickedTrackLength + " for " + length);
playlist.remove(pickedTrack);
playlist.put(track, length);
break;
}
}
}
}
return playlist;
}
private Map<String, Double> downloadTracksWithLengths(String searchString) throws IOException {
Map<String, Double> tracks = new HashMap<String, Double>();
URL url = new URL("http://ws.spotify.com/search/1/track?q="+ searchString);
BufferedReader bufReader = new BufferedReader(new InputStreamReader(url.openStream()));
String line = bufReader.readLine();
String trackName = "";
while (line != null) {
if (line.contains("<name>")) {
trackName = line.substring(line.indexOf("<name>") + 6, line.indexOf("</name>"));
}
if (line.contains("<length>")) {
Double trackLength = Double.valueOf(line.substring(line.indexOf("<length>") + 8, line.indexOf("</length>")));
tracks.put(trackName, trackLength);
trackName = "";
}
line = bufReader.readLine();
}
return tracks;
}
private double totalLength(Map<String, Double> playlist) {
double total = 0;
for (String name : playlist.keySet()) {
double length = playlist.get(name);
total += length;
}
return total;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment