Shuffle

Walter Bright newshound1 at digitalmars.com
Sat Jan 26 12:13:30 PST 2008


Latest based on suggestions:


/* Program to randomly copy music files from source to destination device.
  * Written in the D programming language.
  * Written by Walter Bright, http://www.digitalmars.com
  * Placed into the Public Domain.
  * Thanks to help from Oskar Linde, Anders Bergh, and Fritz van Bommel
  */


import std.file;
import std.stdio;
import std.string;
import std.c.stdlib;
import std.path;
import std.random;

int main(string[] args)
{
     if (args.length != 3)
     {	writefln("Usage: shuffle fromdir todir");
	exit(1);
     }
     auto fromdir = args[1];
     auto todir = args[2];

     /* Recursively search for all the mp3 and wma files in directory 
fromdir
      * and put them into files[]
      */
     string[] files;
     bool callback(DirEntry *de)
     {
	if (de.isdir)
	    listdir(de.name, &callback); // recurse into subdirectories
	else
	{
	    // Collect only files with mp3 and wma extensions
	    auto ext = getExt(de.name);
	    if (fnmatch(ext, "mp3") || fnmatch(ext, "wma"))
		files ~= de.name;
	}
	return true;	// keep going
     }
     std.file.listdir(fromdir, &callback);

     auto n = files.length;
     writefln(n, " music files");
     if (!n)
	return 0;

     /* Shuffle the files[] array using Durstenfeld's algorithm
      * based on the Fisher-Yates method
      */
     auto max = (typeof(std.random.rand()).max / n) * n;
     while (--n)
     {
	/* Pick random r in range 0..max, discarding others
	 * to eliminate modulo bias
	 */
	auto r = max;
	do
	    r = std.random.rand();
	while (r >= max);

	auto j = r % (n + 1);	// pick element to swap with

	// swap [n] and [j]
	auto tmp = files[n];
	files[n] = files[j];
	files[j] = tmp;
     }

     /* Sequentially fill the target until done or it quits with an
      * exception when the device is full.
      */
     foreach (fromfile; files)
     {
	auto tofile = std.path.join(todir, basename(fromfile));
	writefln("%s => %s", fromfile, tofile);
	std.file.copy(fromfile, tofile);
     }

     writefln("Done");
     return 0;
}


More information about the Digitalmars-d-announce mailing list