<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3574297678094971136</id><updated>2012-01-08T09:29:24.176-08:00</updated><category term='ruby array sort natcmp'/><category term='java junit unit testing'/><category term='ruby challenge'/><title type='text'>ZIJAB</title><subtitle type='html'>ZIJAB Is Just Another Blog -- Programming Languages Articles (Ruby, Java, etc.)</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://zijab.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://zijab.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Blogmaster</name><uri>http://www.blogger.com/profile/04882929917619086944</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>5</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3574297678094971136.post-2851061069232234294</id><published>2008-09-07T17:43:00.000-07:00</published><updated>2008-09-11T19:23:02.093-07:00</updated><title type='text'>Finding The Opposite Of A Regular Expression In Ruby</title><content type='html'>I don't know if it happened to you but there are some times when you want to find the contrary of what you have in mind, I mean the opposite (inverse) of a regular expression or everything except a certain regexp. Well, there is a way to achieve that with Ruby (and a lot of other programming languages):&lt;br /&gt;&lt;blockquote&gt;/^((?!REGULAR_EXPRESSION_HERE).)*$/&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;For example, if you want to find every lines where the first character is NOT 2 to 4 "f" followed by "oo" and then "bar" somewhere else on the line, you can use:&lt;br /&gt;&lt;blockquote&gt;/^((?!^f{2,4}oo.*bar).)*$/&lt;/blockquote&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;blockquote&gt;"foo+bar"[/^((?!^f{2,4}oo.*bar).)*$/] =&gt; "foo+bar"&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;"fffoo+bar"[/^((?!^f{2,4}oo.*bar).)*$/] =&gt; nil&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;" fffoo+bar"[/^((?!^f{2,4}oo.*bar).)*$/] =&gt; " fffoo+bar"&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;"fffffoo+bar"[/^((?!^f{2,4}oo.*bar).)*$/] =&gt; "fffffoo+bar"&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;For the references, those ideas came from the Vim tips section &lt;a href="http://www.vim.org/tips/tip.php?tip_id=802"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I hope this will help someone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3574297678094971136-2851061069232234294?l=zijab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zijab.blogspot.com/feeds/2851061069232234294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3574297678094971136&amp;postID=2851061069232234294' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default/2851061069232234294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default/2851061069232234294'/><link rel='alternate' type='text/html' href='http://zijab.blogspot.com/2008/09/finding-opposite-of-regular-expression.html' title='Finding The Opposite Of A Regular Expression In Ruby'/><author><name>Blogmaster</name><uri>http://www.blogger.com/profile/04882929917619086944</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3574297678094971136.post-8668094447397632300</id><published>2008-09-06T16:34:00.000-07:00</published><updated>2008-09-06T17:03:42.177-07:00</updated><title type='text'>Industrial Robot Controlled by Java (World's First)</title><content type='html'>Today I won't provide you with boring code but instead talk about something a lot of people would not believe possible. Some people already know that Sun has a commercial "Real-Time" system for Java. A &lt;a href="http://www.cs.lth.se/home/Sven_Robertz/publ/jtres-flexpicker.pdf"&gt;group of people&lt;/a&gt; have developed a robot controller powered by Java. To achieve their goal, they used a commercial industrial robot from the ABB company: The ABB IRB 340 Flexpicker, one of the fastest (10 G of acceleration) robot in the world. Because seeing is believing, here is the video:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=xH1yUXd9krU"&gt;Click here to see the video&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I was amazed! Now, can you imagine yourself hacking an industrial robot controller with your favorite Java IDE?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3574297678094971136-8668094447397632300?l=zijab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zijab.blogspot.com/feeds/8668094447397632300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3574297678094971136&amp;postID=8668094447397632300' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default/8668094447397632300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default/8668094447397632300'/><link rel='alternate' type='text/html' href='http://zijab.blogspot.com/2008/09/industrial-robot-controlled-by-java.html' title='Industrial Robot Controlled by Java (World&apos;s First)'/><author><name>Blogmaster</name><uri>http://www.blogger.com/profile/04882929917619086944</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3574297678094971136.post-6868678181235780979</id><published>2007-06-19T15:45:00.000-07:00</published><updated>2007-06-19T17:18:37.697-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java junit unit testing'/><title type='text'>One way to test a two dimensional array in Java with JUnit</title><content type='html'>There is some times when you want to do some unit testing on a multidimensional array with Java and JUnit. I'm posting one solution today to share it, but also because I want you to share your better solutions. I am really not an expert in Java and I had some difficulties trying to unit test one of my class with a 2 dimensional array, so I wrote this simple class:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;import junit.framework.Assert;&lt;br /&gt;import java.util.Arrays;&lt;br /&gt;&lt;br /&gt;public class Assertx extends Assert {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/** A private constructor because we don't want any Assertx object */&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private Assertx() {}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/**&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* This method test two "2 dimensional" arrays to see if they are the same&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* size and if the items inside are the same.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* @param message The message that will be outputed if the test fail.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* @param expected The expected 2 dimensional array.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;* @param actual The actual 2 dimensional array.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static public void assertArrayEquals(String message,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double[][] expected,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;double[][]&amp;nbsp;actual)&amp;nbsp;{&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;If&amp;nbsp;both&amp;nbsp;arrays&amp;nbsp;are&amp;nbsp;null,&amp;nbsp;then&amp;nbsp;we&amp;nbsp;consider&amp;nbsp;they&amp;nbsp;are&amp;nbsp;equal&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(expected&amp;nbsp;==&amp;nbsp;null&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;actual&amp;nbsp;==&amp;nbsp;null)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return;&amp;nbsp;//&amp;nbsp;We&amp;nbsp;get&amp;nbsp;out&amp;nbsp;of&amp;nbsp;the&amp;nbsp;function&amp;nbsp;as&amp;nbsp;everything&amp;nbsp;is&amp;nbsp;fine.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;We&amp;nbsp;test&amp;nbsp;to&amp;nbsp;see&amp;nbsp;if&amp;nbsp;the&amp;nbsp;first&amp;nbsp;dimension&amp;nbsp;is&amp;nbsp;the&amp;nbsp;same.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(expected.length&amp;nbsp;!=&amp;nbsp;actual.length)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fail(message&amp;nbsp;+&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;".&amp;nbsp;The&amp;nbsp;array&amp;nbsp;lengths&amp;nbsp;of&amp;nbsp;the&amp;nbsp;first&amp;nbsp;dimensions&amp;nbsp;aren't&amp;nbsp;the&amp;nbsp;same.");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;We&amp;nbsp;test&amp;nbsp;every&amp;nbsp;array&amp;nbsp;inside&amp;nbsp;the&amp;nbsp;'outer'&amp;nbsp;array.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;(int&amp;nbsp;i=0; i&amp;gt;expected.length; i++)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Can&amp;nbsp;also&amp;nbsp;use&amp;nbsp;(with&amp;nbsp;JUnit&amp;nbsp;4.3, but never tried&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// it)&amp;nbsp;assertArrayEquals(actual,&amp;nbsp;expected);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertTrue(message&amp;nbsp;+&amp;nbsp;".&amp;nbsp;Array&amp;nbsp;no."&amp;nbsp;+&amp;nbsp;i&amp;nbsp;+&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"&amp;nbsp;in&amp;nbsp;expected&amp;nbsp;and&amp;nbsp;actual&amp;nbsp;aren't&amp;nbsp;the&amp;nbsp;same.",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Arrays.equals(expected[i],&amp;nbsp;actual[i]));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/**&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;This&amp;nbsp;method&amp;nbsp;test&amp;nbsp;two&amp;nbsp;"2&amp;nbsp;dimensional"&amp;nbsp;arrays&amp;nbsp;to&amp;nbsp;see&amp;nbsp;if&amp;nbsp;they&amp;nbsp;are&amp;nbsp;the&amp;nbsp;same&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;size&amp;nbsp;and&amp;nbsp;if&amp;nbsp;the&amp;nbsp;items&amp;nbsp;inside&amp;nbsp;are&amp;nbsp;the&amp;nbsp;same.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;@param&amp;nbsp;expected&amp;nbsp;The&amp;nbsp;expected&amp;nbsp;2&amp;nbsp;dimensional&amp;nbsp;array.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*&amp;nbsp;@param&amp;nbsp;actual&amp;nbsp;The&amp;nbsp;actual&amp;nbsp;2&amp;nbsp;dimensional&amp;nbsp;array.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&amp;nbsp;public&amp;nbsp;void&amp;nbsp;assertArrayEquals(double[][]&amp;nbsp;expected,&amp;nbsp;double[][]&amp;nbsp;actual)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;assertArrayEquals(null,&amp;nbsp;expected,&amp;nbsp;actual);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To use this class, simply import it and do your test like this:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;double[][] arrAct = {{0.0}, {1.0}, {2.0}, {1}};&lt;br /&gt;double[][] arrExp = {{0.0}, {1.0}, {2.0}, {1}};&lt;br /&gt;&lt;br /&gt;assertArrayEquals(arrExp, arrAct);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, as you can see, it's quite simple to do your test with that kind of class. If you want to test for an 'int', simply change the 'double' for 'int'. As I was saying, I would like to know a better solution to do it. I guess there is a way to do it directly with JUnit, but I didn't come up with a working solution, so please, post your solutions!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3574297678094971136-6868678181235780979?l=zijab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zijab.blogspot.com/feeds/6868678181235780979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3574297678094971136&amp;postID=6868678181235780979' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default/6868678181235780979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default/6868678181235780979'/><link rel='alternate' type='text/html' href='http://zijab.blogspot.com/2007/06/one-way-to-test-two-dimensional-array.html' title='One way to test a two dimensional array in Java with JUnit'/><author><name>Blogmaster</name><uri>http://www.blogger.com/profile/04882929917619086944</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3574297678094971136.post-6171165751435392235</id><published>2007-05-01T17:22:00.000-07:00</published><updated>2007-05-01T18:58:14.257-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby array sort natcmp'/><title type='text'>Natural order String comparison for the Ruby Array class</title><content type='html'>Sometimes you want to order an array of strings with embedded numbers. But if we use the sort method from the array class we can have some big surprises (some information has been deleted for clarity):&lt;br/&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;strong&gt;irb&gt;&lt;/strong&gt;foo = ['foobar', 'a13bb32', 'a10', 'a13bb2c10',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'a2', 'a3', 'a13bb2c9', 'a13', 'a20', 'a13bb2',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'a13bb1', 'a13bb10', 'a13bb20', 'a13bb3', 'a13bb01']&lt;br/&gt;&lt;br /&gt;&lt;strong&gt;irb&gt;&lt;/strong&gt;puts foo.sort&lt;br /&gt;a10&lt;br/&gt;a13&lt;br/&gt;a13bb01&lt;br/&gt;a13bb1&lt;br/&gt;a13bb10&lt;br/&gt;a13bb2&lt;br/&gt;a13bb20&lt;br/&gt;a13bb2c10&lt;br/&gt;a13bb2c9&lt;br/&gt;a13bb3&lt;br/&gt;a13bb32&lt;br/&gt;a2&lt;br/&gt;a20&lt;br/&gt;a3&lt;br/&gt;foobar&lt;/span&gt;&lt;br/&gt;&lt;br /&gt;The problem is that the sort method from the Array class cannot "see" the embedded numbers. It only sorts comparing each characters one at a time (usually with the ASCII numbers for the priority), so that 'a13' comes before 'a2' (because '1' comes before '2', the sort method doesn't compare '13' with '2'). Because we can open Ruby classes easily, we can add a new way to sort our strings with embedded numbers:&lt;br /&gt;&lt;span style="font-size:85%; font-family:courier new;"&gt;&lt;br /&gt;# --------8&lt;--------&lt;br /&gt;class Array&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;# Method which sort an array composed of strings with embedded numbers by&lt;br /&gt;&amp;nbsp;&amp;nbsp;# the 'natural' representation of numbers inside a string.&lt;br /&gt;&amp;nbsp;&amp;nbsp;def natcmp&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reg_number = /\d+/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# We call the sort method of the Array class.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.sort do |str1, str2|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# We try to find an embedded number&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a = str1.match(reg_number)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b = str2.match(reg_number)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# If there is no number&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if [a,b].include? nil&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str1 &lt;=&gt; str2&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while true&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;begin&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# We compare strings before the number. If there&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# are equal, we will have to compare the numbers&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (comp = a.pre_match &lt;=&gt; b.pre_match) == 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# If the numbers are equal&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;comp = (a[0] == b[0]) ? comp = a[0] + a.post_match &lt;=&gt; b[0] + b.post_match : &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;comp = a[0].to_i &lt;=&gt; b[0].to_i&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;str1, str2 = a.post_match, b.post_match&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a = str1.match(reg_number)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b = str2.match(reg_number)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;rescue&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;comp&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;# Same as 'natcmp' but replace in place.&lt;br /&gt;&amp;nbsp;&amp;nbsp;def natcmp!&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.replace(natcmp)&lt;br /&gt;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;# --------8&lt;--------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;So now, if we try our new method, here's the result:&lt;br/&gt;&lt;br /&gt;&lt;span style="font-size:85%; font-family:courier new;"&gt;&lt;strong&gt;irb&gt;&lt;/strong&gt;puts foo.natcmp&lt;br/&gt;a2&lt;br/&gt;a3&lt;br/&gt;a10&lt;br/&gt;a13&lt;br/&gt;a13bb1&lt;br/&gt;a13bb01&lt;br/&gt;a13bb2&lt;br/&gt;a13bb2c9&lt;br/&gt;a13bb2c10&lt;br/&gt;a13bb3&lt;br/&gt;a13bb10&lt;br/&gt;a13bb20&lt;br/&gt;a13bb32&lt;br/&gt;a20&lt;br/&gt;foobar&lt;br/&gt;&lt;br/&gt;&lt;/span&gt;&lt;br /&gt;We can even use the 'natcmp!' method if we want to change the array in place. I hope this will help somebody.&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3574297678094971136-6171165751435392235?l=zijab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zijab.blogspot.com/feeds/6171165751435392235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3574297678094971136&amp;postID=6171165751435392235' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default/6171165751435392235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default/6171165751435392235'/><link rel='alternate' type='text/html' href='http://zijab.blogspot.com/2007/05/natural-order-string-comparison-for.html' title='Natural order String comparison for the Ruby Array class'/><author><name>Blogmaster</name><uri>http://www.blogger.com/profile/04882929917619086944</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3574297678094971136.post-5850257102589557533</id><published>2007-04-19T21:19:00.001-07:00</published><updated>2007-04-20T13:09:04.703-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby challenge'/><title type='text'>Ruby and the old phone programming challenge</title><content type='html'>I recently came across an old programming language challenge while I was looking for the new &lt;i&gt;D&lt;/i&gt; programming language (&lt;a href="http://www.digitalmars.com/d/lisp-java-d.html"&gt;&lt;span style="font-size:85%;"&gt;http://www.digitalmars.com/d/lisp-java-d.html&lt;/span&gt;&lt;/a&gt;). The challenge is to write a program which will output all possible combinations of phone numbers with words (like 555-ruby) given a dictionnary and a phone number in input. Lionello Lunesu took 1h15 and 55 lines of D code to achieve the goal. With the links on his site, I then look at&lt;a href="http://userpages.umbc.edu/~bcorfm1/C++-vs-Lisp.html"&gt; this site&lt;/a&gt; and &lt;a href="http://www.norvig.com/java-lisp.html"&gt;this one&lt;/a&gt; from Peter Norvig, a &lt;i&gt;Lisp&lt;/i&gt; programmer, which took 2h and 45 lines of lisp code to do it. Being a &lt;i&gt;Ruby&lt;/i&gt; fan, I tried to solve this challenge with one of my favorite language: &lt;i&gt;Ruby&lt;/i&gt;. I was telling everybody how much of a productivity boost I got since I learned this new language, I thought it was time to prove it. And guess what, I was able to achieve it with pretty good results: 20 lines of &lt;i&gt;Ruby&lt;/i&gt; code in 50 minutes (not couting blanks and comments like everybody else)! Here is my code:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:70%;"&gt;# Number/letters mapping&lt;br /&gt;map = {'2'=&gt;'a'..'c', '3'=&gt;'d'..'f', '4'=&gt;'g'..'i', '5'=&gt;'j'..'l', '6'=&gt;'m'..'o',&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'7'=&gt;'p'..'s', '8'=&gt;'t'..'v', '9'=&gt;'w'..'z', '0'=&gt;[], '1'=&gt;[]}&lt;br /&gt;&lt;br /&gt;if ARGV.length != 2&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;puts 'Usage: {dictFile} {phoneNumber}'&lt;br /&gt;else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Reading the file in memory (*nix or Windows (or Mac???))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f = IO.popen("cat #{ARGV[0]}") rescue IO.popen("type #{ARGV[0]}") rescue fail '?'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content = f.readlines&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# For each word found&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content.each do |word|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;word.chomp!.downcase!&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;next if word.empty? or word.size != ARGV[1].size # If the word is not good.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;good_word = true&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ARGV[1].size.times do |i|&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Comparing each letters&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if not map[ARGV[1][i,1]].include?(word[i,1])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;good_word = false&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Write it if it's good.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;puts word if good_word&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;end&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;That's it! I took a dictionnary from OpenOffice to test my code and it seems to work fine. I know that I could optimize my code, but that's not the point of the challenge. The same thing can be achieved with different languages (&lt;i&gt;Python&lt;/i&gt; for instance), but I wanted to share my solution for those of you who are looking at &lt;i&gt;Ruby&lt;/i&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3574297678094971136-5850257102589557533?l=zijab.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zijab.blogspot.com/feeds/5850257102589557533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3574297678094971136&amp;postID=5850257102589557533' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default/5850257102589557533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3574297678094971136/posts/default/5850257102589557533'/><link rel='alternate' type='text/html' href='http://zijab.blogspot.com/2007/04/ruby-and-old-phone-programming.html' title='Ruby and the old phone programming challenge'/><author><name>Blogmaster</name><uri>http://www.blogger.com/profile/04882929917619086944</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
