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