Created
February 15, 2014 15:21
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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