<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: permutations code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sat, 11 Oct 2008 18:06:06 GMT</pubDate>
    <description>DZone Snippets: permutations code</description>
    <item>
      <title>Permutations of letters in a word</title>
      <link>http://snippets.dzone.com/posts/show/5763</link>
      <description>I've been programming for a while but for some reason figuring this out was really hard - it took me 2 and a half hours. Unsurprisingly, the solution is extremely simple...&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/usr/bin/ruby&lt;br /&gt;# permute - takes a word and returns all the permutations of the letters in the word&lt;br /&gt;&lt;br /&gt;def permute(word="")&lt;br /&gt;  permutations_among(word.split(//))&lt;br /&gt;end&lt;br /&gt;def permutations_among(letters)&lt;br /&gt;  permutations = []&lt;br /&gt;  if letters.size == 1&lt;br /&gt;    permutations &lt;&lt; letters.first&lt;br /&gt;  else&lt;br /&gt;    letters.each_with_index do |letter, i|&lt;br /&gt;      surrounding_letters = letters.dup; surrounding_letters.delete_at(i)&lt;br /&gt;      permutations += permutations_among(surrounding_letters).map {|permutation| letter + permutation }&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  permutations&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;permute(ARGV.shift).each {|permutation| puts permutation }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Some benchmarks against other implementations:&lt;br /&gt;&lt;br /&gt;* Array#permutations: &lt;a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/32844"&gt;http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/32844&lt;/a&gt;&lt;br /&gt;* Array#perm: &lt;a href="http://blade.nagaokaut.ac.jp/~sinara/ruby/math/combinatorics/array-perm.rb"&gt;http://blade.nagaokaut.ac.jp/~sinara/ruby/math/combinatorics/array-perm.rb&lt;/a&gt;&lt;br /&gt;* geta: &lt;a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/139290"&gt;http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/139290&lt;/a&gt;&lt;br /&gt;* String#perm (based on geta)&lt;br /&gt;* Array#each_permutation: &lt;a href="http://knanshon.blogspot.com/2006/08/ruby-permutations.html"&gt;http://knanshon.blogspot.com/2006/08/ruby-permutations.html&lt;/a&gt;&lt;br /&gt;* permutation: &lt;a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/140345"&gt;http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/140345&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                                              user     system      total        real&lt;br /&gt;permutations_among:                       1.680000   0.010000   1.690000 (  1.700779)&lt;br /&gt;Array#permutations:                       1.740000   0.010000   1.750000 (  1.798288)&lt;br /&gt;geta:                                     2.430000   0.010000   2.440000 (  2.506668)&lt;br /&gt;String#perm:                              2.260000   0.010000   2.270000 (  2.280652)&lt;br /&gt;Array#each_permutation:                   0.820000   0.000000   0.820000 (  0.827463)&lt;br /&gt;permutation:                              2.140000   0.010000   2.150000 (  2.171966)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Benchmark code:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;require 'benchmark'&lt;br /&gt;&lt;br /&gt;N = 1_000&lt;br /&gt;Benchmark.bm(40) do |x|&lt;br /&gt;  letters = %w(a b c d e)&lt;br /&gt;  string = "abcde"&lt;br /&gt;  x.report("permutations_among:") do&lt;br /&gt;    N.times { permutations_among(letters) }&lt;br /&gt;  end&lt;br /&gt;  x.report('Array#permutations:') do&lt;br /&gt;    N.times { letters.permutations }&lt;br /&gt;  end&lt;br /&gt;  x.report('geta:') do&lt;br /&gt;    N.times { geta(string) }&lt;br /&gt;  end&lt;br /&gt;  x.report('String#perm:') do&lt;br /&gt;    N.times { string.perm }&lt;br /&gt;  end&lt;br /&gt;  x.report('Array#each_permutation:') do&lt;br /&gt;    N.times { letters.each_permutation {|perm| } }&lt;br /&gt;  end&lt;br /&gt;  x.report('permutation:') do&lt;br /&gt;    N.times { 0.upto(string.length.factorial-1) {|i| permutation(string, i)} }&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So, not bad for a first try ;)</description>
      <pubDate>Sun, 13 Jul 2008 22:21:49 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5763</guid>
      <author>mcmire ()</author>
    </item>
    <item>
      <title>Generate permutations</title>
      <link>http://snippets.dzone.com/posts/show/4632</link>
      <description>Generates all the permutations of {1, 2, ..., n}.&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://compprog.wordpress.com/2007/10/08/generating-permutations-2/"&gt;this&lt;/a&gt; for further explanations.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;void printv(int v[], int n) {&lt;br /&gt;	int i;&lt;br /&gt;&lt;br /&gt;	for (i = 0; i &lt; n; i++)&lt;br /&gt;		printf("%d ", v[i]);&lt;br /&gt;	printf("\n");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*!&lt;br /&gt;	This just swaps the values of a and b&lt;br /&gt;&lt;br /&gt;	i.e if a = 1 and b = 2, after&lt;br /&gt;&lt;br /&gt;		SWAP(a, b);&lt;br /&gt;&lt;br /&gt;	a = 2 and b = 1&lt;br /&gt;*/&lt;br /&gt;#define SWAP(a, b) a = a + b - (b = a)&lt;br /&gt;&lt;br /&gt;/*!&lt;br /&gt;	Generates the next permutation of the vector v of length n.&lt;br /&gt;&lt;br /&gt;	@return 1, if there are no more permutations to be generated&lt;br /&gt;&lt;br /&gt;	@return 0, otherwise&lt;br /&gt;*/&lt;br /&gt;int next(int v[], int n) {&lt;br /&gt;	/* P2 */&lt;br /&gt;	/* Find the largest i */&lt;br /&gt;	int i = n - 2;&lt;br /&gt;	while ((i &gt;= 0) &amp;&amp; (v[i] &gt; v[i + 1]))&lt;br /&gt;		--i;&lt;br /&gt;&lt;br /&gt;	/* If i is smaller than 0, then there are no more permutations. */&lt;br /&gt;	if (i &lt; 0)&lt;br /&gt;		return 1;&lt;br /&gt;&lt;br /&gt;	/* Find the largest element after vi but not larger than vi */&lt;br /&gt;	int k = n - 1;&lt;br /&gt;	while (v[i] &gt; v[k])&lt;br /&gt;		--k;&lt;br /&gt;	SWAP(v[i], v[k]);&lt;br /&gt;&lt;br /&gt;	/* Swap the last n - i elements. */&lt;br /&gt;	int j;&lt;br /&gt;	k = 0;&lt;br /&gt;	for (j = i + 1; j &lt; (n + i) / 2 + 1; ++j, ++k)&lt;br /&gt;		SWAP(v[j], v[n - k - 1]);&lt;br /&gt;&lt;br /&gt;	return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[]) {&lt;br /&gt;	int v[128];&lt;br /&gt;	int n = 3;&lt;br /&gt;&lt;br /&gt;	/* The initial permutation is 1 2 3 ...*/&lt;br /&gt;	/* P1 */&lt;br /&gt;	int i;&lt;br /&gt;	for (i = 0; i &lt; n; ++i)&lt;br /&gt;		v[i] = i + 1;&lt;br /&gt;	printv(v, n);&lt;br /&gt;&lt;br /&gt;	int done = 1;&lt;br /&gt;	do {&lt;br /&gt;		if (!(done = next(v, n)))&lt;br /&gt;			printv(v, n); /* P3 */&lt;br /&gt;	} while (!done);&lt;br /&gt;&lt;br /&gt;	return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 10 Oct 2007 14:45:36 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4632</guid>
      <author>scvalex (Alexandru Scvortov)</author>
    </item>
    <item>
      <title>Factorial function</title>
      <link>http://snippets.dzone.com/posts/show/4257</link>
      <description>A (non-recursive) factorial function&lt;br /&gt;&lt;code&gt;int factorial(int x) {&lt;br /&gt; int fac = 1;&lt;br /&gt; for (int i=2; i&lt;=x; i++) fac *= i;&lt;br /&gt; return fac;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Also, with this function defined, you can use two macros for calculating combinations &amp; permutations:&lt;br /&gt;&lt;code&gt;#define nCr(n, r) (factorial(n) / factorial(n-r) / factorial(r))&lt;br /&gt;#define nPr(n, r) (factorial(n) / factorial(n-r))&lt;/code&gt;</description>
      <pubDate>Thu, 05 Jul 2007 03:50:14 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4257</guid>
      <author>Minimiscience (Guildorn Tanaleth)</author>
    </item>
  </channel>
</rss>
