<?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'><id>tag:blogger.com,1999:blog-7408569574805188613</id><updated>2009-10-04T12:10:17.749-07:00</updated><title type='text'>coding-experiments</title><subtitle type='html'>everything related to algorithms</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default?start-index=26&amp;max-results=25'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>33</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-8587457769872882861</id><published>2009-10-02T10:34:00.000-07:00</published><updated>2009-10-02T12:54:54.935-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='math expressions'/><category scheme='http://www.blogger.com/atom/ns#' term='F#'/><category scheme='http://www.blogger.com/atom/ns#' term='eval'/><title type='text'>Evaluating math expressions in F#</title><content type='html'>This time we will try to write math expressions evaluator in F#. At first - why we need that ? Well, math expressions evaluator is useful in computer algebra systems - for evaluating some equations. Also such evaluator may be useful for financial institutions where also some kind of formula computation/evaluation is needed and etc. It`s a pitty that such eval function is not implemented in F# language. Possible reasons is that F# is compiled language... Anyway we will try to write such universal eval function which accepts arbitrary math expression and returns result to the user. So what are possible ways of implementing such function in F# ?&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;br /&gt; - by writing so called domain-specific language - math expressions compiler. This is achieved by using some tools such as fsyacc and fslex. Defining custom tokens and etc.&lt;br /&gt;&lt;br /&gt; - by using .NET System.CodeDom.Compiler libraries. This is achieved by generating class definition "on the fly" and with the help of CodeDom - compiling this class in memory.&lt;br /&gt;&lt;br /&gt; - another different approach - is try to write F# script which recursively analyzes math expression and evaluates it piece by piece until it finds the answer. This solution does not use tools mentioned above.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So the last approach will be discussed here. Main algorithm of evaluating math expressions is displayed below:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_hTm-LSlj8U4/SsZLF6W1kXI/AAAAAAAAAHs/svR3bAFxuRM/s1600-h/eval_diag.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 307px; height: 400px;" src="http://1.bp.blogspot.com/_hTm-LSlj8U4/SsZLF6W1kXI/AAAAAAAAAHs/svR3bAFxuRM/s400/eval_diag.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5388076569131848050" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;F# code which implements this idea is &lt;a href="http://code.google.com/p/coding-experiments/source/browse/trunk/Fsharp/MathEvaluator.fs"&gt;placed here&lt;/a&gt;.&lt;br /&gt;There are also some eval() function tests implemented in this code. So that after executing this script you will get output something like:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_hTm-LSlj8U4/SsZOJNBfCPI/AAAAAAAAAH0/lEuY2kxr9sw/s1600-h/eval_tests.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 229px;" src="http://4.bp.blogspot.com/_hTm-LSlj8U4/SsZOJNBfCPI/AAAAAAAAAH0/lEuY2kxr9sw/s400/eval_tests.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5388079924217055474" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusions:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It is possible to generalize eval() function algorithm in about 90~ lines of F# code without using CodeDom model or fsyacc/fslex tools. This makes solution pretty much "homogeneous" which can be useful in some situations. Also this eval() implementation takes as input arbitrary math expression. As for the bad side - solution is very slow (can be hundreds of times slower than plain F# function call), because of joining/spliting lists constantly. So if you need fast implementation of eval - you should optimize/rewrite this code if possible or take a look in other above mentioned solutions. But in systems where speed issues are not critical - this solution may be OK.&lt;br /&gt;&lt;br /&gt;Have fun with F# and eval !!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-8587457769872882861?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/8587457769872882861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=8587457769872882861&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/8587457769872882861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/8587457769872882861'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2009/10/evaluating-math-expressions-in-f.html' title='Evaluating math expressions in F#'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_hTm-LSlj8U4/SsZLF6W1kXI/AAAAAAAAAHs/svR3bAFxuRM/s72-c/eval_diag.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-8809298968180742603</id><published>2009-09-17T23:07:00.000-07:00</published><updated>2009-10-04T11:36:07.633-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XNA Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='polygon'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='2D graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='geometry'/><title type='text'>XNA quest for centroid of polygon</title><content type='html'>Now we will talk about XNA Framework and How to find geometrical center of polygon (aka. so called centroid). At first - Why do we need centroid at all ? Well... for example - for some graphics applications we may want drag&amp;drop shape by it`s centroid. Or maybe in some game applications we may need to find shape`s center of gravity, for simulating physics of balancing objects around center of gravity. And in cases when shape material density is uniform (the same over shape) then shape geometrical center (centroid) is also center of gravity (or center of mass). So lets begin search of centroid...&lt;br /&gt;For this you will need:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;- Visual Studio 2008&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;- XNA 3.1 Framework&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First - some notes about XNA framework. It`s a pitty that such great 2D/3D .NET library doesn`t have 2D primitives drawing routines. Well, actually it has some, but for being able to draw some 2D primitives like points and lines, you should dig deeply in 3D knowledge - for drawing mentioned primitives in MSDN way you should define 3D vectors and 3D viewports !! What the hell ? If user only wants 2D stuff, it means that all 3D stuff should be abstracted out of the view. So that at the end, framework should have separate levels of abstraction into 2D and 3D. But this is not the case about drawing 2D primtives... So one way of drawing point in non-MSDN way is to generate small rectangle texture in run-time and draw this generated texture on screen. Next thing is drawing a simple line in non-MSDN way. Recipe for that - we take generated 2D rectangle texture earlier and draw it as line by scaling and rotating it as needed. After defining this stuff we have all prerequisites for target problem.&lt;br /&gt;Now- How we will find centroid of polygon ? This is not that hard. According to wikipedia &lt;a href="http://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon"&gt;centroid formulas&lt;/a&gt; can be computed simply, assuming we have polygon vertex coordinates and assuming polygon is not complex.&lt;br /&gt;So centroid computation algorithm in C# is this:&lt;br /&gt;&lt;br /&gt;_______________________________________________________&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public static Vector2 CalculateCentroid(Vector2[] points, &lt;br /&gt;                                        int lastPointIndex)&lt;br /&gt;{&lt;br /&gt;    float area = 0.0f;&lt;br /&gt;    float Cx = 0.0f;&lt;br /&gt;    float Cy = 0.0f;&lt;br /&gt;    float tmp = 0.0f;&lt;br /&gt;    int k;&lt;br /&gt;&lt;br /&gt;    for (int i = 0; i &lt;= lastPointIndex; i++)&lt;br /&gt;    {&lt;br /&gt;        k = (i + 1) % (lastPointIndex + 1);&lt;br /&gt;        tmp = points[i].X * points[k].Y - &lt;br /&gt;              points[k].X * points[i].Y;&lt;br /&gt;        area += tmp;&lt;br /&gt;        Cx += (points[i].X + points[k].X) * tmp;&lt;br /&gt;        Cy += (points[i].Y + points[k].Y) * tmp;&lt;br /&gt;    }&lt;br /&gt;    area *= 0.5f;&lt;br /&gt;    Cx *= 1.0f / (6.0f * area);&lt;br /&gt;    Cy *= 1.0f / (6.0f * area);&lt;br /&gt;&lt;br /&gt;    return new Vector2(Cx, Cy);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;___________________________________________&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;NOTE: this algorithm doesn`t apply for complex polygons&lt;/span&gt;. &lt;br /&gt;But How simply check that polygon is not complex, or not self-intersecting ? One way of doing this is brute-force way -&gt; we can check every polygon edge pair for intersection. If there are some edges which intersects, then polygon is complex, otherwise - simple. So by using this brute-force solution, complex polygon check simplifies to lines self-intersection problem. And How do we check if lines self-intersects ? One way is to find-out 2 linear equations of these lines: y = a1*x + b1 ; y = a2*x + b2.&lt;br /&gt;Then self-intersection point is simply where these equations equals:&lt;br /&gt;a1*x + b1 = a2*x + b2  --&gt; x_intersection = (b2-b1)/(a1-a2). Substituting into any of these two equations we get y_intersection = (a1*b2-a2*b1)/(a1-a2).&lt;br /&gt;Next step - we need to check does lines segments intersects, not the whole lines. This is done just comparing does x_intersection is within x_min,x_max of both lines, the similar check apply for y_intersection. So line intersection check simplifies to finding linear equations slope and intercept constants. This is one way of self-intersection test of lines. But there is also other way to do it (if we don`t need exact intersection point) - suppose we have line1 with end-points l1p1,l1p2 and line2 with end-points l2p1,l2p2. Define function DIRECTION(point1,point2,point3) which returns the direction [CLOCKWISE,COUNTER_CLOCKWISE,LINE] in which we traverse path point1-&gt;point2-&gt;point3. By having such function we can easily define when 2 line segments intersects. Below are one example when lines intersects:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_hTm-LSlj8U4/SrOeeJIz7HI/AAAAAAAAAHc/2u3WumvY4tI/s1600-h/intersecting.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 207px;" src="http://1.bp.blogspot.com/_hTm-LSlj8U4/SrOeeJIz7HI/AAAAAAAAAHc/2u3WumvY4tI/s400/intersecting.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382820220324015218" /&gt;&lt;/a&gt;&lt;br /&gt;Another example when lines do not intersects:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_hTm-LSlj8U4/SrOfWqM0YmI/AAAAAAAAAHk/9x-snmrqr0I/s1600-h/non-intersecting.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 265px;" src="http://4.bp.blogspot.com/_hTm-LSlj8U4/SrOfWqM0YmI/AAAAAAAAAHk/9x-snmrqr0I/s400/non-intersecting.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382821191271866978" /&gt;&lt;/a&gt;&lt;br /&gt;So lines intersects when :&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;direction(l1p1,l1p2,l2p1) != direction(l1p1,l1p2,l2p2) AND &lt;br /&gt;direction(l2p1,l2p2,l1p1) != direction(l2p1,l2p2,l1p2)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This type of lines intersection test is implemented in polygon self-intersection test. So you can download &lt;a href="http://coding-experiments.googlecode.com/svn/trunk/Csharp/Centroid.zip"&gt;centroid XNA 3.1 project&lt;/a&gt; and try experimenting by drawing various polygons and seeing where centroid is computed.&lt;br /&gt;Final part - some results from this project (centroid is draw as black pixel):&lt;br /&gt;Some convex polygons:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/SrOBxVCrP2I/AAAAAAAAAGc/dTA3Jmm1kgk/s1600-h/triangle.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 225px; height: 115px;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/SrOBxVCrP2I/AAAAAAAAAGc/dTA3Jmm1kgk/s320/triangle.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382788664099815266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/SrOCJiWyZEI/AAAAAAAAAGk/oI-Wai96S_A/s1600-h/trapezoid.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 218px; height: 74px;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/SrOCJiWyZEI/AAAAAAAAAGk/oI-Wai96S_A/s320/trapezoid.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382789079990690882" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/SrOCzHfBigI/AAAAAAAAAGs/9yPtnfqVPWI/s1600-h/parallelogram.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 166px; height: 87px;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/SrOCzHfBigI/AAAAAAAAAGs/9yPtnfqVPWI/s320/parallelogram.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382789794331986434" /&gt;&lt;/a&gt;&lt;br /&gt;Now, more interesting -&gt; concave polygons:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/SrOD5kFnvnI/AAAAAAAAAG0/bC4xmzd7eLg/s1600-h/concave1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 203px; height: 194px;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/SrOD5kFnvnI/AAAAAAAAAG0/bC4xmzd7eLg/s320/concave1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382791004600909426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/SrOEObDPDJI/AAAAAAAAAG8/VAsUFwqMOuk/s1600-h/concave2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 157px; height: 126px;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/SrOEObDPDJI/AAAAAAAAAG8/VAsUFwqMOuk/s320/concave2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382791362952236178" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_hTm-LSlj8U4/SrOEp36MYNI/AAAAAAAAAHE/6ILQFinwcwQ/s1600-h/concave3.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 166px; height: 189px;" src="http://1.bp.blogspot.com/_hTm-LSlj8U4/SrOEp36MYNI/AAAAAAAAAHE/6ILQFinwcwQ/s320/concave3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382791834555408594" /&gt;&lt;/a&gt;&lt;br /&gt;From the concave polygon examples (especially from first concave) can be seen that centroid is not the average of (max,min) coordinates in shape. However in some cases it can be that centroid coincides with AVERAGE(Min,Max) of figure (for example for rectangle). But in general - it not. If to talk informally, then centroid is simply the average of ALL points coordinates in shape.&lt;br /&gt;Finally just some examples of complex polygons - as evidence that application detects complex (or self-intersecting) polygons :-) :&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/SrOFtACNUrI/AAAAAAAAAHM/SYrXg9Re-jY/s1600-h/complex1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 108px;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/SrOFtACNUrI/AAAAAAAAAHM/SYrXg9Re-jY/s320/complex1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382792987787743922" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_hTm-LSlj8U4/SrOGKvdMXQI/AAAAAAAAAHU/as2gJjJLmJM/s1600-h/complex2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 97px;" src="http://4.bp.blogspot.com/_hTm-LSlj8U4/SrOGKvdMXQI/AAAAAAAAAHU/as2gJjJLmJM/s320/complex2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5382793498733600002" /&gt;&lt;/a&gt;&lt;br /&gt;Actually we can also compute centroids of complex polygon by using info from above mentioned wikipedia site. That is - to get centroid of complex polygon we need:&lt;br /&gt;1. Decompose complex polygon into N simple polygons.&lt;br /&gt;2. Compute area and centroid of each simple polygon by method already explained in this article.&lt;br /&gt;3. Average computed centroids by &lt;a href="http://en.wikipedia.org/wiki/Centroid#Centroid_by_geometric_decomposition"&gt;some formula&lt;/a&gt;.&lt;br /&gt;The main task is number 1. - How effectively split complex polygon into simple ones.&lt;br /&gt;This task is left as exercise to the reader :-)&lt;br /&gt;&lt;br /&gt;Have fun with centroids, polygons, XNA and 2D/3D programming in general !!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-8809298968180742603?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/8809298968180742603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=8809298968180742603&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/8809298968180742603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/8809298968180742603'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2009/09/xna-quest-for-centroid-of-polygon.html' title='XNA quest for centroid of polygon'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_hTm-LSlj8U4/SrOeeJIz7HI/AAAAAAAAAHc/2u3WumvY4tI/s72-c/intersecting.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-4150397248595649036</id><published>2009-06-21T12:23:00.000-07:00</published><updated>2009-10-04T11:24:53.527-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Langton&apos;s ant'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='cellular automaton'/><title type='text'>Langton's ant Or order out of chaos</title><content type='html'>This time we will talk about &lt;a href="http://en.wikipedia.org/wiki/Langton%27s_ant"&gt;Langton's ant&lt;/a&gt; - the simple system of simple rules, but with complex behavior. Simple system of Langton`s ant is defined as :&lt;br /&gt;    * At a white square, turn 90° left,  flip the color of the square, move forward one unit&lt;br /&gt;    * At a black square, turn 90° right, flip the color of the square, move forward one unit&lt;br /&gt;This is so called L/R system. But what if for the one color we will have not the one direction, but the direction chain ? That is- for the white squares we will have some chain of 'LRLRR...' events and for the black squares we will have another chain of 'RRLRRL...' events ?? These events should cycle in a row. Then more interesting patterns should occure. So this experiment tests this idea of multiple direction row for the same state/color. Experiment &lt;a href="http://code.google.com/p/coding-experiments/source/browse/trunk/Python/Langtons_ant.py"&gt;script is here&lt;/a&gt;.&lt;br /&gt;Results are somewhat interesting. At first, the classic Langton`s ant example-&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/L_R.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 247px; height: 180px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/L_R.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Can we have system with shorter steps to "highway" ? Seems - yes we can. This is it:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/L_LRL.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 205px; height: 163px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/L_LRL.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;But this is not the end. There is system which is almost "highway" from the scratch:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/L_RLL.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 223px; height: 168px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/L_RLL.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And finally- some exotic general Langton`s ant systems:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/LLR_LLRR.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 259px; height: 147px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/LLR_LLRR.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/LRL_RL.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 328px; height: 109px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/LRL_RL.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/LRR_LRRR.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 330px; height: 157px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/LRR_LRRR.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/L_LLRLLRR.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 225px; height: 189px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/L_LLRLLRR.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/L_LLRRR.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 145px; height: 248px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/L_LLRRR.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/L_LRRR.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 181px; height: 234px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/L_LRRR.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;Seems that systems L/R and L/LRL is unstable and switches to stable system L/RLL.&lt;br /&gt;Another conclusion is that there are some other systems that gets to the different types of "highway" - the order out of chaos.&lt;br /&gt;&lt;br /&gt;Have fun with Langton`s ant !!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-4150397248595649036?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/4150397248595649036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=4150397248595649036&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/4150397248595649036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/4150397248595649036'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2009/06/langtons-ant-or-order-out-of-chaos.html' title='Langton&apos;s ant Or order out of chaos'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-7382489815428621600</id><published>2009-03-15T10:13:00.000-07:00</published><updated>2009-10-04T11:14:37.287-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='image processing'/><category scheme='http://www.blogger.com/atom/ns#' term='digital image forensic'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='copy-move forgery'/><title type='text'>Detecting copy-move forgery in images</title><content type='html'>This time I`ll talk about digital image forensic and how to detect copy-move forgery in images. I`ve implemented some &lt;a href="http://code.google.com/p/coding-experiments/source/browse/trunk/Python/detect_copymove.py"&gt;ad-hoc algorithm&lt;/a&gt; for detection of this kind of forgeries. Algorithm is robust, so it can detect forgeries in lossy image formats- such as JPEG. Please keep in mind - this algorithm is experimental toy, if you want more general solutions - you should read &lt;a href="http://www.ws.binghamton.edu/fridrich/Research/copymove.pdf"&gt;this paper&lt;/a&gt; or &lt;a href="http://www.ists.dartmouth.edu/library/102.pdf"&gt;maybe this&lt;/a&gt; to get some ideas in the field.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Robust detection algorithm steps&lt;/b&gt;&lt;br /&gt;1. Blur image for eliminating image details&lt;br /&gt;2. Convert image to degraded palette&lt;br /&gt;3. Decompose image into small NxN pixel blocks&lt;br /&gt;4. Alphabetically order these blocks by their pixel values&lt;br /&gt;5. Extract only these adjacent blocks which have small absolute color difference&lt;br /&gt;6. Cluster these blocks into clusters by intersection area among blocks&lt;br /&gt;7. Extract only these clusters which are bigger than block size&lt;br /&gt;8. Extract only these clusters which have similar cluster, by using some sort of similarity function (in this case Hausdorff distance between clusters)&lt;br /&gt;9. Draw discovered similar clusters on image&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Copy-move detection script usage instructions&lt;/b&gt;&lt;br /&gt;1. At first try to execute script with default parameters-&lt;br /&gt;&lt;i&gt;python detect_copymove.py image&lt;/i&gt;&lt;br /&gt;2. Then try to lower block color deviation threshold-&lt;br /&gt;&lt;i&gt;python detect_copymove.py image --blcoldev=0.05&lt;/i&gt;&lt;br /&gt;3. Finally - run script in manual mode and try to spot similar regions by eyes-&lt;br /&gt;&lt;i&gt;python detect_copymove.py image --blcoldev=0.05 --imauto=0&lt;/i&gt;&lt;br /&gt;If by trying all 3 steps - no copy-move tamperings revealed - there is a good chance that really there are no such tamperings in image. BTW, script has more parameters, full list of them - &lt;br /&gt;&lt;i&gt;python detect_copymove.py --help&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Experiments - object cloning forgery&lt;/b&gt;&lt;br /&gt;This type of forgery tries to deceive viewer that there were more objects than really was.&lt;br /&gt;Original picture:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_hTm-LSlj8U4/Sb1HH5u5vxI/AAAAAAAAAFE/FVOBu956tK4/s1600-h/parade_org.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 232px;" src="http://4.bp.blogspot.com/_hTm-LSlj8U4/Sb1HH5u5vxI/AAAAAAAAAFE/FVOBu956tK4/s320/parade_org.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313481336449253138" /&gt;&lt;/a&gt;&lt;br /&gt;Doctored image:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/Sb1IAcy2MKI/AAAAAAAAAFM/qOCk_NV_Phg/s1600-h/parade_doc.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 232px;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/Sb1IAcy2MKI/AAAAAAAAAFM/qOCk_NV_Phg/s320/parade_doc.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313482307933712546" /&gt;&lt;/a&gt;&lt;br /&gt;Copy-move script output:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/Sb1IiFG3b1I/AAAAAAAAAFU/PIAWsXNTpIE/s1600-h/parade_doc_analyzed.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 232px;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/Sb1IiFG3b1I/AAAAAAAAAFU/PIAWsXNTpIE/s320/parade_doc_analyzed.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313482885690781522" /&gt;&lt;/a&gt;&lt;br /&gt;As you see script detected cloning of one tank, but did not detected cloning of tank in further row. This can be because of small size of that tank and because that tank is on boundary of image.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Experiments - object hiding forgery&lt;/b&gt;&lt;br /&gt;In this type of forgery viewer is deceived that there were less objects than in reality was.&lt;br /&gt;Original image:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_hTm-LSlj8U4/Sb1LIJMgVRI/AAAAAAAAAFc/qL7xTgvBylc/s1600-h/dune_org.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_hTm-LSlj8U4/Sb1LIJMgVRI/AAAAAAAAAFc/qL7xTgvBylc/s320/dune_org.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313485738646459666" /&gt;&lt;/a&gt;&lt;br /&gt;Doctored image:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/Sb1Ld0ZkH5I/AAAAAAAAAFk/DXXU35tkp6o/s1600-h/dune_doc.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/Sb1Ld0ZkH5I/AAAAAAAAAFk/DXXU35tkp6o/s320/dune_doc.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313486111021211538" /&gt;&lt;/a&gt;&lt;br /&gt;Copy-move script output:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_hTm-LSlj8U4/Sb1MJPD9IaI/AAAAAAAAAFs/ptuZLsTN11A/s1600-h/dune_doc_analyzed.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_hTm-LSlj8U4/Sb1MJPD9IaI/AAAAAAAAAFs/ptuZLsTN11A/s320/dune_doc_analyzed.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313486856912708002" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Experiments - mixed type forgery&lt;/b&gt;&lt;br /&gt;In this type of forgery some objects was hidden, some - cloned.&lt;br /&gt;Original picture:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/Sb1Nb85ImLI/AAAAAAAAAF0/VGFZPpNoRp4/s1600-h/dogs_org.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/Sb1Nb85ImLI/AAAAAAAAAF0/VGFZPpNoRp4/s320/dogs_org.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313488277964626098" /&gt;&lt;/a&gt;&lt;br /&gt;Doctored image:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/Sb1NlZ61hCI/AAAAAAAAAF8/8JH8K1FB1Hw/s1600-h/dogs_doc.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/Sb1NlZ61hCI/AAAAAAAAAF8/8JH8K1FB1Hw/s320/dogs_doc.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313488440375215138" /&gt;&lt;/a&gt;&lt;br /&gt;Copy-move script output:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/Sb1Nzw_jxlI/AAAAAAAAAGE/ePEP4LTOJ4g/s1600-h/dogs_doc_analyzed.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/Sb1Nzw_jxlI/AAAAAAAAAGE/ePEP4LTOJ4g/s320/dogs_doc_analyzed.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5313488687087208018" /&gt;&lt;/a&gt;&lt;br /&gt;As you see script detected 2 forgeries - cloning of dog, and cloning of background (which was done with intention to hide other dog)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusions&lt;/b&gt;&lt;br /&gt;Copy-move forgery detection script works not bad. However it is also not perfect of course (may not detect all tamperings, so called false negative rate is not zero of course). And I`ve not tested very well, but I suppose script also have false positive rate - i.e. can detect areas which actually was not tampered. But all in all - I think this algorithm is pretty obvious and can be simply implemented and used as first line of defense against copy-move forgeries.&lt;br /&gt;&lt;br /&gt;Have fun in copy-move forgeries hunting !!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-7382489815428621600?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/7382489815428621600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=7382489815428621600&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/7382489815428621600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/7382489815428621600'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2009/03/detecting-copy-move-forgery-in-images.html' title='Detecting copy-move forgery in images'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_hTm-LSlj8U4/Sb1HH5u5vxI/AAAAAAAAAFE/FVOBu956tK4/s72-c/parade_org.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-467893408170205033</id><published>2009-02-21T10:32:00.000-08:00</published><updated>2009-10-04T11:08:33.733-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='selfish gene algorithm'/><category scheme='http://www.blogger.com/atom/ns#' term='evolution strategy'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Evolving first lady of the internet</title><content type='html'>At last I ported &lt;a href="http://code.google.com/p/coding-experiments/source/browse/trunk/Python/sga.py"&gt;selfish gene algorithm&lt;/a&gt; into Python. This algorithm pseudo-code is:&lt;br /&gt;1. Encode some solution into set of genes.&lt;br /&gt;2. Set default probability for each gene.&lt;br /&gt;3. Generate 2 random solutions, according to genes probability.&lt;br /&gt;4. Compare these 2 solutions:&lt;br /&gt;  for better solution- increase it`s genes probability by some value&lt;br /&gt;  for worse solution- decrease it`s genes probability by some value&lt;br /&gt;5. Repeat everything from 3, until needed.&lt;br /&gt;&lt;br /&gt;Now, interesting part. What can we do with selfish gene algorithm ? After seeing &lt;a href="http://rogeralsing.com/2008/12/07/genetic-programming-evolution-of-mona-lisa/"&gt;this post&lt;/a&gt; about genetic programming and evolutionary art, I`ve decided to try something similar. But only by using selfish gene algorithm. I`ve tried 2 experiments - tried to evolve picture of &lt;a href="http://en.wikipedia.org/wiki/Lenna"&gt;first lady of the internet&lt;/a&gt; composed of polygons. And second experiment - lenna picture is evolved as some number of lines.&lt;br /&gt;So experiment idea is to generate 2 random images, composed of random polygons (or lines in other experiment) and to compare these 2 images. For image which is more similar to original lenna picture - we increase polygons probability, for other picture - decrease polygons probability. In the long run - "good polygons" tends to group together.&lt;br /&gt;Below are the results of these experiments. Evolved pictures of lenna are compiled as frames of animated GIF image. N - is the iteration number (starting from zero):&lt;br /&gt;&lt;b&gt;&lt;br /&gt;Lena evolved as set of polygons&lt;br /&gt;&lt;/b&gt;&lt;table style="width: 422px; height: 373px;" border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Original Lena&lt;/td&gt;&lt;td&gt;Lena evolution:&lt;br /&gt;39614 iterations&lt;br /&gt;100 polygons&lt;br /&gt;3.5 hours&lt;br /&gt;&lt;a href="http://code.google.com/p/coding-experiments/source/browse/trunk/Python/lena_poly.py"&gt;experiment code&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaC.png"&gt;&lt;img style="cursor: pointer; width: 200px; height: 200px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaC.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaPolyEvolution.gif"&gt;&lt;img style="cursor: pointer; width: 200px; height: 200px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaPolyEvolution.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lena evolved as set of lines&lt;/b&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Original Lena&lt;/td&gt;&lt;td&gt;Lena evolution:&lt;br /&gt;69471 iterations&lt;br /&gt;200 lines&lt;br /&gt;2.5 hours&lt;br /&gt;&lt;a href="http://code.google.com/p/coding-experiments/source/browse/trunk/Python/lena_line.py"&gt;experiment code&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaG.png"&gt;&lt;img style="cursor: pointer; width: 200px; height: 200px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaG.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaLineEvolution.gif"&gt;&lt;img style="cursor: pointer; width: 200px; height: 200px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaLineEvolution.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusions:&lt;/b&gt;&lt;br /&gt;Selfish gene algorithm (sort of evolution strategy algorithm) is suitable for solving search and optimization problems, including generation of evolutionary art :-)&lt;br /&gt;Below are final iteration pictures better quality than gif:&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaPolyFinal.png"&gt;&lt;img style="cursor: pointer; width: 200px; height: 200px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaPolyFinal.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaLineFinal.png"&gt;&lt;img style="cursor: pointer; width: 200px; height: 200px;" src="http://coding-experiments.googlecode.com/svn/trunk/Data/LenaLineFinal.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Have fun with selfish gene algorithm, genetic algorithms and evolution art !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-467893408170205033?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/467893408170205033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=467893408170205033&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/467893408170205033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/467893408170205033'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2009/02/evolving-first-lady-of-internet.html' title='Evolving first lady of the internet'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-7543776435044054226</id><published>2008-12-03T04:28:00.000-08:00</published><updated>2009-10-04T11:04:39.326-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dijkstra&apos;s algorithm'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><title type='text'>Project Euler p83 and Dijkstra's algorithm</title><content type='html'>Problem definition:&lt;br /&gt;-----------------------------------------------------------&lt;br /&gt;In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by moving left, right, up, and down, is indicated in bold and is equal to 2297.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;131&lt;/strong&gt; 673 &lt;strong&gt;234 &lt;/strong&gt;&lt;strong&gt;103 &lt;/strong&gt;&lt;strong&gt;18&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;201 &lt;/strong&gt;&lt;strong&gt;96 &lt;/strong&gt;&amp;nbsp;&lt;strong&gt;342 &lt;/strong&gt;965 &lt;strong&gt;150&lt;/strong&gt;&lt;br /&gt;630 803&amp;nbsp;746 &lt;strong&gt;422 &lt;/strong&gt;&lt;strong&gt;111&lt;/strong&gt;&lt;br /&gt;537 699&amp;nbsp;497 &lt;strong&gt;121 &lt;/strong&gt;956&lt;br /&gt;805 732&amp;nbsp;524 &lt;strong&gt;37 &lt;/strong&gt;&amp;nbsp;&lt;strong&gt;331&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Find the minimal path sum, in &lt;a href="http://projecteuler.net/project/matrix.txt"&gt;matrix.txt&lt;/a&gt; , a 31K text file containing a 80 by 80 matrix, from the top left to the bottom right by moving left, right, up, and down.&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------&lt;br /&gt;Problem is solved with the help of &lt;a href="http://en.wikipedia.org/wiki/Dijkstra's_algorithm"&gt;Dijkstra's algorithm&lt;/a&gt;&lt;br /&gt;Answer is calculated in a 2.5 seconds. Also it is not optimized,- computes distances to all nodes in network. To speed up - when we find target node - we can only check these nodes which distance is less than target node distance. Also this code suits equally well for solving project euler problem no 81 - only change shortestpath() function parameter "directions". And finally - this solution shows shortest path visually,- prints it to screen. Program code:&lt;br /&gt;___________________________________________________________&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;&lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;time&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;as&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;t&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;readmatrix&lt;/span&gt;(filename):&lt;br /&gt;    f&lt;span style="color: #666666"&gt;=&lt;/span&gt;&lt;span style="color: #007020"&gt;open&lt;/span&gt;(filename, &lt;span style="color: #4070a0"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;)&lt;br /&gt;    m&lt;span style="color: #666666"&gt;=&lt;/span&gt;[&lt;span style="color: #007020"&gt;map&lt;/span&gt;(&lt;span style="color: #007020; font-weight: bold"&gt;lambda&lt;/span&gt; x: &lt;span style="color: #007020"&gt;int&lt;/span&gt;(x),r&lt;span style="color: #666666"&gt;.&lt;/span&gt;strip()&lt;span style="color: #666666"&gt;.&lt;/span&gt;split(&lt;span style="color: #4070a0"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;)) &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; r &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; f&lt;span style="color: #666666"&gt;.&lt;/span&gt;readlines()]&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; m&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;nextcell&lt;/span&gt;(dctresults):&lt;br /&gt;    minw &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;10000000&lt;/span&gt;&lt;br /&gt;    mink &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;None&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; k &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; dctresults:&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;not&lt;/span&gt; dctresults[k][&lt;span style="color: #40a070"&gt;2&lt;/span&gt;]:&lt;br /&gt;            &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; dctresults[k][&lt;span style="color: #40a070"&gt;1&lt;/span&gt;] &lt;span style="color: #666666"&gt;&amp;lt;&lt;/span&gt; minw:&lt;br /&gt;                minw &lt;span style="color: #666666"&gt;=&lt;/span&gt; dctresults[k][&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;br /&gt;                mink &lt;span style="color: #666666"&gt;=&lt;/span&gt; k&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; mink&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;analyzecell&lt;/span&gt;(lstmat, tupcell, lstdirec, dctresults):&lt;br /&gt;    i,j &lt;span style="color: #666666"&gt;=&lt;/span&gt; tupcell&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; dr &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; lstdirec:&lt;br /&gt;        di,dj &lt;span style="color: #666666"&gt;=&lt;/span&gt; dr&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; (i&lt;span style="color: #666666"&gt;+&lt;/span&gt;di) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(lstmat)) &lt;span style="color: #007020; font-weight: bold"&gt;and&lt;/span&gt; (j&lt;span style="color: #666666"&gt;+&lt;/span&gt;dj) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(lstmat)):&lt;br /&gt;            &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;not&lt;/span&gt; dctresults&lt;span style="color: #666666"&gt;.&lt;/span&gt;has_key((i&lt;span style="color: #666666"&gt;+&lt;/span&gt;di,j&lt;span style="color: #666666"&gt;+&lt;/span&gt;dj)):&lt;br /&gt;                dctresults[(i&lt;span style="color: #666666"&gt;+&lt;/span&gt;di,j&lt;span style="color: #666666"&gt;+&lt;/span&gt;dj)] &lt;span style="color: #666666"&gt;=&lt;/span&gt; [(i,j),dctresults[(i,j)][&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;span style="color: #666666"&gt;+&lt;/span&gt;lstmat[i&lt;span style="color: #666666"&gt;+&lt;/span&gt;di][j&lt;span style="color: #666666"&gt;+&lt;/span&gt;dj],&lt;span style="color: #007020"&gt;False&lt;/span&gt;]&lt;br /&gt;            &lt;span style="color: #007020; font-weight: bold"&gt;else&lt;/span&gt;:&lt;br /&gt;                oldw &lt;span style="color: #666666"&gt;=&lt;/span&gt; dctresults[(i&lt;span style="color: #666666"&gt;+&lt;/span&gt;di,j&lt;span style="color: #666666"&gt;+&lt;/span&gt;dj)][&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;br /&gt;                neww &lt;span style="color: #666666"&gt;=&lt;/span&gt; dctresults[(i,j)][&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;span style="color: #666666"&gt;+&lt;/span&gt;lstmat[i&lt;span style="color: #666666"&gt;+&lt;/span&gt;di][j&lt;span style="color: #666666"&gt;+&lt;/span&gt;dj]&lt;br /&gt;                &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; neww &lt;span style="color: #666666"&gt;&amp;lt;&lt;/span&gt; oldw:&lt;br /&gt;                    dctresults[(i&lt;span style="color: #666666"&gt;+&lt;/span&gt;di,j&lt;span style="color: #666666"&gt;+&lt;/span&gt;dj)][&lt;span style="color: #40a070"&gt;0&lt;/span&gt;] &lt;span style="color: #666666"&gt;=&lt;/span&gt; (i,j)&lt;br /&gt;                    dctresults[(i&lt;span style="color: #666666"&gt;+&lt;/span&gt;di,j&lt;span style="color: #666666"&gt;+&lt;/span&gt;dj)][&lt;span style="color: #40a070"&gt;1&lt;/span&gt;] &lt;span style="color: #666666"&gt;=&lt;/span&gt; neww&lt;br /&gt;    dctresults[(i,j)][&lt;span style="color: #40a070"&gt;2&lt;/span&gt;] &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;True&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;shortestpath&lt;/span&gt;(filename, directions):&lt;br /&gt;    mat &lt;span style="color: #666666"&gt;=&lt;/span&gt; readmatrix(filename)&lt;br /&gt;    results &lt;span style="color: #666666"&gt;=&lt;/span&gt; {}&lt;br /&gt;    results[(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;,&lt;span style="color: #40a070"&gt;0&lt;/span&gt;)] &lt;span style="color: #666666"&gt;=&lt;/span&gt; [&lt;span style="color: #007020"&gt;None&lt;/span&gt;,mat[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;][&lt;span style="color: #40a070"&gt;0&lt;/span&gt;],&lt;span style="color: #007020"&gt;False&lt;/span&gt;]&lt;br /&gt;    cell &lt;span style="color: #666666"&gt;=&lt;/span&gt; nextcell(results)&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;while&lt;/span&gt; cell:&lt;br /&gt;        analyzecell(mat,cell,directions,results)&lt;br /&gt;        cell &lt;span style="color: #666666"&gt;=&lt;/span&gt; nextcell(results)&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; results, results[(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(mat)&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;,&lt;span style="color: #007020"&gt;len&lt;/span&gt;(mat)&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)][&lt;span style="color: #40a070"&gt;1&lt;/span&gt;], mat&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;showpath&lt;/span&gt;(res, inpmat):&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #007020"&gt;len&lt;/span&gt;(inpmat)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;br /&gt;    pathcells &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt;    curc &lt;span style="color: #666666"&gt;=&lt;/span&gt; (&lt;span style="color: #007020"&gt;len&lt;/span&gt;(inpmat)&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;,&lt;span style="color: #007020"&gt;len&lt;/span&gt;(inpmat)&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;while&lt;/span&gt; curc:&lt;br /&gt;        pathcells &lt;span style="color: #666666"&gt;+=&lt;/span&gt; [curc]&lt;br /&gt;        curc &lt;span style="color: #666666"&gt;=&lt;/span&gt; res[curc][&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; i &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(inpmat)):&lt;br /&gt;        s&lt;span style="color: #666666"&gt;=&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;#39;|&amp;#39;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; j &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(inpmat)):&lt;br /&gt;            s&lt;span style="color: #666666"&gt;+=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;#&amp;#39;&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; (i,j) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; pathcells &lt;span style="color: #007020; font-weight: bold"&gt;else&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; s&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;#39;|&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #007020"&gt;len&lt;/span&gt;(inpmat)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;t1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; t&lt;span style="color: #666666"&gt;.&lt;/span&gt;time()&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #40a070"&gt;1000&lt;/span&gt;&lt;br /&gt;resd, pathsum, mat &lt;span style="color: #666666"&gt;=&lt;/span&gt; shortestpath(&lt;span style="color: #4070a0"&gt;&amp;#39;matrix.txt&amp;#39;&lt;/span&gt;,[(&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;,&lt;span style="color: #40a070"&gt;0&lt;/span&gt;),(&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;,&lt;span style="color: #40a070"&gt;0&lt;/span&gt;),(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;,&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;),(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;,&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)])&lt;br /&gt;t2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; t&lt;span style="color: #666666"&gt;.&lt;/span&gt;time()&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #40a070"&gt;1000&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;Shortest path sum&amp;#39;&lt;/span&gt;, pathsum, &lt;span style="color: #4070a0"&gt;&amp;#39;; Calculation time is &amp;#39;&lt;/span&gt;, &lt;span style="color: #007020"&gt;int&lt;/span&gt;(t2&lt;span style="color: #666666"&gt;-&lt;/span&gt;t1), &lt;span style="color: #4070a0"&gt;&amp;#39;ms&amp;#39;&lt;/span&gt;&lt;br /&gt;showpath(resd, mat)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;___________________________________________________________&lt;br /&gt;Have fun with shortest path algorithms !!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-7543776435044054226?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/7543776435044054226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=7543776435044054226&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/7543776435044054226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/7543776435044054226'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/12/project-euler-p83-and-dijkstras.html' title='Project Euler p83 and Dijkstra&apos;s algorithm'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-4347580285949059623</id><published>2008-11-11T09:30:00.000-08:00</published><updated>2009-10-04T11:01:12.151-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><title type='text'>Project Euler p92</title><content type='html'>Problem description:&lt;br /&gt;-------------------------------------------------------------------&lt;br /&gt;A number chain is created by continuously adding the square of the digits in a number to form a new number until it has been seen before.&lt;br /&gt;&lt;br /&gt;For example,&lt;br /&gt;&lt;br /&gt;44 -&gt; 32 -&gt; 13 -&gt; 10 -&gt; &lt;span style="font-weight:bold;"&gt;1&lt;/span&gt; -&gt; &lt;span style="font-weight:bold;"&gt;1&lt;/span&gt;&lt;br /&gt;85 -&gt; &lt;span style="font-weight:bold;"&gt;89&lt;/span&gt; -&gt; 145 -&gt; 42 -&gt; 20 -&gt; 4 -&gt; 16 -&gt; 37 -&gt; 58 -&gt; &lt;span style="font-weight:bold;"&gt;89&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Therefore any chain that arrives at 1 or 89 will become stuck in an endless loop. What is most amazing is that EVERY starting number will eventually arrive at 1 or 89.&lt;br /&gt;&lt;br /&gt;How many starting numbers below ten million will arrive at 89?&lt;br /&gt;-------------------------------------------------------------------&lt;br /&gt;Semi-bruteforce algorithm based on idea that we don`t need to construct full number chains from starting number until 1 or 89. Instead we will save in memory each starting number final result (1 or 89). And at the next starting number we will construct number chain only until previous calculated number.&lt;br /&gt;Well solution is slow, but fits in "one minute rule" :-). Here it is-&lt;br /&gt;_____________________________________________________________&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;&lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;time&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;as&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;t&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;nextnum&lt;/span&gt;(number):&lt;br /&gt; n &lt;span style="color: #666666"&gt;=&lt;/span&gt; number&lt;br /&gt; s &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;0&lt;/span&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;while&lt;/span&gt; n&lt;span style="color: #666666"&gt;!=&lt;/span&gt;&lt;span style="color: #40a070"&gt;0&lt;/span&gt;:&lt;br /&gt;  m &lt;span style="color: #666666"&gt;=&lt;/span&gt; n&lt;span style="color: #666666"&gt;%&lt;/span&gt;&lt;span style="color: #40a070"&gt;10&lt;/span&gt;&lt;br /&gt;  n &lt;span style="color: #666666"&gt;=&lt;/span&gt; n&lt;span style="color: #666666"&gt;/&lt;/span&gt;&lt;span style="color: #40a070"&gt;10&lt;/span&gt;&lt;br /&gt;  s &lt;span style="color: #666666"&gt;+=&lt;/span&gt; m&lt;span style="color: #666666"&gt;*&lt;/span&gt;m&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; s&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;untilknown&lt;/span&gt;(number):&lt;br /&gt;    start &lt;span style="color: #666666"&gt;=&lt;/span&gt; number&lt;br /&gt;    res &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;while&lt;/span&gt; start &lt;span style="color: #666666"&gt;&amp;gt;=&lt;/span&gt; number &lt;span style="color: #007020; font-weight: bold"&gt;and&lt;/span&gt; start &lt;span style="color: #007020; font-weight: bold"&gt;not&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; (&lt;span style="color: #40a070"&gt;1&lt;/span&gt;,&lt;span style="color: #40a070"&gt;89&lt;/span&gt;):&lt;br /&gt;        start &lt;span style="color: #666666"&gt;=&lt;/span&gt; nextnum(start)&lt;br /&gt;        res &lt;span style="color: #666666"&gt;+=&lt;/span&gt; [start]&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; res&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;endswith89&lt;/span&gt;(limit):&lt;br /&gt;    seq &lt;span style="color: #666666"&gt;=&lt;/span&gt; {&lt;span style="color: #40a070"&gt;1&lt;/span&gt;:&lt;span style="color: #40a070"&gt;1&lt;/span&gt;,&lt;span style="color: #40a070"&gt;89&lt;/span&gt;:&lt;span style="color: #40a070"&gt;89&lt;/span&gt;}&lt;br /&gt;    ret &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;0&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; x &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #40a070"&gt;1&lt;/span&gt;,limit):&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;not&lt;/span&gt; seq&lt;span style="color: #666666"&gt;.&lt;/span&gt;has_key(x):&lt;br /&gt;            k &lt;span style="color: #666666"&gt;=&lt;/span&gt; untilknown(x)&lt;br /&gt;            &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; k:&lt;br /&gt;                kk &lt;span style="color: #666666"&gt;=&lt;/span&gt; k[&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;br /&gt;            &lt;span style="color: #007020; font-weight: bold"&gt;else&lt;/span&gt;:&lt;br /&gt;                kk &lt;span style="color: #666666"&gt;=&lt;/span&gt; x&lt;br /&gt;            seq[x] &lt;span style="color: #666666"&gt;=&lt;/span&gt; seq[kk]&lt;br /&gt;            &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #007020"&gt;len&lt;/span&gt;(k) &lt;span style="color: #666666"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #40a070"&gt;1&lt;/span&gt;:&lt;br /&gt;                &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; i &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(k)&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;):&lt;br /&gt;                    seq[k[i]] &lt;span style="color: #666666"&gt;=&lt;/span&gt; seq[kk]&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; seq[x] &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #40a070"&gt;89&lt;/span&gt;:&lt;br /&gt;            ret &lt;span style="color: #666666"&gt;+=&lt;/span&gt; &lt;span style="color: #40a070"&gt;1&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; ret&lt;br /&gt;&lt;br /&gt;t1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; t&lt;span style="color: #666666"&gt;.&lt;/span&gt;time()&lt;br /&gt;ans &lt;span style="color: #666666"&gt;=&lt;/span&gt; endswith89(&lt;span style="color: #40a070"&gt;10000000&lt;/span&gt;)&lt;br /&gt;t2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; t&lt;span style="color: #666666"&gt;.&lt;/span&gt;time()&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; ans, &lt;span style="color: #007020"&gt;int&lt;/span&gt;(t2&lt;span style="color: #666666"&gt;-&lt;/span&gt;t1),&lt;span style="color: #4070a0"&gt;&amp;#39;s&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;_____________________________________________________________&lt;br /&gt;&lt;br /&gt;Have fun !!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-4347580285949059623?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/4347580285949059623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=4347580285949059623&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/4347580285949059623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/4347580285949059623'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/11/project-euler-p92.html' title='Project Euler p92'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-8481574984945289700</id><published>2008-10-27T04:12:00.000-07:00</published><updated>2009-10-04T10:57:52.698-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><title type='text'>Project Euler p99</title><content type='html'>Project Euler problem 99 description:&lt;br /&gt;------------------------------------------------------------------------&lt;br /&gt;Comparing two numbers written in index form like 2^11 and 3^7 is not difficult, as any calculator would confirm that 2^11 = 2048 &lt; 3^7 = 2187.&lt;br /&gt;&lt;br /&gt;However, confirming that 632382^518061 &gt; 519432^525806 would be much more difficult, as both numbers contain over three million digits.&lt;br /&gt;&lt;br /&gt;Using &lt;a href="http://projecteuler.net/project/base_exp.txt"&gt;base_exp.txt&lt;/a&gt; (right click and 'Save Link/Target As...'), a 22K text file containing one thousand lines with a base/exponent pair on each line, determine which line number has the greatest numerical value.&lt;br /&gt;&lt;br /&gt;NOTE: The first two lines in the file represent the numbers in the example given above.&lt;br /&gt;------------------------------------------------------------------------&lt;br /&gt;The trick of solution is not to compare whole numbers (because raising to power will be too much CPU time and memory consuming operation), instead we can compare logarithms of numbers. So actually we will compare LOG(number^power). Ok, but we still have to do power operation ? Well, no more ! By applying known logarithm formula: LOG(number^power) = power*LOG(number). So we are comparing &lt;span style="font-weight:bold;"&gt;power*LOG(number)&lt;/span&gt;. This is very fast operation.&lt;br /&gt;Problem solution is found in a 3.7 ms. Solution Python code:&lt;br /&gt;_____________________________________________________&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;&lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;time&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;as&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;tm&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;math&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;as&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;m&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;t1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; tm&lt;span style="color: #666666"&gt;.&lt;/span&gt;time()&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #40a070"&gt;1000&lt;/span&gt;&lt;br /&gt;f&lt;span style="color: #666666"&gt;=&lt;/span&gt;&lt;span style="color: #007020"&gt;open&lt;/span&gt;(&lt;span style="color: #4070a0"&gt;&amp;#39;base_exp.txt&amp;#39;&lt;/span&gt;, &lt;span style="color: #4070a0"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;)&lt;br /&gt;l&lt;span style="color: #666666"&gt;=&lt;/span&gt;[i&lt;span style="color: #666666"&gt;.&lt;/span&gt;strip()&lt;span style="color: #666666"&gt;.&lt;/span&gt;split(&lt;span style="color: #4070a0"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;)&lt;span style="color: #666666"&gt;+&lt;/span&gt;[n&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;] &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; (n,i) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;enumerate&lt;/span&gt;(f&lt;span style="color: #666666"&gt;.&lt;/span&gt;readlines())]&lt;br /&gt;l &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;map&lt;/span&gt;(&lt;span style="color: #007020; font-weight: bold"&gt;lambda&lt;/span&gt; i: (&lt;span style="color: #007020"&gt;int&lt;/span&gt;(i[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]),&lt;span style="color: #007020"&gt;int&lt;/span&gt;(i[&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]), i[&lt;span style="color: #40a070"&gt;2&lt;/span&gt;]), l)&lt;br /&gt;l &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;map&lt;/span&gt;(&lt;span style="color: #007020; font-weight: bold"&gt;lambda&lt;/span&gt; (x,a,n): (a&lt;span style="color: #666666"&gt;*&lt;/span&gt;m&lt;span style="color: #666666"&gt;.&lt;/span&gt;log(x), n), l)&lt;br /&gt;&lt;span style="color: #007020"&gt;max&lt;/span&gt; &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;max&lt;/span&gt;(l)&lt;br /&gt;t2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; tm&lt;span style="color: #666666"&gt;.&lt;/span&gt;time()&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #40a070"&gt;1000&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; &lt;span style="color: #007020"&gt;max&lt;/span&gt;,t2&lt;span style="color: #666666"&gt;-&lt;/span&gt;t1,&lt;span style="color: #4070a0"&gt;&amp;#39;ms&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;________________________________________________________&lt;br /&gt;Have fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-8481574984945289700?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/8481574984945289700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=8481574984945289700&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/8481574984945289700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/8481574984945289700'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/10/project-euler-p99.html' title='Project Euler p99'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-6993698570734208601</id><published>2008-10-11T10:29:00.000-07:00</published><updated>2009-10-04T10:55:00.537-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Pi'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Calculation of Pi</title><content type='html'>This time I tried to answer a question - what is the best method of &lt;a href="http://en.wikipedia.org/wiki/Pi"&gt;calculating Pi&lt;/a&gt; to a required accuracy - for example,- 100 or 1000 or 10 000 decimal digits ?&lt;br /&gt;So I chose 4 Pi formulas for testing:&lt;br /&gt;1. &lt;a href="http://en.wikipedia.org/wiki/Leibniz_formula_for_pi"&gt;Leibniz&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://en.wikipedia.org/wiki/Madhava_of_Sangamagrama#The_value_of_.CF.80_.28pi.29"&gt;Madhava&lt;/a&gt; transformed series&lt;br /&gt;3. &lt;a href="http://en.wikipedia.org/wiki/Machin-like_formula"&gt;Machin like formula&lt;/a&gt;&lt;br /&gt;4. &lt;a href="http://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_algorithm"&gt;Gauss algorithm&lt;/a&gt;&lt;br /&gt;The idea for experiment - is to find out which algorithm gives more decimal digits of Pi in same number of iterations/terms. So measurement algorithm is this:&lt;br /&gt;1. Calculate correct digits of Pi given from every Pi formula in each iteration.&lt;br /&gt;2. Plot diagram - correct Pi decimal digits amount VS iteration number&lt;br /&gt;(For this to work - you must have Matplotlib module).&lt;br /&gt;Python code doing this stuff:&lt;br /&gt;_____________________________________________________&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;&lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;inspect&lt;/span&gt;&lt;span style="color: #666666"&gt;,&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;time&lt;/span&gt;&lt;span style="color: #666666"&gt;,&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;decimal&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; Decimal, getcontext&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;pylab&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; plot,  show,  xlabel,  ylabel,  title,  grid,  legend&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;correct_digits&lt;/span&gt;(calcpi):&lt;br /&gt; pi &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;quot;3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989&amp;quot;&lt;/span&gt;&lt;br /&gt; gd &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;1000&lt;/span&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; i,s &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;enumerate&lt;/span&gt;(&lt;span style="color: #007020"&gt;zip&lt;/span&gt;(pi,&lt;span style="color: #007020"&gt;str&lt;/span&gt;(calcpi))):&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; s[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;] &lt;span style="color: #666666"&gt;!=&lt;/span&gt; s[&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]:&lt;br /&gt;   gd &lt;span style="color: #666666"&gt;=&lt;/span&gt; i &lt;span style="color: #666666"&gt;-&lt;/span&gt; &lt;span style="color: #40a070"&gt;2&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; gd &lt;span style="color: #666666"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: #40a070"&gt;0&lt;/span&gt;: gd &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;0&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: #007020; font-weight: bold"&gt;break&lt;/span&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; gd&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;show_results&lt;/span&gt;(res):&lt;br /&gt; x&lt;span style="color: #666666"&gt;=&lt;/span&gt;&lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(res[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;][&lt;span style="color: #40a070"&gt;2&lt;/span&gt;]))&lt;br /&gt; plpar &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; legpar &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; i &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(res)):&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; plpar: plpar &lt;span style="color: #666666"&gt;+=&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; legpar: legpar &lt;span style="color: #666666"&gt;+=&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;&lt;br /&gt;  plpar &lt;span style="color: #666666"&gt;+=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;quot;x, res[&amp;quot;&lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(i)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;quot;][2]&amp;quot;&lt;/span&gt;&lt;br /&gt;  legpar &lt;span style="color: #666666"&gt;+=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;quot;res[&amp;quot;&lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(i)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;quot;][0][3:] +&amp;#39; (&amp;#39;+ str(int(res[&amp;quot;&lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(i)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;quot;][1])) + &amp;#39;ms)&amp;#39;&amp;quot;&lt;/span&gt;&lt;br /&gt; plpar &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;quot;plot(&amp;quot;&lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;plpar&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;quot;, linewidth=2.0)&amp;quot;&lt;/span&gt;&lt;br /&gt; legpar &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;quot;legend((&amp;quot;&lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;legpar&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;quot;), loc=0)&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;exec&lt;/span&gt;(plpar)&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;exec&lt;/span&gt;(legpar)&lt;br /&gt; xlabel(&lt;span style="color: #4070a0"&gt;&amp;#39;Iterations&amp;#39;&lt;/span&gt;, fontsize &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;15&lt;/span&gt;)&lt;br /&gt; ylabel(&lt;span style="color: #4070a0"&gt;&amp;#39;Correct digits&amp;#39;&lt;/span&gt;, fontsize &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;15&lt;/span&gt;)&lt;br /&gt; title(&lt;span style="color: #4070a0"&gt;&amp;quot;Convergence of some $\pi$ formulas&amp;quot;&lt;/span&gt;,fontsize&lt;span style="color: #666666"&gt;=&lt;/span&gt;&lt;span style="color: #40a070"&gt;20&lt;/span&gt;)&lt;br /&gt; grid()&lt;br /&gt; show()&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;test_pi_formulas&lt;/span&gt;(pi_func_list):&lt;br /&gt;    res &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt;    terms &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;6&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;Calculating &lt;/span&gt;&lt;span style="color: #70a0d0; font-style: italic"&gt;%d&lt;/span&gt;&lt;span style="color: #4070a0"&gt; iterations...&amp;#39;&lt;/span&gt; &lt;span style="color: #666666"&gt;%&lt;/span&gt; terms&lt;br /&gt;    getcontext()&lt;span style="color: #666666"&gt;.&lt;/span&gt;prec &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;1002&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; pif &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; pi_func_list:&lt;br /&gt;        t1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; time&lt;span style="color: #666666"&gt;.&lt;/span&gt;time()&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #40a070"&gt;1000&lt;/span&gt;&lt;br /&gt;        name,r &lt;span style="color: #666666"&gt;=&lt;/span&gt; pif(terms)&lt;br /&gt;        t2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; time&lt;span style="color: #666666"&gt;.&lt;/span&gt;time()&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #40a070"&gt;1000&lt;/span&gt;&lt;br /&gt;        res&lt;span style="color: #666666"&gt;.&lt;/span&gt;append((name,t2&lt;span style="color: #666666"&gt;-&lt;/span&gt;t1,r))&lt;br /&gt;    show_results(res)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;pi_Leibniz&lt;/span&gt;(terms):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; http://en.wikipedia.org/wiki/Leibniz_formula_for_pi&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; st &lt;span style="color: #666666"&gt;=&lt;/span&gt; inspect&lt;span style="color: #666666"&gt;.&lt;/span&gt;stack()[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;][&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]&lt;br /&gt; ra &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;)&lt;br /&gt; ans &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; n &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(terms):&lt;br /&gt;  ra &lt;span style="color: #666666"&gt;+=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;4&lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;(&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;span style="color: #666666"&gt;**&lt;/span&gt;n)&lt;span style="color: #666666"&gt;/&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;n&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;br /&gt;  ans&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(correct_digits(ra))&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; st,ans&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;pi_Madhava&lt;/span&gt;(terms):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; http://en.wikipedia.org/wiki/Madhava_of_Sangamagrama#The_value_of_.CF.80_.28pi.29&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; st &lt;span style="color: #666666"&gt;=&lt;/span&gt; inspect&lt;span style="color: #666666"&gt;.&lt;/span&gt;stack()[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;][&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]&lt;br /&gt; ra &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;)&lt;br /&gt; k &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;12&lt;/span&gt;)&lt;span style="color: #666666"&gt;**&lt;/span&gt;Decimal(&lt;span style="color: #4070a0"&gt;&amp;#39;0.5&amp;#39;&lt;/span&gt;)&lt;br /&gt; ans &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; n &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(terms):&lt;br /&gt;  ra &lt;span style="color: #666666"&gt;+=&lt;/span&gt; Decimal((&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;span style="color: #666666"&gt;**&lt;/span&gt;n)&lt;span style="color: #666666"&gt;/&lt;/span&gt;Decimal((&lt;span style="color: #40a070"&gt;2&lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;n&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;span style="color: #666666"&gt;*&lt;/span&gt;(&lt;span style="color: #40a070"&gt;3&lt;/span&gt;&lt;span style="color: #666666"&gt;**&lt;/span&gt;n))&lt;br /&gt;  ans&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(correct_digits(k&lt;span style="color: #666666"&gt;*&lt;/span&gt;ra))&lt;br /&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; st, ans&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;pi_Machin&lt;/span&gt;(terms):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; http://en.wikipedia.org/wiki/Machin-like_formula&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; st &lt;span style="color: #666666"&gt;=&lt;/span&gt; inspect&lt;span style="color: #666666"&gt;.&lt;/span&gt;stack()[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;][&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]&lt;br /&gt; c1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;span style="color: #666666"&gt;/&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;5&lt;/span&gt;)&lt;br /&gt; c2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;span style="color: #666666"&gt;/&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;239&lt;/span&gt;)&lt;br /&gt; a &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;4&lt;/span&gt;)&lt;br /&gt; atan1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;)&lt;br /&gt; atan2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;)&lt;br /&gt; ra &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;)&lt;br /&gt; ans &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; n &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(terms):&lt;br /&gt;  atan1 &lt;span style="color: #666666"&gt;+=&lt;/span&gt; Decimal((&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;span style="color: #666666"&gt;**&lt;/span&gt;n) &lt;span style="color: #666666"&gt;*&lt;/span&gt; (c1&lt;span style="color: #666666"&gt;**&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;n&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;))&lt;span style="color: #666666"&gt;/&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;n&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;br /&gt;  atan2 &lt;span style="color: #666666"&gt;+=&lt;/span&gt; Decimal((&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;span style="color: #666666"&gt;**&lt;/span&gt;n) &lt;span style="color: #666666"&gt;*&lt;/span&gt; (c2&lt;span style="color: #666666"&gt;**&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;n&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;))&lt;span style="color: #666666"&gt;/&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;&lt;span style="color: #666666"&gt;*&lt;/span&gt;n&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;br /&gt;  ra &lt;span style="color: #666666"&gt;=&lt;/span&gt; a &lt;span style="color: #666666"&gt;*&lt;/span&gt; (a&lt;span style="color: #666666"&gt;*&lt;/span&gt;atan1 &lt;span style="color: #666666"&gt;-&lt;/span&gt; atan2)&lt;br /&gt;  ans&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(correct_digits(ra))&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; st, ans&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;pi_Gauss&lt;/span&gt;(terms):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; http://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_algorithm&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; st &lt;span style="color: #666666"&gt;=&lt;/span&gt; inspect&lt;span style="color: #666666"&gt;.&lt;/span&gt;stack()[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;][&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]&lt;br /&gt; one &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)&lt;br /&gt; ra &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;)&lt;br /&gt; val &lt;span style="color: #666666"&gt;=&lt;/span&gt; (one,one&lt;span style="color: #666666"&gt;/&lt;/span&gt;(Decimal(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;span style="color: #666666"&gt;**&lt;/span&gt;Decimal(&lt;span style="color: #4070a0"&gt;&amp;#39;0.5&amp;#39;&lt;/span&gt;)),one&lt;span style="color: #666666"&gt;/&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;4&lt;/span&gt;),one)&lt;br /&gt; ans &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; n &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(terms):&lt;br /&gt;  an, bn, tn, pn &lt;span style="color: #666666"&gt;=&lt;/span&gt; val&lt;br /&gt;  an1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; (an&lt;span style="color: #666666"&gt;+&lt;/span&gt;bn)&lt;span style="color: #666666"&gt;/&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;br /&gt;  bn1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; (an&lt;span style="color: #666666"&gt;*&lt;/span&gt;bn)&lt;span style="color: #666666"&gt;**&lt;/span&gt;Decimal(&lt;span style="color: #4070a0"&gt;&amp;#39;0.5&amp;#39;&lt;/span&gt;)&lt;br /&gt;  tn1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; tn &lt;span style="color: #666666"&gt;-&lt;/span&gt; pn &lt;span style="color: #666666"&gt;*&lt;/span&gt; (an &lt;span style="color: #666666"&gt;-&lt;/span&gt; an1)&lt;span style="color: #666666"&gt;**&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;br /&gt;  pn1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; Decimal(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;) &lt;span style="color: #666666"&gt;*&lt;/span&gt; pn&lt;br /&gt;  val &lt;span style="color: #666666"&gt;=&lt;/span&gt; (an1, bn1, tn1, pn1)&lt;br /&gt;  ra &lt;span style="color: #666666"&gt;=&lt;/span&gt; ((an&lt;span style="color: #666666"&gt;+&lt;/span&gt;bn)&lt;span style="color: #666666"&gt;**&lt;/span&gt;Decimal(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;))&lt;span style="color: #666666"&gt;/&lt;/span&gt;(Decimal(&lt;span style="color: #40a070"&gt;4&lt;/span&gt;)&lt;span style="color: #666666"&gt;*&lt;/span&gt;tn)&lt;br /&gt;  ans&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(correct_digits(ra))&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; st, ans&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; __name__ &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;:&lt;br /&gt; mod &lt;span style="color: #666666"&gt;=&lt;/span&gt; sys&lt;span style="color: #666666"&gt;.&lt;/span&gt;modules[__name__]&lt;br /&gt; pifunc &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; key, value &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; mod&lt;span style="color: #666666"&gt;.&lt;/span&gt;__dict__&lt;span style="color: #666666"&gt;.&lt;/span&gt;items():&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #007020"&gt;str&lt;/span&gt;(value)[:&lt;span style="color: #40a070"&gt;13&lt;/span&gt;] &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;&amp;lt;function pi_&amp;#39;&lt;/span&gt;:&lt;br /&gt;   pifunc&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(value)&lt;br /&gt; test_pi_formulas(pifunc)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;_____________________________________________________&lt;br /&gt;BTW this code is very scalable - if there is a need to test additional Pi formula - you only need to add new Pi function code like this:&lt;br /&gt;"def pi_new_required_function(terms):&lt;br /&gt;[...]". (Function name MUST begin with "pi_"). The rest program will do it for you - measure execution times, measure decimal digits correctness, plot results...&lt;br /&gt;This is thanks to Python reflection used in program -&gt; program scans itself for ALL pi functions and dynamically invokes them.&lt;br /&gt;&lt;br /&gt;So after execution of this test we get such graph:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_hTm-LSlj8U4/SPD2rLxFZXI/AAAAAAAAAD0/G-dTh9RClr8/s1600-h/pi.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_hTm-LSlj8U4/SPD2rLxFZXI/AAAAAAAAAD0/G-dTh9RClr8/s320/pi.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5255971986894841202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;From graph can be seen that fastest converges Gauss Pi algorithm (from the chosen set of Pi formulas). So if you need for some reason to calculate Pi in desired accuracy (desired decimal places amount) I suggest Gauss algorithm. Because you will get result in less iterations / CPU cycles compared with other algorithms from the set.&lt;br /&gt;&lt;br /&gt;Have fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-6993698570734208601?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/6993698570734208601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=6993698570734208601&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/6993698570734208601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/6993698570734208601'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/10/calculation-of-pi.html' title='Calculation of Pi'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_hTm-LSlj8U4/SPD2rLxFZXI/AAAAAAAAAD0/G-dTh9RClr8/s72-c/pi.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-445072994115237621</id><published>2008-09-21T12:33:00.000-07:00</published><updated>2009-10-04T10:51:37.336-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='image processing'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Detecting similar color zones in image</title><content type='html'>After analyzing &lt;a href="http://coding-experiments.blogspot.com/2008/09/finding-similar-parts-in-image.html"&gt;information entropy&lt;/a&gt; in image I started to think - what will be if we hash image not by it`s total entropy, but instead- by some other cumulative function ? After several tries, I found this hashing function interesting-&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/SNawd5-7kAI/AAAAAAAAACo/wtGBx0jyHZA/s1600-h/colf.jpeg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/SNawd5-7kAI/AAAAAAAAACo/wtGBx0jyHZA/s200/colf.jpeg" border="0" alt=""id="BLOGGER_PHOTO_ID_5248576443574358018" /&gt;&lt;/a&gt;&lt;br /&gt;Where Ir,Ig,Ib - pixel value in red,green,blue channels respectively and N is number of pixels in image.&lt;br /&gt;Python code doing this stuff of image zones comparision is very similar to the previous mentioned (information entropy) article code. It only differs on 2 aspects:&lt;br /&gt;- Now we compare image blocks by above mentioned hash function&lt;br /&gt;- There is no code of grouping image blocks.&lt;br /&gt;Pseudo code of algorithm:&lt;br /&gt;1. Split given image into 4x4 small image blocks.&lt;br /&gt;2. Calculate color hash of each block.&lt;br /&gt;3. Find blocks with similar hash value&lt;br /&gt;4. Draw these blocks on top of original image as green color layer&lt;br /&gt;Python code, which does that:&lt;br /&gt;_______________________________________________________&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;&lt;span style="color: #007020; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;PIL&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; Image&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;math&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;colorhash&lt;/span&gt;(pixels):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; Calculating color hash by summing&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; intensity levels in all 3 channels&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; separatelly and multiplying these&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; accumulated intensities together&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; also dividing by cube of pixel amount.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;br /&gt; cr &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;sum&lt;/span&gt;([r &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; (r,g,b) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; pixels])&lt;br /&gt; cg &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;sum&lt;/span&gt;([g &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; (r,g,b) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; pixels])&lt;br /&gt; cb &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;sum&lt;/span&gt;([b &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; (r,g,b) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; pixels])&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; ((cr&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;) &lt;span style="color: #666666"&gt;*&lt;/span&gt; (cg&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;) &lt;span style="color: #666666"&gt;*&lt;/span&gt; (cb&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)) &lt;span style="color: #666666"&gt;/&lt;/span&gt; &lt;span style="color: #007020"&gt;len&lt;/span&gt;(pixels)&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;3&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;decompose&lt;/span&gt;(image, block_len):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; Decomposing given image into some number of&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; smaller images of size block_len*block_len&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; parts &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt; w, h &lt;span style="color: #666666"&gt;=&lt;/span&gt; image&lt;span style="color: #666666"&gt;.&lt;/span&gt;size&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; x &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;, w, block_len):&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; y &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;, h, block_len):&lt;br /&gt;   locim &lt;span style="color: #666666"&gt;=&lt;/span&gt; image&lt;span style="color: #666666"&gt;.&lt;/span&gt;crop((x,y,x&lt;span style="color: #666666"&gt;+&lt;/span&gt;block_len,y&lt;span style="color: #666666"&gt;+&lt;/span&gt;block_len))&lt;br /&gt;   acc &lt;span style="color: #666666"&gt;=&lt;/span&gt; colorhash(&lt;span style="color: #007020"&gt;list&lt;/span&gt;(locim&lt;span style="color: #666666"&gt;.&lt;/span&gt;getdata()))&lt;br /&gt;   parts&lt;span style="color: #666666"&gt;.&lt;/span&gt;append((acc,x,y,locim))&lt;br /&gt;&lt;br /&gt; parts&lt;span style="color: #666666"&gt;.&lt;/span&gt;sort()&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; parts&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;similarparts&lt;/span&gt;(imagparts):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; Detecting similar image blocks by comparing&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; calculated color hashes of given images. &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; Two images considered being equal if &lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; their color hash difference is not big.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; dupl &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; i &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(imagparts)&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;):&lt;br /&gt;  acc1, x1, y1, im1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; imagparts[i]&lt;br /&gt;   acc2, x2, y2, im2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; imagparts[i&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;br /&gt;  &lt;br /&gt;   &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; acc1 &lt;span style="color: #666666"&gt;==&lt;/span&gt; acc2 &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #40a070"&gt;0&lt;/span&gt;:&lt;br /&gt;     diff &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.0&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: #007020; font-weight: bold"&gt;else&lt;/span&gt;:&lt;br /&gt;     diff &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;100.0&lt;/span&gt; &lt;span style="color: #666666"&gt;*&lt;/span&gt; (&lt;span style="color: #40a070"&gt;1.0&lt;/span&gt; &lt;span style="color: #666666"&gt;-&lt;/span&gt; &lt;span style="color: #007020"&gt;float&lt;/span&gt;(acc1) &lt;span style="color: #666666"&gt;/&lt;/span&gt; acc2)&lt;br /&gt;  &lt;br /&gt;   col &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.3&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; diff &lt;span style="color: #666666"&gt;&amp;gt;&lt;/span&gt; col:&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; imagparts[i] &lt;span style="color: #007020; font-weight: bold"&gt;not&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; dupl:&lt;br /&gt;     dupl&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(imagparts[i])&lt;br /&gt;     &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; imagparts[i&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;] &lt;span style="color: #007020; font-weight: bold"&gt;not&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; dupl:&lt;br /&gt;      dupl&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(imagparts[i&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;])&lt;br /&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; dupl&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;marksimilar&lt;/span&gt;(image, dparts):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; Mark found similar image blocks on&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; original image, by applying red layer&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; on similar parts of image.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; dparts:&lt;br /&gt;  colormask &lt;span style="color: #666666"&gt;=&lt;/span&gt; Image&lt;span style="color: #666666"&gt;.&lt;/span&gt;new(&lt;span style="color: #4070a0"&gt;&amp;#39;RGB&amp;#39;&lt;/span&gt;, dparts[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;][&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]&lt;span style="color: #666666"&gt;.&lt;/span&gt;size,(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;,&lt;span style="color: #40a070"&gt;255&lt;/span&gt;,&lt;span style="color: #40a070"&gt;0&lt;/span&gt;))&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; (acc,x,y,im) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; dparts:&lt;br /&gt;   im &lt;span style="color: #666666"&gt;=&lt;/span&gt; Image&lt;span style="color: #666666"&gt;.&lt;/span&gt;blend(im, colormask, &lt;span style="color: #40a070"&gt;0.3&lt;/span&gt;)&lt;br /&gt;   image&lt;span style="color: #666666"&gt;.&lt;/span&gt;paste(im,(x,y))&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; image&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; __name__ &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:&lt;br /&gt; im &lt;span style="color: #666666"&gt;=&lt;/span&gt; Image&lt;span style="color: #666666"&gt;.&lt;/span&gt;open(&lt;span style="color: #4070a0"&gt;&amp;quot;1.jpg&amp;quot;&lt;/span&gt;)&lt;br /&gt; ls &lt;span style="color: #666666"&gt;=&lt;/span&gt; decompose(im, &lt;span style="color: #40a070"&gt;4&lt;/span&gt;)&lt;br /&gt; dparts &lt;span style="color: #666666"&gt;=&lt;/span&gt; similarparts(ls)&lt;br /&gt; im &lt;span style="color: #666666"&gt;=&lt;/span&gt; marksimilar(im, dparts)&lt;br /&gt; im&lt;span style="color: #666666"&gt;.&lt;/span&gt;show()&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;_________________________________________________________&lt;br /&gt;Running this code on several images we get:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_hTm-LSlj8U4/SNa7l8tZ1FI/AAAAAAAAADQ/nNsLOskFa0U/s1600-h/_1.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_hTm-LSlj8U4/SNa7l8tZ1FI/AAAAAAAAADQ/nNsLOskFa0U/s320/_1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5248588676373009490" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/SNa7wn4HURI/AAAAAAAAADY/ipsze07MPfQ/s1600-h/_2.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/SNa7wn4HURI/AAAAAAAAADY/ipsze07MPfQ/s320/_2.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5248588859759350034" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/SNa76oPkWTI/AAAAAAAAADg/P2gsWj6puO8/s1600-h/_3.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/SNa76oPkWTI/AAAAAAAAADg/P2gsWj6puO8/s320/_3.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5248589031656413490" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/SNa8G0evdoI/AAAAAAAAADo/cPnku7UUV-g/s1600-h/_4.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/SNa8G0evdoI/AAAAAAAAADo/cPnku7UUV-g/s320/_4.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5248589241099712130" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;Seems in some cases by using such color hash function we can detect color similarities in image. Maybe even some symmetry in image (if it exists). Also this hash function should be improved, because somehow it "sticks" into finding similarities in darker zones of image.&lt;br /&gt;&lt;br /&gt;Have fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-445072994115237621?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/445072994115237621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=445072994115237621&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/445072994115237621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/445072994115237621'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/09/detecting-similar-color-zones-in-image.html' title='Detecting similar color zones in image'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_hTm-LSlj8U4/SNawd5-7kAI/AAAAAAAAACo/wtGBx0jyHZA/s72-c/colf.jpeg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-7019487150857002856</id><published>2008-09-14T11:24:00.000-07:00</published><updated>2009-10-04T10:48:26.388-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='information entropy'/><category scheme='http://www.blogger.com/atom/ns#' term='image processing'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Detecting similar entropy zones in image</title><content type='html'>As I thought about &lt;a href="http://en.wikipedia.org/wiki/Information_entropy"&gt;information entropy&lt;/a&gt; one idea came to me - to write application which looks similar entropy zones in image. So after some time, I came with this algorithm (pseudo code):&lt;br /&gt;&lt;br /&gt;1. Split image into 5x5 pixel image blocks&lt;br /&gt;2. Calculate information entropy of these blocks (actually sum of entropy in 3 color channels)&lt;br /&gt;3. Find similar entropy blocks.&lt;br /&gt;4. [...] filter out small groups of blocks (seems like noise, huh ? ). Blah, blah...&lt;br /&gt;5. Picture these similar entropy blocks on top of original image as red color layer.&lt;br /&gt;&lt;br /&gt;Now real part (as you know already) - Python code which does the job [you need PIL module to run this]:&lt;br /&gt;______________________________________________________________&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;&lt;span style="color: #007020; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;PIL&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; Image&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;math&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;entropysum&lt;/span&gt;(pixels):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; Calculating information entropy for image&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; region and returning entropy sum for&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; all 3 color channels&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; cr &lt;span style="color: #666666"&gt;=&lt;/span&gt; [r &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; (r,g,b) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; pixels]&lt;br /&gt; cg &lt;span style="color: #666666"&gt;=&lt;/span&gt; [g &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; (r,g,b) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; pixels]&lt;br /&gt; cb &lt;span style="color: #666666"&gt;=&lt;/span&gt; [b &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; (r,g,b) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; pixels]&lt;br /&gt; &lt;br /&gt; er &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.0&lt;/span&gt;&lt;br /&gt; eg &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.0&lt;/span&gt;&lt;br /&gt; eb &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.0&lt;/span&gt;&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; r &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; set(cr):&lt;br /&gt;  p &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;float&lt;/span&gt;(cr&lt;span style="color: #666666"&gt;.&lt;/span&gt;count(r))&lt;span style="color: #666666"&gt;/&lt;/span&gt;&lt;span style="color: #007020"&gt;len&lt;/span&gt;(cr)&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; p &lt;span style="color: #666666"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.0&lt;/span&gt;: er &lt;span style="color: #666666"&gt;+=&lt;/span&gt; &lt;span style="color: #666666"&gt;-&lt;/span&gt;p &lt;span style="color: #666666"&gt;*&lt;/span&gt; log(p,&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; g &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; set(cg):&lt;br /&gt;  p &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;float&lt;/span&gt;(cg&lt;span style="color: #666666"&gt;.&lt;/span&gt;count(g))&lt;span style="color: #666666"&gt;/&lt;/span&gt;&lt;span style="color: #007020"&gt;len&lt;/span&gt;(cg)&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; p &lt;span style="color: #666666"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.0&lt;/span&gt;: eg &lt;span style="color: #666666"&gt;+=&lt;/span&gt; &lt;span style="color: #666666"&gt;-&lt;/span&gt;p &lt;span style="color: #666666"&gt;*&lt;/span&gt; log(p,&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; b &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; set(cb):&lt;br /&gt;  p &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;float&lt;/span&gt;(cb&lt;span style="color: #666666"&gt;.&lt;/span&gt;count(b))&lt;span style="color: #666666"&gt;/&lt;/span&gt;&lt;span style="color: #007020"&gt;len&lt;/span&gt;(cb)&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; p &lt;span style="color: #666666"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.0&lt;/span&gt;: eb &lt;span style="color: #666666"&gt;+=&lt;/span&gt; &lt;span style="color: #666666"&gt;-&lt;/span&gt;p &lt;span style="color: #666666"&gt;*&lt;/span&gt; log(p,&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; er &lt;span style="color: #666666"&gt;+&lt;/span&gt; eg &lt;span style="color: #666666"&gt;+&lt;/span&gt; eb&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;decompose&lt;/span&gt;(image, block_len):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; Decomposing given image into some number of&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; smaller images of size block_len*block_len&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; parts &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt; w, h &lt;span style="color: #666666"&gt;=&lt;/span&gt; image&lt;span style="color: #666666"&gt;.&lt;/span&gt;size&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; x &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;, w, block_len):&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; y &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #40a070"&gt;0&lt;/span&gt;, h, block_len):&lt;br /&gt;   locim &lt;span style="color: #666666"&gt;=&lt;/span&gt; image&lt;span style="color: #666666"&gt;.&lt;/span&gt;crop((x,y,x&lt;span style="color: #666666"&gt;+&lt;/span&gt;block_len,y&lt;span style="color: #666666"&gt;+&lt;/span&gt;block_len))&lt;br /&gt;   acc &lt;span style="color: #666666"&gt;=&lt;/span&gt; entropysum(&lt;span style="color: #007020"&gt;list&lt;/span&gt;(locim&lt;span style="color: #666666"&gt;.&lt;/span&gt;getdata()))&lt;br /&gt;   parts&lt;span style="color: #666666"&gt;.&lt;/span&gt;append((acc,x,y,locim))&lt;br /&gt; &lt;br /&gt; parts&lt;span style="color: #666666"&gt;.&lt;/span&gt;sort()&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; parts&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;similarparts&lt;/span&gt;(imagparts):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; Detecting similar image blocks by comparing&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; entropy of given images. Two images considered&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; being equal if entropy difference is not big.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; dupl &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; i &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(imagparts)&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;):&lt;br /&gt;  acc1, x1, y1, im1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; imagparts[i]&lt;br /&gt;  acc2, x2, y2, im2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; imagparts[i&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;br /&gt;  &lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; acc1 &lt;span style="color: #666666"&gt;==&lt;/span&gt; acc2 &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #40a070"&gt;0&lt;/span&gt;:&lt;br /&gt;   gain &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.0&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;else&lt;/span&gt;:&lt;br /&gt;   gain &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;100.0&lt;/span&gt; &lt;span style="color: #666666"&gt;*&lt;/span&gt; (&lt;span style="color: #40a070"&gt;1.0&lt;/span&gt; &lt;span style="color: #666666"&gt;-&lt;/span&gt; acc1 &lt;span style="color: #666666"&gt;/&lt;/span&gt; acc2)&lt;br /&gt;&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.01&lt;/span&gt; &lt;span style="color: #666666"&gt;&amp;lt;&lt;/span&gt; gain &lt;span style="color: #666666"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: #40a070"&gt;0.1&lt;/span&gt; :&lt;br /&gt;   &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; imagparts[i] &lt;span style="color: #007020; font-weight: bold"&gt;not&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; dupl:&lt;br /&gt;    dupl&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(imagparts[i])&lt;br /&gt;   &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; imagparts[i&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;] &lt;span style="color: #007020; font-weight: bold"&gt;not&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; dupl:&lt;br /&gt;    dupl&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(imagparts[i&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;])&lt;br /&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; dupl&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;clusterparts&lt;/span&gt;(parts):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; Grouping nearest images into groups.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; This is done, because we need to&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; filter out very small groups. We&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; want to know only big differences.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;br /&gt; filtparts &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt; clust &lt;span style="color: #666666"&gt;=&lt;/span&gt; {}&lt;br /&gt; belongs &lt;span style="color: #666666"&gt;=&lt;/span&gt; {}&lt;br /&gt; w,h &lt;span style="color: #666666"&gt;=&lt;/span&gt; parts[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;][&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]&lt;span style="color: #666666"&gt;.&lt;/span&gt;size&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #60a0b0; font-style: italic"&gt;# assign all parts to clusters&lt;/span&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; i &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(parts)):&lt;br /&gt;  acc, x, y, im &lt;span style="color: #666666"&gt;=&lt;/span&gt; parts[i]&lt;br /&gt;  sides &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt;  sides&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(&lt;span style="color: #007020"&gt;str&lt;/span&gt;(x)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(y)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(x&lt;span style="color: #666666"&gt;+&lt;/span&gt;w)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(y))&lt;br /&gt;  sides&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(&lt;span style="color: #007020"&gt;str&lt;/span&gt;(x&lt;span style="color: #666666"&gt;+&lt;/span&gt;w)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(y)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(x&lt;span style="color: #666666"&gt;+&lt;/span&gt;w)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(y&lt;span style="color: #666666"&gt;+&lt;/span&gt;h))&lt;br /&gt;  sides&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(&lt;span style="color: #007020"&gt;str&lt;/span&gt;(x)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(y&lt;span style="color: #666666"&gt;+&lt;/span&gt;h)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(x&lt;span style="color: #666666"&gt;+&lt;/span&gt;w)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(y&lt;span style="color: #666666"&gt;+&lt;/span&gt;h))&lt;br /&gt;  sides&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(&lt;span style="color: #007020"&gt;str&lt;/span&gt;(x)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(y)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(x)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(y&lt;span style="color: #666666"&gt;+&lt;/span&gt;h))&lt;br /&gt;  &lt;br /&gt;  &lt;span style="color: #60a0b0; font-style: italic"&gt;# detect side already in cluster&lt;/span&gt;&lt;br /&gt;  fc &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;None&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; s &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; sides:&lt;br /&gt;   &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; belongs&lt;span style="color: #666666"&gt;.&lt;/span&gt;has_key(s):&lt;br /&gt;    fc &lt;span style="color: #666666"&gt;=&lt;/span&gt; belongs[s]&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;break&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span style="color: #60a0b0; font-style: italic"&gt;# if this is new cluster&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; fc &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #007020"&gt;None&lt;/span&gt;:&lt;br /&gt;   fc &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;len&lt;/span&gt;(clust) &lt;span style="color: #666666"&gt;+&lt;/span&gt; &lt;span style="color: #40a070"&gt;1&lt;/span&gt;&lt;br /&gt;   clust[fc] &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;1&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;else&lt;/span&gt;:&lt;br /&gt;   clust[fc] &lt;span style="color: #666666"&gt;+=&lt;/span&gt; &lt;span style="color: #40a070"&gt;1&lt;/span&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;span style="color: #60a0b0; font-style: italic"&gt;# set cluster for rectangle sides&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; s &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; sides:&lt;br /&gt;   &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;not&lt;/span&gt; belongs&lt;span style="color: #666666"&gt;.&lt;/span&gt;has_key(s):&lt;br /&gt;    belongs[s] &lt;span style="color: #666666"&gt;=&lt;/span&gt; fc&lt;br /&gt;&lt;br /&gt; &lt;span style="color: #60a0b0; font-style: italic"&gt;# filter out small clusters&lt;/span&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; i &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(parts)):&lt;br /&gt;  acc, x, y, im &lt;span style="color: #666666"&gt;=&lt;/span&gt; parts[i]&lt;br /&gt;  side &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;str&lt;/span&gt;(x)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(y)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(x&lt;span style="color: #666666"&gt;+&lt;/span&gt;w)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;str&lt;/span&gt;(y)&lt;br /&gt;  cl &lt;span style="color: #666666"&gt;=&lt;/span&gt; belongs[side]&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; clust[cl] &lt;span style="color: #666666"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #40a070"&gt;2&lt;/span&gt;:&lt;br /&gt;   filtparts&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(parts[i])&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; filtparts&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;marksimilar&lt;/span&gt;(image, dparts):&lt;br /&gt; &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; Mark found similar image blocks on&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; original image, by applying red layer&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; on similar parts of image.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt; &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; dparts:&lt;br /&gt;  colormask &lt;span style="color: #666666"&gt;=&lt;/span&gt; Image&lt;span style="color: #666666"&gt;.&lt;/span&gt;new(&lt;span style="color: #4070a0"&gt;&amp;#39;RGB&amp;#39;&lt;/span&gt;, dparts[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;][&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]&lt;span style="color: #666666"&gt;.&lt;/span&gt;size,(&lt;span style="color: #40a070"&gt;255&lt;/span&gt;,&lt;span style="color: #40a070"&gt;0&lt;/span&gt;,&lt;span style="color: #40a070"&gt;0&lt;/span&gt;))&lt;br /&gt;  &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; (acc,x,y,im) &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; dparts:&lt;br /&gt;   im &lt;span style="color: #666666"&gt;=&lt;/span&gt; Image&lt;span style="color: #666666"&gt;.&lt;/span&gt;blend(im, colormask, &lt;span style="color: #40a070"&gt;0.4&lt;/span&gt;)&lt;br /&gt;   image&lt;span style="color: #666666"&gt;.&lt;/span&gt;paste(im,(x,y))&lt;br /&gt; &lt;br /&gt; &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; image&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; __name__ &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:&lt;br /&gt; im &lt;span style="color: #666666"&gt;=&lt;/span&gt; Image&lt;span style="color: #666666"&gt;.&lt;/span&gt;open(&lt;span style="color: #4070a0"&gt;&amp;quot;1.jpg&amp;quot;&lt;/span&gt;)&lt;br /&gt; ls &lt;span style="color: #666666"&gt;=&lt;/span&gt; decompose(im, &lt;span style="color: #40a070"&gt;5&lt;/span&gt;)&lt;br /&gt; dparts &lt;span style="color: #666666"&gt;=&lt;/span&gt; similarparts(ls)&lt;br /&gt; cparts &lt;span style="color: #666666"&gt;=&lt;/span&gt; clusterparts(dparts)&lt;br /&gt; im &lt;span style="color: #666666"&gt;=&lt;/span&gt; marksimilar(im, cparts)&lt;br /&gt; im&lt;span style="color: #666666"&gt;.&lt;/span&gt;show()&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;________________________________________________________&lt;br /&gt;So these are the results after running this script on several images:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/SM1hYDu69YI/AAAAAAAAACI/pMcemMgckBg/s1600-h/_1.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/SM1hYDu69YI/AAAAAAAAACI/pMcemMgckBg/s320/_1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5245956206903358850" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/SM1h6KeqLdI/AAAAAAAAACQ/eDr7DDRShJU/s1600-h/_11.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/SM1h6KeqLdI/AAAAAAAAACQ/eDr7DDRShJU/s320/_11.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5245956792829750738" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/SM1ieQvVPxI/AAAAAAAAACY/fNfk0UhE_nM/s1600-h/_6.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/SM1ieQvVPxI/AAAAAAAAACY/fNfk0UhE_nM/s320/_6.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5245957412985585426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/SM1iuIJbdxI/AAAAAAAAACg/pPB1ILOlwCY/s1600-h/_8.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/SM1iuIJbdxI/AAAAAAAAACg/pPB1ILOlwCY/s320/_8.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5245957685557032722" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So this algorithm is an interesting tool for exploration of information entropy in image. Maybe in some cases it could be a tool for analyzing very similar texture zones. BTW information entropy may be used for hashing image. Hashing image is useful, because it lets us to search similar images in database (for example) by its hash.&lt;br /&gt;&lt;br /&gt;Have fun !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-7019487150857002856?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/7019487150857002856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=7019487150857002856&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/7019487150857002856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/7019487150857002856'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/09/finding-similar-parts-in-image.html' title='Detecting similar entropy zones in image'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_hTm-LSlj8U4/SM1hYDu69YI/AAAAAAAAACI/pMcemMgckBg/s72-c/_1.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-5839616367505646129</id><published>2008-08-31T12:32:00.000-07:00</published><updated>2009-10-04T10:45:13.541-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='number of runs'/><category scheme='http://www.blogger.com/atom/ns#' term='randomness'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Number of runs in random sequence</title><content type='html'>While reading this article about human ability on outputing random data-&lt;br /&gt;&lt;a href="http://faculty.rhodes.edu/wetzel/random/mainbody.html"&gt;http://faculty.rhodes.edu/wetzel/random/mainbody.html&lt;/a&gt;&lt;br /&gt;I started to think - How we can simply detect that entered sequence is NOT random ( or entered by human) ? Of course to make some real-world measurements we need statistics a lot. But if we need just some straightfoward method for preliminary results ? Well, the idea was to check the number of runs in sequence and to compare the result with the expected value. (Number of runs is total number of subsequences in sequence).&lt;br /&gt;So that if number_of_runs != expected_number_of_runs then we can conclude that data is not much random. OK. Number of runs we can measure simply. But what about expected_number_of_runs ? Somehow I suspected that this expected runs count should be dependent on the random variable values amount. For example sequences 'azazaz' and 'azxazx' are the same length, but one is composed of a,z (2 values) and second- a,z,x (3 values). So if we know what is going on with the number_of_runs when random sequences is composed from different values amount - we may calculate expected_number_of_runs given any sequence. Second point - for eliminating need to recalculate everything when sequence length changes - better calculate expected_number_of_runs / sequence_length.&lt;br /&gt;So I made such experiment for detection of such dependancy.&lt;br /&gt;Experiment Python code (to run it you need matplotlib python module):&lt;br /&gt;_________________________________________________________________&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;&lt;span style="color: #007020; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;random&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;pylab&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; plot,  show,  xlabel,  ylabel,  title,  grid,  legend&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;runs&lt;/span&gt;(lst):&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #007020"&gt;sum&lt;/span&gt;([&lt;span style="color: #007020"&gt;int&lt;/span&gt;(&lt;span style="color: #007020; font-weight: bold"&gt;not&lt;/span&gt; lst[i]&lt;span style="color: #666666"&gt;==&lt;/span&gt;lst[i&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]) &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; i &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #007020"&gt;len&lt;/span&gt;(lst)&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;)])&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;testruns&lt;/span&gt;(n):&lt;br /&gt;    s&lt;span style="color: #666666"&gt;=&lt;/span&gt;[randint(&lt;span style="color: #40a070"&gt;1&lt;/span&gt;, n) &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; x &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #40a070"&gt;10000&lt;/span&gt;)]&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #007020"&gt;float&lt;/span&gt;(runs(s)) &lt;span style="color: #666666"&gt;/&lt;/span&gt; &lt;span style="color: #007020"&gt;len&lt;/span&gt;(s)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020"&gt;max&lt;/span&gt; &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #40a070"&gt;20&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007020"&gt;xrange&lt;/span&gt; &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;range&lt;/span&gt;(&lt;span style="color: #40a070"&gt;2&lt;/span&gt;, &lt;span style="color: #007020"&gt;max&lt;/span&gt;)&lt;br /&gt;yruns &lt;span style="color: #666666"&gt;=&lt;/span&gt; [testruns(x) &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; x &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;xrange&lt;/span&gt;] &lt;span style="color: #60a0b0; font-style: italic"&gt;# Generating random data and counting runs&lt;/span&gt;&lt;br /&gt;yreg &lt;span style="color: #666666"&gt;=&lt;/span&gt; [&lt;span style="color: #40a070"&gt;1.0&lt;/span&gt;&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;1.0&lt;/span&gt;&lt;span style="color: #666666"&gt;/&lt;/span&gt;x &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; x &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;xrange&lt;/span&gt;]  &lt;span style="color: #60a0b0; font-style: italic"&gt;# Function for fitting data&lt;/span&gt;&lt;br /&gt;plot(&lt;span style="color: #007020"&gt;xrange&lt;/span&gt;, yruns ,  &lt;span style="color: #4070a0"&gt;&amp;#39;ro&amp;#39;&lt;/span&gt;,  &lt;span style="color: #007020"&gt;xrange&lt;/span&gt;, yreg)&lt;br /&gt;xlabel(&lt;span style="color: #4070a0"&gt;&amp;#39;Variable values amount&amp;#39;&lt;/span&gt;)&lt;br /&gt;ylabel(&lt;span style="color: #4070a0"&gt;&amp;#39;Number of runs per item&amp;#39;&lt;/span&gt;)&lt;br /&gt;title(&lt;span style="color: #4070a0"&gt;&amp;#39;Number of runs dependance on variable values amount&amp;#39;&lt;/span&gt;)&lt;br /&gt;legend((&lt;span style="color: #4070a0"&gt;&amp;#39;Experimental&amp;#39;&lt;/span&gt; , &lt;span style="color: #4070a0"&gt;&amp;#39;Data fit:  &amp;#39;&lt;/span&gt; &lt;span style="color: #4070a0"&gt;r&amp;#39;$1-n^{-1}$&amp;#39;&lt;/span&gt;), loc&lt;span style="color: #666666"&gt;=&lt;/span&gt;&lt;span style="color: #40a070"&gt;7&lt;/span&gt;)&lt;br /&gt;grid()&lt;br /&gt;show()&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;_________________________________________________________________&lt;br /&gt;&lt;br /&gt;So after running this random data test- we get such plot:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/SLr7a4riAZI/AAAAAAAAACA/EpX_o2jNMJE/s1600-h/number_of_runs.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/SLr7a4riAZI/AAAAAAAAACA/EpX_o2jNMJE/s400/number_of_runs.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5240777555709133202" /&gt;&lt;/a&gt;&lt;br /&gt;So it tells us that expected_number_of_runs we need to calculate like that-&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;expected_number_of_runs = sequence_length * (1 - 1/n)&lt;/span&gt;;&lt;br /&gt;n- unique element count in sequence. So now we have some tool for detecting sequence being not much random.&lt;br /&gt;First- we measure real number_of_runs in sequence.&lt;br /&gt;Second - we calculate expected_number_of_runs.&lt;br /&gt;Third - if these two values is not approximately equal - then we can conclude that data is not random. Of course we can`t be sure about randomness just from this test.&lt;br /&gt;We need a lot of different measures - information entropy and as such... But&lt;br /&gt;the goal of this article was to play with number_of_runs. Maybe later - I will write something about information entropy. It is very interesting also.&lt;br /&gt;&lt;br /&gt;Have fun!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-5839616367505646129?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/5839616367505646129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=5839616367505646129&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/5839616367505646129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/5839616367505646129'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/08/number-of-runs-in-random-sequence.html' title='Number of runs in random sequence'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_hTm-LSlj8U4/SLr7a4riAZI/AAAAAAAAACA/EpX_o2jNMJE/s72-c/number_of_runs.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-5975217008022829805</id><published>2008-08-27T12:34:00.000-07:00</published><updated>2009-10-04T10:37:29.742-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='codegolf'/><category scheme='http://www.blogger.com/atom/ns#' term='vigenere cipher'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Codegolf - Vigenere Cipher</title><content type='html'>Problem definition:&lt;br /&gt;---------------------------------------------------&lt;br /&gt;The Vigenere cipher is a simple form of a polyalphabetic substitution, using a series of different Caesar ciphers based on the letters of a keyword. It's over 450 years old now, but that shouldn't stop us having a bit of golfing fun with it now.&lt;br /&gt;&lt;br /&gt;The following information is largely taken from Wikipedia's &lt;a href="http://en.wikipedia.org/wiki/Vigenere_cipher"&gt;Vigenere cipher&lt;/a&gt; page. You might find some interesting information that isn't included here, so I recommend you check it out.&lt;br /&gt;&lt;br /&gt;Your job is to write some code which takes a keyword and some plaintext, and encrypts it according to the Vigenere cipher.&lt;br /&gt;&lt;br /&gt;In a Caesar cipher, each letter of the alphabet is shifted along some number of places; for example, in a Caesar cipher of shift 3, A would become D, B would become E and so on. The Vigenere cipher consists of several Caesar ciphers in sequence with different shift values.&lt;br /&gt;&lt;br /&gt;To encipher, a table of alphabets can be used, termed a tabula recta, Vigenere square, or Vigenere table. It consists of the alphabet written out 26 times in different rows, each alphabet shifted cyclically to the left compared to the previous alphabet, corresponding to the 26 possible Caesar ciphers. At different points in the encryption process, the cipher uses a different alphabet from one of the rows. The alphabet used at each point depends on a repeating keyword.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Image:Vigenere-square.png"&gt;Click here to see the Vigenere square&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;See the examples section below for a worked example.&lt;br /&gt;More Information&lt;br /&gt;&lt;br /&gt;    * Your code will be given both the keyword and the plaintext on stdin. It will be in the format&lt;br /&gt;&lt;br /&gt;      KEYWORD&lt;br /&gt;      PLAINTEXT&lt;br /&gt;&lt;br /&gt;      with newlines at the end of each line.&lt;br /&gt;&lt;br /&gt;    * You should print the encrypted plaintext on stdout.&lt;br /&gt;    * Both the keyword and the plaintext will contain only the uppercase letters A through Z.&lt;br /&gt;    * Your code will be run three times and will need to pass all three tests to be deemed successful.&lt;br /&gt;---------------------------------------------------&lt;br /&gt;Code golf challenge is interesting because it measures your ability to write code as short as possible. My try to give shortest solution in Python:&lt;br /&gt;&lt;br /&gt;Run no 1 -&gt; code size 111 bytes:&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;k&lt;span style="color: #666666"&gt;=&lt;/span&gt;&lt;span style="color: #007020"&gt;raw_input&lt;/span&gt;()&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #40a070"&gt;100&lt;/span&gt;;p&lt;span style="color: #666666"&gt;=&lt;/span&gt;&lt;span style="color: #007020"&gt;raw_input&lt;/span&gt;()&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style="color: #666666"&gt;.&lt;/span&gt;join(&lt;span style="color: #007020"&gt;map&lt;/span&gt;(&lt;span style="color: #007020; font-weight: bold"&gt;lambda&lt;/span&gt; x, y: &lt;span style="color: #007020"&gt;chr&lt;/span&gt;(&lt;span style="color: #40a070"&gt;65&lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;(&lt;span style="color: #007020"&gt;ord&lt;/span&gt;(x)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;ord&lt;/span&gt;(y)&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;130&lt;/span&gt;)&lt;span style="color: #666666"&gt;%&lt;/span&gt;&lt;span style="color: #40a070"&gt;26&lt;/span&gt;), k[:&lt;span style="color: #007020"&gt;len&lt;/span&gt;(p)], p))&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Run no 2 -&gt; code size 84 bytes:&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;i&lt;span style="color: #666666"&gt;=&lt;/span&gt;&lt;span style="color: #007020"&gt;raw_input&lt;/span&gt;;&lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style="color: #666666"&gt;.&lt;/span&gt;join(&lt;span style="color: #007020"&gt;chr&lt;/span&gt;(&lt;span style="color: #40a070"&gt;65&lt;/span&gt;&lt;span style="color: #666666"&gt;+&lt;/span&gt;(&lt;span style="color: #007020"&gt;ord&lt;/span&gt;(x)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #007020"&gt;ord&lt;/span&gt;(y)&lt;span style="color: #666666"&gt;-&lt;/span&gt;&lt;span style="color: #40a070"&gt;130&lt;/span&gt;)&lt;span style="color: #666666"&gt;%&lt;/span&gt;&lt;span style="color: #40a070"&gt;26&lt;/span&gt;) &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; x,y &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;zip&lt;/span&gt;(i()&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #40a070"&gt;10&lt;/span&gt;,i()))&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Have fun!&lt;br /&gt;&lt;a href="http://codegolf.com/competition/browse"&gt;Code golf&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-5975217008022829805?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/5975217008022829805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=5975217008022829805&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/5975217008022829805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/5975217008022829805'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/08/codegolf-vigenere-cipher.html' title='Codegolf - Vigenere Cipher'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-4377720350595529598</id><published>2008-08-25T07:20:00.001-07:00</published><updated>2009-10-04T10:33:13.613-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><title type='text'>Project Euler p22</title><content type='html'>Problem description:&lt;br /&gt;-----------------------------------------------------------&lt;br /&gt;Using &lt;a href="http://projecteuler.net/project/names.txt"&gt;names.txt&lt;/a&gt; (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.&lt;br /&gt;&lt;br /&gt;For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 * 53 = 49714.&lt;br /&gt;&lt;br /&gt;What is the total of all the name scores in the file?&lt;br /&gt;-----------------------------------------------------------&lt;br /&gt;Solution in Python:&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;ReadFile&lt;/span&gt;():&lt;br /&gt;    &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot; Read data input file&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    f &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;open&lt;/span&gt;(&lt;span style="color: #4070a0"&gt;&amp;#39;C:/ProjectEuler/names.txt&amp;#39;&lt;/span&gt;,&lt;span style="color: #4070a0"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;)&lt;br /&gt;    &lt;span style="color: #007020"&gt;str&lt;/span&gt; &lt;span style="color: #666666"&gt;=&lt;/span&gt; f&lt;span style="color: #666666"&gt;.&lt;/span&gt;readlines()&lt;br /&gt;    f&lt;span style="color: #666666"&gt;.&lt;/span&gt;close()&lt;br /&gt;    &lt;span style="color: #007020"&gt;str&lt;/span&gt;[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;] &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;str&lt;/span&gt;[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]&lt;span style="color: #666666"&gt;.&lt;/span&gt;replace(&lt;span style="color: #4070a0"&gt;&amp;#39;&amp;quot;&amp;#39;&lt;/span&gt;,&lt;span style="color: #4070a0"&gt;&amp;#39;&amp;#39;&lt;/span&gt;)&lt;br /&gt;    ret &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;str&lt;/span&gt;[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]&lt;span style="color: #666666"&gt;.&lt;/span&gt;split(&lt;span style="color: #4070a0"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;)&lt;br /&gt;    ret&lt;span style="color: #666666"&gt;.&lt;/span&gt;sort()&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; ret&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;AlphabeticalValue&lt;/span&gt;(string):&lt;br /&gt;    alph &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;list&lt;/span&gt;(&lt;span style="color: #4070a0"&gt;&amp;#39;ABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;#39;&lt;/span&gt;)&lt;br /&gt;    values &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;map&lt;/span&gt;(&lt;span style="color: #007020; font-weight: bold"&gt;lambda&lt;/span&gt; x: alph&lt;span style="color: #666666"&gt;.&lt;/span&gt;index(x)&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;, &lt;span style="color: #007020"&gt;list&lt;/span&gt;(string))&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #007020"&gt;sum&lt;/span&gt;(values)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;TotalScore&lt;/span&gt;():&lt;br /&gt;    names &lt;span style="color: #666666"&gt;=&lt;/span&gt; ReadFile()&lt;br /&gt;    namsc &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;map&lt;/span&gt;(&lt;span style="color: #007020; font-weight: bold"&gt;lambda&lt;/span&gt; (x,y): AlphabeticalValue(y)&lt;span style="color: #666666"&gt;*&lt;/span&gt;(x&lt;span style="color: #666666"&gt;+&lt;/span&gt;&lt;span style="color: #40a070"&gt;1&lt;/span&gt;), &lt;span style="color: #007020"&gt;list&lt;/span&gt;(&lt;span style="color: #007020"&gt;enumerate&lt;/span&gt;(names)))&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #007020"&gt;sum&lt;/span&gt;(namsc)&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; __name__ &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; TotalScore()&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What is missing ? Of course - Have fun :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-4377720350595529598?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/4377720350595529598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=4377720350595529598&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/4377720350595529598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/4377720350595529598'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/08/project-euler-p22.html' title='Project Euler p22'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-6556810989068156022</id><published>2008-07-11T12:56:00.000-07:00</published><updated>2009-10-04T10:30:34.759-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google codejam contest'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Google codejam 2008 contest practice test</title><content type='html'>This time we will probe Google famous CodeJam contest. We will try to solve codejam 2008 one of practice tests. Test problem is defined as:&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;Problem&lt;br /&gt;&lt;br /&gt;You're interested in writing a program to classify triangles. Triangles can be classified according to their internal angles. If one of the internal angles is exactly 90 degrees, then that triangle is known as a "right" triangle. If one of the internal angles is greater than 90 degrees, that triangle is known as an "obtuse" triangle. Otherwise, all the internal angles are less than 90 degrees and the triangle is known as an "acute" triangle.&lt;br /&gt;&lt;br /&gt;Triangles can also be classified according to the relative lengths of their sides. In a "scalene" triangle, all three sides have different lengths. In an "isosceles" triangle, two of the sides are of equal length. (If all three sides have the same length, the triangle is known as an "equilateral" triangle, but you can ignore this case since there will be no equilateral triangles in the input data.)&lt;br /&gt;&lt;br /&gt;Your program must determine, for each set of three points, whether or not those points form a triangle. If the three points are not distinct, or the three points are collinear, then those points do not form a valid triangle. (Another way is to calculate the area of the triangle; valid triangles must have non-zero area.) Otherwise, your program will classify the triangle as one of "acute", "obtuse", or "right", and one of "isosceles" or "scalene".&lt;br /&gt;&lt;br /&gt;Input&lt;br /&gt;&lt;br /&gt;The first line of input gives the number of cases, N. N test cases follow. Each case is a line formatted as&lt;br /&gt;&lt;br /&gt;x1 y1 x2 y2 x3 y3&lt;br /&gt;&lt;br /&gt;Output&lt;br /&gt;&lt;br /&gt;For each test case, output one line containing "Case #x: " followed by one of these strings:&lt;br /&gt;&lt;br /&gt;    * isosceles acute triangle&lt;br /&gt;    * isosceles obtuse triangle&lt;br /&gt;    * isosceles right triangle&lt;br /&gt;    * scalene acute triangle&lt;br /&gt;    * scalene obtuse triangle&lt;br /&gt;    * scalene right triangle&lt;br /&gt;    * not a triangle&lt;br /&gt;&lt;br /&gt;Limits&lt;br /&gt;&lt;br /&gt;1 ≤ N ≤ 100,&lt;br /&gt;x1, y1, x2, y2, x3, y3 will be integers. &lt;br /&gt;&lt;br /&gt;Sample Input&lt;br /&gt;&lt;br /&gt;0 0 0 4 1 2&lt;br /&gt;1 1 1 4 3 2&lt;br /&gt;2 2 2 4 4 3&lt;br /&gt;3 3 3 4 5 3&lt;br /&gt;4 4 4 5 5 6&lt;br /&gt;5 5 5 6 6 5&lt;br /&gt;6 6 6 7 6 8&lt;br /&gt;7 7 7 7 7 7&lt;br /&gt;&lt;br /&gt;Sample Output&lt;br /&gt;&lt;br /&gt;Case #1: isosceles obtuse triangle&lt;br /&gt;Case #2: scalene acute triangle&lt;br /&gt;Case #3: isosceles acute triangle&lt;br /&gt;Case #4: scalene right triangle&lt;br /&gt;Case #5: scalene obtuse triangle&lt;br /&gt;Case #6: isosceles right triangle&lt;br /&gt;Case #7: not a triangle&lt;br /&gt;Case #8: not a triangle&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------&lt;br /&gt;This time solution is written in Python language. To test this solution you need to have Python interpreter installed. You can install it from www.python.org. For trying this script- paste Sample Input lines into file named 'A-large.in' and place this file into the same folder where below mentioned Python script will be. Script is somewhat fast - 100 sample triangles is analyzed in just 2.2 ms !!!. Script code:&lt;br /&gt;&lt;div class="highlight" &gt;&lt;pre&gt;&lt;span style="color: #60a0b0; font-style: italic"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;sys&lt;/span&gt;&lt;span style="color: #666666"&gt;,&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;time&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;ReadFile&lt;/span&gt;():&lt;br /&gt;    &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot; Read data input file&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    path &lt;span style="color: #666666"&gt;=&lt;/span&gt; sys&lt;span style="color: #666666"&gt;.&lt;/span&gt;path[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]&lt;br /&gt;    f &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;open&lt;/span&gt;(path &lt;span style="color: #666666"&gt;+&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;/A-large.in&amp;#39;&lt;/span&gt;,&lt;span style="color: #4070a0"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;)&lt;br /&gt;    &lt;span style="color: #007020"&gt;str&lt;/span&gt; &lt;span style="color: #666666"&gt;=&lt;/span&gt; f&lt;span style="color: #666666"&gt;.&lt;/span&gt;readlines()&lt;br /&gt;    f&lt;span style="color: #666666"&gt;.&lt;/span&gt;close()&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #007020"&gt;str&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;IsTriangle&lt;/span&gt;(p):&lt;br /&gt;    &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;Defines triangle by it`s area&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    area &lt;span style="color: #666666"&gt;=&lt;/span&gt; (p[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]&lt;span style="color: #666666"&gt;*&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;5&lt;/span&gt;])&lt;span style="color: #666666"&gt;+&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;2&lt;/span&gt;]&lt;span style="color: #666666"&gt;*&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;5&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;1&lt;/span&gt;])&lt;span style="color: #666666"&gt;+&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;4&lt;/span&gt;]&lt;span style="color: #666666"&gt;*&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]))&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; area &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #40a070"&gt;0&lt;/span&gt;:&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;not a triangle&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;else&lt;/span&gt;:&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;triangle&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;SideType&lt;/span&gt;(p):&lt;br /&gt;    &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;Defines triangle by sides lengths&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    s1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; ((&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;2&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;span style="color: #666666"&gt;+&lt;/span&gt;(&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;3&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;))&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;0.5&lt;/span&gt;&lt;br /&gt;    s2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; ((&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;4&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;span style="color: #666666"&gt;+&lt;/span&gt;(&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;5&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;))&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;0.5&lt;/span&gt;&lt;br /&gt;    s3 &lt;span style="color: #666666"&gt;=&lt;/span&gt; ((&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;2&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;4&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;span style="color: #666666"&gt;+&lt;/span&gt;(&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;5&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;))&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;0.5&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; s1&lt;span style="color: #666666"&gt;!=&lt;/span&gt;s2 &lt;span style="color: #007020; font-weight: bold"&gt;and&lt;/span&gt; s1&lt;span style="color: #666666"&gt;!=&lt;/span&gt;s3 &lt;span style="color: #007020; font-weight: bold"&gt;and&lt;/span&gt; s3&lt;span style="color: #666666"&gt;!=&lt;/span&gt;s2:&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;scalene&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; s1&lt;span style="color: #666666"&gt;==&lt;/span&gt;s2 &lt;span style="color: #007020; font-weight: bold"&gt;or&lt;/span&gt; s1&lt;span style="color: #666666"&gt;==&lt;/span&gt;s3 &lt;span style="color: #007020; font-weight: bold"&gt;or&lt;/span&gt; s3&lt;span style="color: #666666"&gt;==&lt;/span&gt;s2:&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;isosceles&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;AngleType&lt;/span&gt;(p):&lt;br /&gt;    &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot;Defines triangle type by angle.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt;       Idea based on Pythagorean theorem and somewhat&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt;       empirical hack about &amp;#39;not perfect&amp;#39; right triangles -&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt;       for which (a^2+b^2)/c^2 is only approximately 1.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt;       And the more angle shifts from 90 degrees, the&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #4070a0; font-style: italic"&gt;       more (a^2+b^2)/c^2 relation shifts from 1&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    s1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; ((&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;2&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;span style="color: #666666"&gt;+&lt;/span&gt;(&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;3&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;))&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;0.5&lt;/span&gt;&lt;br /&gt;    s2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; ((&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;4&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;span style="color: #666666"&gt;+&lt;/span&gt;(&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;1&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;5&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;))&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;0.5&lt;/span&gt;&lt;br /&gt;    s3 &lt;span style="color: #666666"&gt;=&lt;/span&gt; ((&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;2&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;4&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;span style="color: #666666"&gt;+&lt;/span&gt;(&lt;span style="color: #007020"&gt;abs&lt;/span&gt;(p[&lt;span style="color: #40a070"&gt;3&lt;/span&gt;]&lt;span style="color: #666666"&gt;-&lt;/span&gt;p[&lt;span style="color: #40a070"&gt;5&lt;/span&gt;])&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;))&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;0.5&lt;/span&gt;&lt;br /&gt;    k1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;round&lt;/span&gt;(&lt;span style="color: #007020"&gt;float&lt;/span&gt;((s1&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;span style="color: #666666"&gt;+&lt;/span&gt;(s2&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;))&lt;span style="color: #666666"&gt;/&lt;/span&gt;&lt;span style="color: #007020"&gt;float&lt;/span&gt;(s3&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;),&lt;span style="color: #40a070"&gt;3&lt;/span&gt;)&lt;br /&gt;    k2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;round&lt;/span&gt;(&lt;span style="color: #007020"&gt;float&lt;/span&gt;((s1&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;span style="color: #666666"&gt;+&lt;/span&gt;(s3&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;))&lt;span style="color: #666666"&gt;/&lt;/span&gt;&lt;span style="color: #007020"&gt;float&lt;/span&gt;(s2&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;),&lt;span style="color: #40a070"&gt;3&lt;/span&gt;)&lt;br /&gt;    k3 &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;round&lt;/span&gt;(&lt;span style="color: #007020"&gt;float&lt;/span&gt;((s3&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;)&lt;span style="color: #666666"&gt;+&lt;/span&gt;(s2&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;))&lt;span style="color: #666666"&gt;/&lt;/span&gt;&lt;span style="color: #007020"&gt;float&lt;/span&gt;(s1&lt;span style="color: #666666"&gt;**&lt;/span&gt;&lt;span style="color: #40a070"&gt;2&lt;/span&gt;),&lt;span style="color: #40a070"&gt;3&lt;/span&gt;)&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; k1&lt;span style="color: #666666"&gt;==&lt;/span&gt;&lt;span style="color: #40a070"&gt;1.0&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;or&lt;/span&gt; k2&lt;span style="color: #666666"&gt;==&lt;/span&gt;&lt;span style="color: #40a070"&gt;1.0&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;or&lt;/span&gt; k3&lt;span style="color: #666666"&gt;==&lt;/span&gt;&lt;span style="color: #40a070"&gt;1.0&lt;/span&gt;:&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;right&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;elif&lt;/span&gt; k1&lt;span style="color: #666666"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #40a070"&gt;1.0&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;or&lt;/span&gt; k2&lt;span style="color: #666666"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #40a070"&gt;1.0&lt;/span&gt; &lt;span style="color: #007020; font-weight: bold"&gt;or&lt;/span&gt; k3&lt;span style="color: #666666"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #40a070"&gt;1.0&lt;/span&gt;:&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;obtuse&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;else&lt;/span&gt;:&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;acute&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;ComputeResults&lt;/span&gt;():&lt;br /&gt;    out &lt;span style="color: #666666"&gt;=&lt;/span&gt; []&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;for&lt;/span&gt; i,s &lt;span style="color: #007020; font-weight: bold"&gt;in&lt;/span&gt; &lt;span style="color: #007020"&gt;enumerate&lt;/span&gt;(ReadFile()):&lt;br /&gt;        pt &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;map&lt;/span&gt;(&lt;span style="color: #007020"&gt;int&lt;/span&gt;,s&lt;span style="color: #666666"&gt;.&lt;/span&gt;rstrip()&lt;span style="color: #666666"&gt;.&lt;/span&gt;split())&lt;br /&gt;        &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; pt&lt;span style="color: #666666"&gt;.&lt;/span&gt;__len__() &lt;span style="color: #666666"&gt;!=&lt;/span&gt; &lt;span style="color: #40a070"&gt;1&lt;/span&gt;:&lt;br /&gt;            tr &lt;span style="color: #666666"&gt;=&lt;/span&gt; IsTriangle(pt)&lt;br /&gt;            st &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;br /&gt;            at &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; tr &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;triangle&amp;#39;&lt;/span&gt;:&lt;br /&gt;                st &lt;span style="color: #666666"&gt;=&lt;/span&gt; SideType(pt) &lt;span style="color: #666666"&gt;+&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;br /&gt;                at &lt;span style="color: #666666"&gt;=&lt;/span&gt; AngleType(pt) &lt;span style="color: #666666"&gt;+&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;br /&gt;            tot &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;Case #&amp;#39;&lt;/span&gt; &lt;span style="color: #666666"&gt;+&lt;/span&gt; &lt;span style="color: #007020"&gt;str&lt;/span&gt;(i) &lt;span style="color: #666666"&gt;+&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;: &amp;#39;&lt;/span&gt; &lt;span style="color: #666666"&gt;+&lt;/span&gt; st &lt;span style="color: #666666"&gt;+&lt;/span&gt; at &lt;span style="color: #666666"&gt;+&lt;/span&gt; tr &lt;span style="color: #666666"&gt;+&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color: #4070a0; font-weight: bold"&gt;\n&lt;/span&gt;&lt;span style="color: #4070a0"&gt;&amp;#39;&lt;/span&gt;&lt;br /&gt;            out&lt;span style="color: #666666"&gt;.&lt;/span&gt;append(tot)&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;return&lt;/span&gt; out&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #06287e"&gt;WriteFile&lt;/span&gt;(lst):&lt;br /&gt;    &lt;span style="color: #4070a0; font-style: italic"&gt;&amp;quot;&amp;quot;&amp;quot; Write results to data file&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    path &lt;span style="color: #666666"&gt;=&lt;/span&gt; sys&lt;span style="color: #666666"&gt;.&lt;/span&gt;path[&lt;span style="color: #40a070"&gt;0&lt;/span&gt;]&lt;br /&gt;    f &lt;span style="color: #666666"&gt;=&lt;/span&gt; &lt;span style="color: #007020"&gt;open&lt;/span&gt;(path &lt;span style="color: #666666"&gt;+&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;/A-large.out&amp;#39;&lt;/span&gt;,&lt;span style="color: #4070a0"&gt;&amp;#39;w&amp;#39;&lt;/span&gt;)&lt;br /&gt;    f&lt;span style="color: #666666"&gt;.&lt;/span&gt;writelines(lst)&lt;br /&gt;    f&lt;span style="color: #666666"&gt;.&lt;/span&gt;close()&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #007020; font-weight: bold"&gt;if&lt;/span&gt; __name__ &lt;span style="color: #666666"&gt;==&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:&lt;br /&gt;    t1 &lt;span style="color: #666666"&gt;=&lt;/span&gt; time&lt;span style="color: #666666"&gt;.&lt;/span&gt;time()&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #40a070"&gt;1000&lt;/span&gt;&lt;br /&gt;    res &lt;span style="color: #666666"&gt;=&lt;/span&gt; ComputeResults()&lt;br /&gt;    t2 &lt;span style="color: #666666"&gt;=&lt;/span&gt; time&lt;span style="color: #666666"&gt;.&lt;/span&gt;time()&lt;span style="color: #666666"&gt;*&lt;/span&gt;&lt;span style="color: #40a070"&gt;1000&lt;/span&gt;&lt;br /&gt;    WriteFile(res)&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;Done.&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;Computation time &amp;#39;&lt;/span&gt;,&lt;span style="color: #007020"&gt;round&lt;/span&gt;(t2&lt;span style="color: #666666"&gt;-&lt;/span&gt;t1,&lt;span style="color: #40a070"&gt;3&lt;/span&gt;),&lt;span style="color: #4070a0"&gt;&amp;#39;ms&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #007020; font-weight: bold"&gt;print&lt;/span&gt; &lt;span style="color: #4070a0"&gt;&amp;#39;Results are written in file A-large.out&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Have fun !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-6556810989068156022?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/6556810989068156022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=6556810989068156022&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/6556810989068156022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/6556810989068156022'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/07/google-codejam-2008-contest-practice.html' title='Google codejam 2008 contest practice test'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-7710064430651662921</id><published>2008-06-10T09:15:00.000-07:00</published><updated>2009-10-04T10:26:49.403-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sudoku solver'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><title type='text'>Project Euler p96 - solving sudoku</title><content type='html'>This is interesting one. Problem description:&lt;br /&gt;-----------------------------------------------&lt;br /&gt;Su Doku (Japanese meaning number place) is the name given to a popular puzzle concept. Its origin is unclear, but credit must be attributed to Leonhard Euler who invented a similar, and much more difficult, puzzle idea called Latin Squares. The objective of Su Doku puzzles, however, is to replace the blanks (or zeros) in a 9 by 9 grid in such that each row, column, and 3 by 3 box contains each of the digits 1 to 9. Below is an example of a typical starting puzzle grid and its solution grid.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;0 0 3  0 2 0  6 0 0&lt;br /&gt;9 0 0  3 0 5  0 0 1&lt;br /&gt;0 0 1  8 0 6  4 0 0&lt;br /&gt;&lt;br /&gt;0 0 8  1 0 2  9 0 0&lt;br /&gt;7 0 0  0 0 0  0 0 8&lt;br /&gt;0 0 6  7 0 8  2 0 0&lt;br /&gt;&lt;br /&gt;0 0 2  6 0 9  5 0 0&lt;br /&gt;8 0 0  2 0 3  0 0 9&lt;br /&gt;0 0 5  0 1 0  3 0 0&lt;br /&gt;===================&lt;br /&gt;4 8 3  9 2 1  6 5 7&lt;br /&gt;9 6 7  3 4 5  8 2 1&lt;br /&gt;2 5 1  8 7 6  4 9 3&lt;br /&gt;&lt;br /&gt;5 4 8  1 3 2  9 7 6&lt;br /&gt;7 2 9  5 6 4  1 3 8&lt;br /&gt;1 3 6  7 9 8  2 4 5&lt;br /&gt;&lt;br /&gt;3 7 2  6 8 9  5 1 4&lt;br /&gt;8 1 4  2 5 3  7 6 9&lt;br /&gt;6 9 5  4 1 7  3 8 2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A well constructed Su Doku puzzle has a unique solution and can be solved by logic, although it may be necessary to employ "guess and test" methods in order to eliminate options (there is much contested opinion over this). The complexity of the search determines the difficulty of the puzzle; the example above is considered easy because it can be solved by straight forward direct deduction.&lt;br /&gt;&lt;br /&gt;The 6K text file, &lt;a href="http://projecteuler.net/project/sudoku.txt"&gt;sudoku.txt&lt;/a&gt; (right click and 'Save Link/Target As...'), contains fifty different Su Doku puzzles ranging in difficulty, but all with unique solutions (the first puzzle in the file is the example above).&lt;br /&gt;&lt;br /&gt;By solving all fifty puzzles find the sum of the 3-digit numbers found in the top left corner of each solution grid; for example, 483 is the 3-digit number found in the top left corner of the solution grid above.&lt;br /&gt;-----------------------------------------------&lt;br /&gt;&lt;br /&gt;Well, back to more understandable language like C# :-). Solution is done as semi brute-force, iterative method. Solution is quick enough - fifty puzzles are solved in just 122 ms. So this is it:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Program&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        static int[][][] ReadSudoku(string file)&lt;br /&gt;        {&lt;br /&gt;            StreamReader sr = new StreamReader(file);&lt;br /&gt;            int[][][] res = new int[50][][];&lt;br /&gt;            int row = 0;&lt;br /&gt;            int sud = -1;&lt;br /&gt;            string line;&lt;br /&gt;&lt;br /&gt;            while (!sr.EndOfStream)&lt;br /&gt;            {&lt;br /&gt;                line = sr.ReadLine();&lt;br /&gt;                if (line.ToLower().IndexOf("grid") &gt; -1)&lt;br /&gt;                {&lt;br /&gt;                    row = 0;&lt;br /&gt;                    sud++;&lt;br /&gt;                    res[sud] = new int[9][];&lt;br /&gt;                }&lt;br /&gt;                else&lt;br /&gt;                {&lt;br /&gt;                    res[sud][row] = Array.ConvertAll&lt;char,int&gt;(line.ToCharArray(), c =&gt; &lt;br /&gt;                                    { return int.Parse(c.ToString()); });&lt;br /&gt;                    row++;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            sr.Close();&lt;br /&gt;&lt;br /&gt;            return res;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void ShowSudoku(int[][] sud)&lt;br /&gt;        {&lt;br /&gt;            string o;&lt;br /&gt;            o = sud.Aggregate("", (agg, next) =&gt;&lt;br /&gt;            {&lt;br /&gt;                return agg +&lt;br /&gt;                    ((agg == "") ? "":"\n") +&lt;br /&gt;                    next.Aggregate("|", (agg2, next2) =&gt; { &lt;br /&gt;                        return agg2 + next2.ToString(); }) + "|";&lt;br /&gt;            });&lt;br /&gt;            o = "-----------\n" + o + "\n-----------";&lt;br /&gt;            o = o.Replace("0", ".");&lt;br /&gt;            Console.Write(o);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static bool ValueIsValid(int[][] grid, int val, int row, int col)&lt;br /&gt;        {&lt;br /&gt;            int regc, regr;&lt;br /&gt;            int lc, lr;&lt;br /&gt;&lt;br /&gt;            if (val == 0)&lt;br /&gt;                return false;&lt;br /&gt;&lt;br /&gt;            // checking row and column&lt;br /&gt;            for (int i = 0; i &lt; 9; i++)&lt;br /&gt;                if ((grid[row][i] == val &amp;&amp; i != col) || &lt;br /&gt;                    (grid[i][col] == val &amp;&amp; i != row))&lt;br /&gt;                    return false;&lt;br /&gt;            &lt;br /&gt;            // checking 3x3 region&lt;br /&gt;            regr = 3*(row / 3);&lt;br /&gt;            regc = 3*(col / 3);&lt;br /&gt;            for (int i = 0; i &lt; 3; i++)&lt;br /&gt;            {&lt;br /&gt;                lc = regc + i;&lt;br /&gt;                for (int j = 0; j &lt; 3; j++)&lt;br /&gt;                {&lt;br /&gt;                    lr = regr + j;&lt;br /&gt;                    if (lc != col || lr != row)&lt;br /&gt;                        if (grid[lr][lc] == val)&lt;br /&gt;                            return false;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return true;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void CellWithMinValid(int[][] grid, &lt;br /&gt;                                    out int rowo, &lt;br /&gt;                                    out int colo)&lt;br /&gt;        {&lt;br /&gt;            int row = -1, col = -1;&lt;br /&gt;            int minvalid = 9;&lt;br /&gt;            int valcount;&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &lt; grid.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                for (int j = 0; j &lt; grid[i].Length; j++)&lt;br /&gt;                {&lt;br /&gt;                    if (grid[i][j] == 0)&lt;br /&gt;                    {&lt;br /&gt;                        valcount = 0;&lt;br /&gt;                        for (int k = 1; k &lt; 10; k++)&lt;br /&gt;                            if (ValueIsValid(grid, k, i, j))&lt;br /&gt;                                valcount++;&lt;br /&gt;                        if (valcount &lt; minvalid)&lt;br /&gt;                        {&lt;br /&gt;                            minvalid = valcount;&lt;br /&gt;                            row = i;&lt;br /&gt;                            col = j;&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                    if (minvalid == 1) break;&lt;br /&gt;                }&lt;br /&gt;                if (minvalid == 1) break;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            rowo = row;&lt;br /&gt;            colo = col;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void SolveSudoku(int[][] grid)&lt;br /&gt;        {&lt;br /&gt;            int row, col;&lt;br /&gt;            int curval;&lt;br /&gt;            int iter;&lt;br /&gt;            bool force;&lt;br /&gt;            int[,] steps = new int[81, 2];&lt;br /&gt;&lt;br /&gt;            CellWithMinValid(grid, out row, out col);&lt;br /&gt;            grid[row][col] = 1;&lt;br /&gt;            steps[0, 0] = row;&lt;br /&gt;            steps[0, 1] = col;&lt;br /&gt;            force = false;&lt;br /&gt;            iter = 0;&lt;br /&gt;&lt;br /&gt;            while (row &gt; -1)&lt;br /&gt;            {&lt;br /&gt;                curval = grid[steps[iter, 0]]&lt;br /&gt;                             [steps[iter, 1]];&lt;br /&gt;                if (ValueIsValid(grid, curval, &lt;br /&gt;                                steps[iter, 0], &lt;br /&gt;                                steps[iter, 1]) &amp;&amp; !force)&lt;br /&gt;                {&lt;br /&gt;                    CellWithMinValid(grid, out row, out col);&lt;br /&gt;                    if (row != -1)&lt;br /&gt;                    {&lt;br /&gt;                        force = false;&lt;br /&gt;                        iter++;&lt;br /&gt;                        grid[row][col] = 1;&lt;br /&gt;                        steps[iter, 0] = row;&lt;br /&gt;                        steps[iter, 1] = col;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;                else&lt;br /&gt;                {&lt;br /&gt;                    curval++;&lt;br /&gt;                    if (curval &lt; 10)&lt;br /&gt;                    {&lt;br /&gt;                        grid[steps[iter, 0]]&lt;br /&gt;                            [steps[iter, 1]] = curval;&lt;br /&gt;                        force = false;&lt;br /&gt;                    }&lt;br /&gt;                    else&lt;br /&gt;                    {&lt;br /&gt;                        grid[steps[iter, 0]]&lt;br /&gt;                            [steps[iter, 1]] = 0;&lt;br /&gt;                        force = true;&lt;br /&gt;                        iter--;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void SolveAll(string file)&lt;br /&gt;        {&lt;br /&gt;            int[][][] sud = ReadSudoku(file);&lt;br /&gt;            int tot = 0;&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &lt; sud.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                SolveSudoku(sud[i]);&lt;br /&gt;                tot += (sud[i][0][0] * 100) + &lt;br /&gt;                    (sud[i][0][1] * 10) + &lt;br /&gt;                    (sud[i][0][2]);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            Console.WriteLine("Answer to projectEuler {0}\nLast sudoku solution:\n",tot);&lt;br /&gt;            ShowSudoku(sud[49]);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            System.Diagnostics.Stopwatch sw = &lt;br /&gt;                new System.Diagnostics.Stopwatch();&lt;br /&gt;            sw.Start();&lt;br /&gt;            SolveAll("C:\\ProjectEuler\\sudoku.txt");&lt;br /&gt;            sw.Stop();&lt;br /&gt;            Console.WriteLine("\n50-ty sudoku`s solved in {0} ms", &lt;br /&gt;                            sw.ElapsedMilliseconds);&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As always - have fun!.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-7710064430651662921?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/7710064430651662921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=7710064430651662921&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/7710064430651662921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/7710064430651662921'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/06/project-euler-p96-solving-sudoku.html' title='Project Euler p96 - solving sudoku'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-3459633502629307311</id><published>2008-05-29T08:49:00.000-07:00</published><updated>2009-10-04T10:24:33.630-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='array programming language'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><category scheme='http://www.blogger.com/atom/ns#' term='J'/><title type='text'>J and Project Euler p35</title><content type='html'>Problem definition:&lt;br /&gt;------------------------------------------&lt;br /&gt;The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.&lt;br /&gt;&lt;br /&gt;There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.&lt;br /&gt;&lt;br /&gt;How many circular primes are there below one million?&lt;br /&gt;------------------------------------------&lt;br /&gt;&lt;br /&gt;This time again solution in J language:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   rot =: |: ". (i.@:#) ((({:,}:) ^: )) (@: ":)&lt;br /&gt;   ffac =: 0{|: @: q: @: rot&lt;br /&gt;   circ =: ((+/@: (ffac = rot)) = (#@:":))&lt;br /&gt;   tot =: +/ @: (circ"0) @: (2&amp;+)&lt;br /&gt;   tot i.999998&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-3459633502629307311?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/3459633502629307311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=3459633502629307311&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/3459633502629307311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/3459633502629307311'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/05/j-and-project-euler-p35.html' title='J and Project Euler p35'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-8821492955154226251</id><published>2008-05-27T11:27:00.001-07:00</published><updated>2009-10-04T10:21:14.738-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='array programming language'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><category scheme='http://www.blogger.com/atom/ns#' term='J'/><title type='text'>Learning J language - euler problem36</title><content type='html'>Project euler problem 36 definition:&lt;br /&gt;--------------------------------------&lt;br /&gt;The decimal number, 585 = 1001001001 (binary), is palindromic in both bases.&lt;br /&gt;&lt;br /&gt;Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2.&lt;br /&gt;&lt;br /&gt;(Please note that the palindromic number, in either base, may not include leading zeros.)&lt;br /&gt;--------------------------------------&lt;br /&gt;&lt;br /&gt;So, I has some interest in &lt;a href="http://en.wikipedia.org/wiki/J_(programming_language)"&gt;array programming language J&lt;/a&gt;. I try to learn it a bit. And as such, I tried to solve this euler problem with the help of J language. What I learned is that this J language is VERY powerful and also it`s programs is very short, but also it is very hard to learn this language and of course - hard to understand the code (if you don`t know the language). But as soon as you proceed - more things are showing up from the fog :-).&lt;br /&gt;&lt;br /&gt;So this is the solution:&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;+/@:((0:`(0&amp;+))@.((+/@:(=|.)=#)@:":*.(+/@:(=|.)=#)@:#:)"0)i.1000000&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;One shot - One Kill, oh sorry, I mean: One line - One Goal :-)&lt;br /&gt;&lt;br /&gt;As you see this code is not much understandable, but I have a little bit more readable code, acctually code is the same- just with defined function names.&lt;br /&gt;This is it:&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;equalbits=: +/@:(=|.)&lt;br /&gt;decpalind =: (equalbits=#)@:":&lt;br /&gt;binpalind =: (equalbits=#)@:#:&lt;br /&gt;bothpalind =: (decpalind*.binpalind)"0&lt;br /&gt;palindsum =: +/@:((0:`(0&amp;+))@.bothpalind)&lt;br /&gt;palindsum i.1000000&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;Also just 6 lines of code. And a bit more readable, but not more if you don`t know some J basics. This language is very powerfull - especially at data processing.&lt;br /&gt;If you want to learn J some basics, I would recommend &lt;a href="http://www.jsoftware.com/help/learning/contents.htm"&gt;this online book&lt;/a&gt; (also comes for free as documentation in J installation pack). Note - J interpreter is also free. This book is very good introduction, without it I would not take a look at J.&lt;br /&gt;So all in all J - powerfull,interesting,strange,hard language in the same time, IMHO.&lt;br /&gt;Have fun !!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-8821492955154226251?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/8821492955154226251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=8821492955154226251&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/8821492955154226251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/8821492955154226251'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/05/learning-j-language-euler-problem36.html' title='Learning J language - euler problem36'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-910924026397991558</id><published>2008-05-21T05:11:00.000-07:00</published><updated>2009-10-04T10:18:46.241-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><title type='text'>Project Euler p102 - finding origin</title><content type='html'>Problem description:&lt;br /&gt;-----------------------------------------------------&lt;br /&gt;Three distinct points are plotted at random on a Cartesian plane, for which -1000 ≤ x, y ≤ 1000, such that a triangle is formed.&lt;br /&gt;&lt;br /&gt;Consider the following two triangles:&lt;br /&gt;&lt;br /&gt;A(-340,495), B(-153,-910), C(835,-947)&lt;br /&gt;&lt;br /&gt;X(-175,41), Y(-421,-714), Z(574,-645)&lt;br /&gt;&lt;br /&gt;It can be verified that triangle ABC contains the origin, whereas triangle XYZ does not.&lt;br /&gt;&lt;br /&gt;Using &lt;a href="http://projecteuler.net/project/triangles.txt"&gt;triangles.txt&lt;/a&gt; (right click and 'Save Link/Target As...'), a 27K text file containing the co-ordinates of one thousand "random" triangles, find the number of triangles for which the interior contains the origin.&lt;br /&gt;&lt;br /&gt;NOTE: The first two examples in the file represent the triangles in the example given above.&lt;br /&gt;-----------------------------------------------------&lt;br /&gt;&lt;br /&gt;I`ve exploited the idea that for origin to be in the triangle interior, triangle lines segments should cross x and y axis 2 times: x+ / x- and y+ / y-.&lt;br /&gt;Basically it is enough to check does triangle cross y+ and y- axis parts, but I didn`t know that and checked both axis. This worked too :-)&lt;br /&gt;&lt;br /&gt;Solution ( C# as always):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.IO;&lt;br /&gt;&lt;br /&gt;namespace ConsoleApplication1&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static int[][] ReadTriangleCoordinates(string file)&lt;br /&gt;        {&lt;br /&gt;            int[][] res;&lt;br /&gt;            StreamReader sr = new StreamReader(file);&lt;br /&gt;            res = Array.ConvertAll(sr.ReadToEnd().TrimEnd().Split("\n".ToCharArray()), &lt;br /&gt;                  s =&gt; {return Array.ConvertAll(s.Split(",".ToCharArray()),&lt;br /&gt;                                         n =&gt; { return int.Parse(n); }) ;});&lt;br /&gt;            sr.Close();&lt;br /&gt;            return res;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void CrossesAxisAt(int x1, &lt;br /&gt;                                  int y1, &lt;br /&gt;                                  int x2, &lt;br /&gt;                                  int y2, &lt;br /&gt;                                  out double? xAt, &lt;br /&gt;                                  out double? yAt)&lt;br /&gt;        {&lt;br /&gt;            int dx = x2 - x1;&lt;br /&gt;            int dy = y2 - y1;&lt;br /&gt;            int xmin = Math.Min(x1, x2);&lt;br /&gt;            int ymin = Math.Min(y1, y2);&lt;br /&gt;            int xmax = Math.Max(x1, x2);&lt;br /&gt;            int ymax = Math.Max(y1, y2);&lt;br /&gt;            double? xcross;&lt;br /&gt;            double? ycross;&lt;br /&gt;            double a;&lt;br /&gt;            double b;&lt;br /&gt;&lt;br /&gt;            if (dx == 0)&lt;br /&gt;            {&lt;br /&gt;                xcross = x1;&lt;br /&gt;                ycross = null;&lt;br /&gt;            }&lt;br /&gt;            else if (dy == 0)&lt;br /&gt;            {&lt;br /&gt;                xcross = null;&lt;br /&gt;                ycross = y1;&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                a = (double)dy / (double)dx;&lt;br /&gt;                b = y1 - (a * x1);&lt;br /&gt;                xcross = -(b / a);&lt;br /&gt;                ycross = b;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            if (xcross != null)&lt;br /&gt;            {&lt;br /&gt;                if (xcross &lt; xmin || xcross &gt; xmax &lt;br /&gt;                                  || ymin &gt; 0 || ymax &lt; 0)&lt;br /&gt;                    xcross = null;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            if (ycross != null)&lt;br /&gt;            {&lt;br /&gt;                if (ycross &lt; ymin || ycross &gt; ymax &lt;br /&gt;                                  || xmin &gt; 0 || xmax &lt; 0)&lt;br /&gt;                    ycross = null;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            xAt = xcross;&lt;br /&gt;            yAt = ycross;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static bool ContainsOrigin(int[] abc)&lt;br /&gt;        {&lt;br /&gt;            double? xc1, xc2, xc3;&lt;br /&gt;            double? yc1, yc2, yc3;&lt;br /&gt;            int xposc = 0, xnegc = 0, yposc = 0, ynegc = 0;&lt;br /&gt;            bool res;&lt;br /&gt;&lt;br /&gt;            CrossesAxisAt(abc[0], abc[1], abc[4], abc[5], out xc1, out yc1);&lt;br /&gt;            CrossesAxisAt(abc[0], abc[1], abc[2], abc[3], out xc2, out yc2);&lt;br /&gt;            CrossesAxisAt(abc[2], abc[3], abc[4], abc[5], out xc3, out yc3);&lt;br /&gt;&lt;br /&gt;            xposc = ((xc1 &gt; 0) ? 1 : 0) + ((xc2 &gt; 0) ? 1 : 0) + ((xc3 &gt; 0) ? 1 : 0);&lt;br /&gt;            xnegc = ((xc1 &lt; 0) ? 1 : 0) + ((xc2 &lt; 0) ? 1 : 0) + ((xc3 &lt; 0) ? 1 : 0);&lt;br /&gt;            yposc = ((yc1 &gt; 0) ? 1 : 0) + ((yc2 &gt; 0) ? 1 : 0) + ((yc3 &gt; 0) ? 1 : 0);&lt;br /&gt;            ynegc = ((yc1 &lt; 0) ? 1 : 0) + ((yc2 &lt; 0) ? 1 : 0) + ((yc3 &lt; 0) ? 1 : 0);&lt;br /&gt;&lt;br /&gt;            if (xposc &gt; 0 &amp;&amp; xnegc &gt; 0 &amp;&amp; yposc &gt; 0 &amp;&amp; ynegc &gt; 0)&lt;br /&gt;                res = true;&lt;br /&gt;            else&lt;br /&gt;                res = false;&lt;br /&gt;&lt;br /&gt;            return res;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static int TrianglesWithOrigin(string file)&lt;br /&gt;        {&lt;br /&gt;            int[][] tr = ReadTriangleCoordinates(file);&lt;br /&gt;            int trcount = 0;&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &lt; tr.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                if (ContainsOrigin(tr[i]))&lt;br /&gt;                    trcount++;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return trcount;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(TrianglesWithOrigin("C:\\ProjectEuler\\triangles.txt"));&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-910924026397991558?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/910924026397991558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=910924026397991558&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/910924026397991558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/910924026397991558'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/05/project-euler-p102-finding-origin.html' title='Project Euler p102 - finding origin'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-896416491935782634</id><published>2008-05-18T12:21:00.000-07:00</published><updated>2009-10-04T10:17:11.882-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='IBM ponder this'/><category scheme='http://www.blogger.com/atom/ns#' term='cellular automaton'/><title type='text'>IBM Ponder This, May 2008 - cellular automaton</title><content type='html'>From the IBM project "ponder this", may 2008:&lt;br /&gt;-------------------------------------------------&lt;br /&gt;This month's puzzle is about Conway's Game of life.&lt;br /&gt;The game is a cellular automaton on a grid where in each generation, every cell determines its state (dead or alive) based on its eight neighbors: a dead cell will change its state to alive if and only if exactly three of its neighbors are alive; A live cell will stay alive if and only if two or three of its neighbors are alive.&lt;br /&gt;All the changes are done simultaneously.&lt;br /&gt;Find a possible state of the universe whose &lt;b&gt;next&lt;/b&gt; generation is depicted below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;....................&lt;br /&gt;....................&lt;br /&gt;..###..###...#...#..&lt;br /&gt;...#....#.#..##.##..&lt;br /&gt;...#....##...#.#.#..&lt;br /&gt;...#....#.#..#...#..&lt;br /&gt;..###..###...#...#..&lt;br /&gt;....................&lt;br /&gt;....................&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;"." denotes dead cells and "#" denotes live cells.&lt;br /&gt;-------------------------------------------------&lt;br /&gt;&lt;br /&gt;So after a bit of thinking i chose Selfish Gene Algorithm, which I also presented on &lt;a href="http://coding-experiments.blogspot.com/2008/04/selfish-gene-algorithm.html"&gt;my blog article&lt;/a&gt;. Please note - I will present solution which will use 4 classes from the given my blog link above. So if you need to test this solution - download the code from that article also and import these classes:&lt;br /&gt;- SGAallele.cs&lt;br /&gt;- SGAgenotype.cs&lt;br /&gt;- SGAlocus.cs&lt;br /&gt;- SGAlocusGroup.cs&lt;br /&gt;Now about solution. In general - solution with the help of selfish gene algorithm, tries to evolve cellular automaton configuration which next generation is similar to the one described in problem definition. Fitness is calculated as wrong cell amount - that is cell, which is not in place of target configuration, amount. Algorithm tries to minimize that wrong cell amount. So solution is this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using SGA;&lt;br /&gt;&lt;br /&gt;namespace ConsoleApplication18&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static int counter = 0;&lt;br /&gt;        static bool[][] grid = InitialGrid();&lt;br /&gt;        static SGAgenotype gen;&lt;br /&gt;&lt;br /&gt;        static void ShowCells(bool[][] cells)&lt;br /&gt;        {&lt;br /&gt;            string outp;&lt;br /&gt;            outp = cells.Aggregate("", (acc1, ba) =&gt; &lt;br /&gt;                                   acc1 + ba.Aggregate("", (acc2, b) =&gt; &lt;br /&gt;                                        acc2 + ((b) ? "#" : ".")) + "\n");&lt;br /&gt;            Console.Write(outp);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static bool[][] InitialGrid()&lt;br /&gt;        {&lt;br /&gt;            bool[][] c = new bool[9][];&lt;br /&gt;            c[0] = new bool[20];&lt;br /&gt;            c[1] = new bool[20];&lt;br /&gt;            c[2] = new bool[] { false, false, true, true, true, false, false, &lt;br /&gt;                                true, true, true, false, false, false, true, &lt;br /&gt;                                false, false, false, true, false, false };&lt;br /&gt;            c[3] = new bool[] { false, false, false, true, false, false, false, &lt;br /&gt;                                false, true, false, true, false, false, true, &lt;br /&gt;                                true, false, true, true, false, false };&lt;br /&gt;            c[4] = new bool[] { false, false, false, true, false, false, false, &lt;br /&gt;                                false, true, true, false, false, false, true, &lt;br /&gt;                                false, true, false, true, false, false };&lt;br /&gt;            c[5] = new bool[] { false, false, false, true, false, false, false, &lt;br /&gt;                                false, true, false, true, false, false, true, &lt;br /&gt;                                false, false, false, true, false, false };&lt;br /&gt;            c[6] = new bool[] { false, false, true, true, true, false, false, true, &lt;br /&gt;                                true, true, false, false, false, true, false, &lt;br /&gt;                                false, false, true, false, false };&lt;br /&gt;            c[7] = new bool[20];&lt;br /&gt;            c[8] = new bool[20];&lt;br /&gt;&lt;br /&gt;            return c;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static int LiveCells(bool[][] grid, int row, int col)&lt;br /&gt;        {&lt;br /&gt;            int live = 0;&lt;br /&gt;&lt;br /&gt;            for (int i = row - 1; i &lt;= row + 1; i++)&lt;br /&gt;            {&lt;br /&gt;                for (int j = col - 1; j &lt;= col + 1; j++)&lt;br /&gt;                {&lt;br /&gt;                    if (i != row || j != col)&lt;br /&gt;                    {&lt;br /&gt;                        if (grid[i][j])&lt;br /&gt;                            live++;&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return live;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static bool WillLive(bool IsLive, int LiveNeighbours)&lt;br /&gt;        {&lt;br /&gt;            bool state;&lt;br /&gt;&lt;br /&gt;            if (IsLive)&lt;br /&gt;                state = (LiveNeighbours &lt; 2 || LiveNeighbours &gt; 3) ? false : true;&lt;br /&gt;            else&lt;br /&gt;                state = (LiveNeighbours == 3) ? true : false;&lt;br /&gt;           &lt;br /&gt;            return state;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static bool[][] ComputeStates(bool[][] grid)&lt;br /&gt;        {&lt;br /&gt;            bool[][] res = new bool[9][];&lt;br /&gt;            res[0] = new bool[20];&lt;br /&gt;            res[1] = new bool[20];&lt;br /&gt;            res[2] = new bool[20];&lt;br /&gt;            res[3] = new bool[20];&lt;br /&gt;            res[4] = new bool[20];&lt;br /&gt;            res[5] = new bool[20];&lt;br /&gt;            res[6] = new bool[20];&lt;br /&gt;            res[7] = new bool[20];&lt;br /&gt;            res[8] = new bool[20];&lt;br /&gt;&lt;br /&gt;            for (int i = 1; i &lt; grid.Length - 1; i++)&lt;br /&gt;            {&lt;br /&gt;                for (int j = 1; j &lt; grid[i].Length - 1; j++)&lt;br /&gt;                {&lt;br /&gt;                    res[i][j] = WillLive(grid[i][j], LiveCells(grid, i, j));&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return res;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static bool[][] CellGridFromGenotype(SGAgenotype gen, SGAgenotype.GenomeNo num)&lt;br /&gt;        {&lt;br /&gt;            int row, col;&lt;br /&gt;            bool v;&lt;br /&gt;            int gene = -1;&lt;br /&gt;            bool[][] res = new bool[9][];&lt;br /&gt;            res[0] = new bool[20];&lt;br /&gt;            res[1] = new bool[20];&lt;br /&gt;            res[2] = new bool[20];&lt;br /&gt;            res[3] = new bool[20];&lt;br /&gt;            res[4] = new bool[20];&lt;br /&gt;            res[5] = new bool[20];&lt;br /&gt;            res[6] = new bool[20];&lt;br /&gt;            res[7] = new bool[20];&lt;br /&gt;            res[8] = new bool[20];&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &lt; gen.locusGroups.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                row = (i) / 20;&lt;br /&gt;                col = (i) - (row * 20);&lt;br /&gt;&lt;br /&gt;                if (num == SGAgenotype.GenomeNo.FirstGenome)&lt;br /&gt;                    gene = gen.locusGroups[i].loci[0].FirstGeneIndex;&lt;br /&gt;                else if (num == SGAgenotype.GenomeNo.SecondGenome)&lt;br /&gt;                    gene = gen.locusGroups[i].loci[0].SecondGeneIndex;&lt;br /&gt;                else if (num == SGAgenotype.GenomeNo.None)&lt;br /&gt;                    gene = gen.locusGroups[i].loci[0].BestGeneIndex;&lt;br /&gt;&lt;br /&gt;                v = Convert.ToBoolean(gen.locusGroups[i].loci[0].Alleles[gene].Value);&lt;br /&gt;&lt;br /&gt;                res[row][col] = v;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return res;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static int WrongCellCount(bool[][] previousStates)&lt;br /&gt;        {&lt;br /&gt;            int res = 0;&lt;br /&gt;            bool[][] nextStates = ComputeStates(previousStates);&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &lt; grid.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                for (int j = 0; j &lt; grid[i].Length; j++)&lt;br /&gt;                {&lt;br /&gt;                    if (nextStates[i][j] != grid[i][j])&lt;br /&gt;                        res++;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return res;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static SGAgenotype.CompareResults CompareCellAutomata()&lt;br /&gt;        {&lt;br /&gt;            SGAgenotype.CompareResults cr;&lt;br /&gt;            bool[][] grid1 = CellGridFromGenotype(gen, SGAgenotype.GenomeNo.FirstGenome);&lt;br /&gt;            bool[][] grid2 = CellGridFromGenotype(gen, SGAgenotype.GenomeNo.SecondGenome);&lt;br /&gt;            bool[][] gridb = CellGridFromGenotype(gen, SGAgenotype.GenomeNo.None);&lt;br /&gt;&lt;br /&gt;            int wcellsGene1 = WrongCellCount(grid1);&lt;br /&gt;            int wcellsGene2 = WrongCellCount(grid2);&lt;br /&gt;            int wcellsGeneb = WrongCellCount(gridb);&lt;br /&gt;&lt;br /&gt;            cr.CompareEachOther = SGAgenotype.GenomeNo.None;&lt;br /&gt;            cr.CompareWithBest = SGAgenotype.GenomeNo.None;&lt;br /&gt;&lt;br /&gt;            if (wcellsGene1 &lt; wcellsGene2)&lt;br /&gt;                cr.CompareEachOther = SGAgenotype.GenomeNo.FirstGenome;&lt;br /&gt;            else if (wcellsGene2 &lt; wcellsGene1)&lt;br /&gt;                cr.CompareEachOther = SGAgenotype.GenomeNo.SecondGenome;&lt;br /&gt;&lt;br /&gt;            if (wcellsGene1 &lt; wcellsGeneb)&lt;br /&gt;                cr.CompareWithBest = SGAgenotype.GenomeNo.FirstGenome;&lt;br /&gt;            else if (wcellsGene2 &lt; wcellsGeneb)&lt;br /&gt;                cr.CompareWithBest = SGAgenotype.GenomeNo.SecondGenome;&lt;br /&gt;&lt;br /&gt;            counter++;&lt;br /&gt;&lt;br /&gt;            if (counter%1000==0)&lt;br /&gt;            {&lt;br /&gt;                Console.Clear();&lt;br /&gt;                ShowCells(gridb);&lt;br /&gt;                Console.WriteLine("====================");&lt;br /&gt;                ShowCells(ComputeStates(gridb));&lt;br /&gt;                Console.WriteLine("====================\nPlease wait...");&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return cr;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            gen = new SGAgenotype(new SGAlocus[] { new SGAlocus(0, 1, 1) }, &lt;br /&gt;                                       180, CompareCellAutomata);&lt;br /&gt;            gen.AlleleAffectValue *= 0.1;&lt;br /&gt;            gen.MutationProbability *= 1.5;&lt;br /&gt;            gen.Evolve(400000);&lt;br /&gt;            Console.WriteLine("DONE.");&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;After execution we get this picture-&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;...............#....&lt;br /&gt;.#....#.....#.....##&lt;br /&gt;...##...##..........&lt;br /&gt;...#....#....##.##.#&lt;br /&gt;....#....##..#...#.#        ANSWER&lt;br /&gt;..#.....#.....#..#..&lt;br /&gt;...#....##..#.....#.&lt;br /&gt;...#..#.....#...#...&lt;br /&gt;....................&lt;br /&gt;====================&lt;br /&gt;....................&lt;br /&gt;....................&lt;br /&gt;..###..###...#...#..&lt;br /&gt;...#....#.#..##.##..&lt;br /&gt;...#....##...#.#.#..    NEXT GENERATION OF CELLS&lt;br /&gt;...#....#.#..#...#..&lt;br /&gt;..##...###...#...#..&lt;br /&gt;....................&lt;br /&gt;....................&lt;br /&gt;====================&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;First picture is answer and second (below) is next generation of cells.&lt;br /&gt;We see that this is approximate answer because next generation differs by 1 cell from the given situation in problem definition. Well, this is because I`ve used genetic algorithm which by definition is probabilistic and doesn`t guarantee to give exact solution. But very well calculates approximate solutions.&lt;br /&gt;So all in all - it was fun to play with selfish gene algorithm and cellular automaton.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-896416491935782634?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/896416491935782634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=896416491935782634&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/896416491935782634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/896416491935782634'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/05/ibm-ponder-this-may-2008-cellular.html' title='IBM Ponder This, May 2008 - cellular automaton'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-1744398218441035746</id><published>2008-05-13T00:05:00.000-07:00</published><updated>2009-10-04T10:14:14.739-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='traveler&apos;s dilemma'/><category scheme='http://www.blogger.com/atom/ns#' term='game theory'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Traveler's dilemma and bonus factor</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Traveler%27s_dilemma"&gt;Traveler's dilemma&lt;/a&gt; description is following (taken from wikipedia):&lt;br /&gt;-------------------------------------------------------&lt;br /&gt;An airline loses two suitcases belonging to two different travelers. Both suitcases happen to be identical and contain identical antiques. An airline manager tasked to settle the claims of both travelers explains that the airline is liable for a maximum of $100 per suitcase, and in order to determine an honest appraised value of the antiques the manager separates both travelers so they can't confer, and asks them to write down the amount of their value at no less than $2 and no larger than $100. He also tells them that if both write down the same number, he will treat that number as the true dollar value of both suitcases and reimburse both travelers that amount. However, if one writes down a smaller number than the other, this smaller number will be taken as the true dollar value, and both travelers will receive that amount along with a bonus/malus: $2 extra will be paid to the traveler who wrote down the lower value and a $2 deduction will be taken from the person who wrote down the higher amount. The challenge is: what strategy should both travelers follow to decide the value they should write down?&lt;br /&gt;-------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Experiment was conducted as following:&lt;br /&gt;- BONUS was chosen between 2 and 20&lt;br /&gt;- Possible travelers request was between BONUS and 100.&lt;br /&gt;- Travelers chooses cost randomly (for no-strategy imitation)&lt;br /&gt;- Cost random selection was repeated 5000000 times&lt;br /&gt;- After that optimal request was calculated as travelers choise which gives the greatest profit.&lt;br /&gt;- And finally these optimal requests are plot in diagram as function of BONUS.&lt;br /&gt;&lt;br /&gt;C# code which conducted experiments on random travelers choise is this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Payoff(int Aoffer, int Boffer, int extra, out int Apayoff, out int Bpayoff)&lt;br /&gt;        {&lt;br /&gt;            int Aextra, Bextra;&lt;br /&gt;            int minoffer = Math.Min(Aoffer, Boffer);&lt;br /&gt;&lt;br /&gt;            if (Aoffer == Boffer)&lt;br /&gt;            {&lt;br /&gt;                Aextra = Bextra = 0;&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                Aextra = (Aoffer == minoffer) ? extra : -extra;&lt;br /&gt;                Bextra = (Boffer == minoffer) ? extra : -extra;&lt;br /&gt;            }&lt;br /&gt;            Apayoff = minoffer + Aextra;&lt;br /&gt;            Bpayoff = minoffer + Bextra;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static long OptimalSelection(int costFrom, int costTo, int goods)&lt;br /&gt;        {&lt;br /&gt;            long[] payoffA = new long[costTo + 1];&lt;br /&gt;            long[] payoffB = new long[costTo + 1];&lt;br /&gt;            Random r = new Random();&lt;br /&gt;            int Ac, Bc;&lt;br /&gt;            int Pa, Pb;&lt;br /&gt;            long Aopt = -1, Bopt = -1;&lt;br /&gt;            long Amax = 0, Bmax = 0;&lt;br /&gt;&lt;br /&gt;            for (int i = 1; i &lt;= goods; i++)&lt;br /&gt;            {&lt;br /&gt;                Ac = r.Next(costFrom, costTo + 1);&lt;br /&gt;                Bc = r.Next(costFrom, costTo + 1);&lt;br /&gt;                Payoff(Ac, Bc, costFrom, out Pa, out Pb);&lt;br /&gt;                payoffA[Ac] += Pa;&lt;br /&gt;                payoffB[Bc] += Pb;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            for (int j = costFrom; j &lt;= costTo; j++)&lt;br /&gt;            {&lt;br /&gt;                if (payoffA[j] &gt; Amax) { Amax = payoffA[j]; Aopt = j; }&lt;br /&gt;                if (payoffB[j] &gt; Bmax) { Bmax = payoffB[j]; Bopt = j; }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return (Aopt + Bopt) / 2;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void MeasureBonusInfluence()&lt;br /&gt;        {&lt;br /&gt;            double[] bonus = Array.ConvertAll(Enumerable.Range(2, 20).ToArray(),&lt;br /&gt;                             v =&gt; (double)(v));&lt;br /&gt;            double[] optimal = Array.ConvertAll(bonus,&lt;br /&gt;                             v =&gt; (double)OptimalSelection((int)v, 100, 5000000));&lt;br /&gt;&lt;br /&gt;            GoogleChart.PlotLineChart(bonus,&lt;br /&gt;                                      optimal,&lt;br /&gt;                                      "Bonus ($)",&lt;br /&gt;                                      "Optimal request ($)",&lt;br /&gt;                                      "Traveler's dilemma - bonus factor",&lt;br /&gt;                                      "400x200");&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            MeasureBonusInfluence();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    class GoogleChart&lt;br /&gt;    {&lt;br /&gt;        public static void PlotLineChart(double[] Xvalues,&lt;br /&gt;                                        double[] Yvalues,&lt;br /&gt;                                        string Xlabel,&lt;br /&gt;                                        string Ylabel,&lt;br /&gt;                                        string Title,&lt;br /&gt;                                        string imgsize)&lt;br /&gt;        {&lt;br /&gt;            string urltemplate = "http://chart.apis.google.com/chart?cht=lxy&amp;chs=@imgsize@&amp;chd=t:@xvalues@%7C@yvalues@&amp;chds=@xmin@,@xmax@,@ymin@,@ymax@&amp;chxr=0,@xmin@,@xmax@%7C1,@ymin@,@ymax@&amp;chxt=x,y,x,y&amp;chxl=2:%7C@xlabel@%7C3:%7C@ylabel@%7C&amp;chxp=2,50%7C3,50&amp;chtt=@title@";&lt;br /&gt;            string xvalagg = Xvalues.Aggregate("", (old, next) =&gt;&lt;br /&gt;                             old + ((old == "") ? "" : ",") + next.ToString(CultureInfo.InvariantCulture));&lt;br /&gt;            string yvalagg = Yvalues.Aggregate("", (old, next) =&gt;&lt;br /&gt;                             old + ((old == "") ? "" : ",") + next.ToString(CultureInfo.InvariantCulture));&lt;br /&gt;&lt;br /&gt;            if (imgsize == null) imgsize = "300x200";&lt;br /&gt;&lt;br /&gt;            urltemplate = urltemplate.Replace("@imgsize@", imgsize);&lt;br /&gt;            urltemplate = urltemplate.Replace("@xvalues@", xvalagg);&lt;br /&gt;            urltemplate = urltemplate.Replace("@yvalues@", yvalagg);&lt;br /&gt;            urltemplate = urltemplate.Replace("@xmin@", Xvalues.Min().ToString(CultureInfo.InvariantCulture));&lt;br /&gt;            urltemplate = urltemplate.Replace("@xmax@", Xvalues.Max().ToString(CultureInfo.InvariantCulture));&lt;br /&gt;            urltemplate = urltemplate.Replace("@ymin@", Yvalues.Min().ToString(CultureInfo.InvariantCulture));&lt;br /&gt;            urltemplate = urltemplate.Replace("@ymax@", Yvalues.Max().ToString(CultureInfo.InvariantCulture));&lt;br /&gt;            urltemplate = urltemplate.Replace("@xlabel@", Xlabel);&lt;br /&gt;            urltemplate = urltemplate.Replace("@ylabel@", Ylabel);&lt;br /&gt;            urltemplate = urltemplate.Replace("@title@", Title);&lt;br /&gt;&lt;br /&gt;            System.Diagnostics.Process.Start(urltemplate);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally after execution of this program, we get this picture of optimal request relation with bonus amount (if travelers chooses randomly):&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_hTm-LSlj8U4/SClIdz9FumI/AAAAAAAAAB4/fvXsgd6WrXM/s1600-h/travel_dil.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_hTm-LSlj8U4/SClIdz9FumI/AAAAAAAAAB4/fvXsgd6WrXM/s400/travel_dil.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5199766921775790690" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-1744398218441035746?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/1744398218441035746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=1744398218441035746&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/1744398218441035746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/1744398218441035746'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/05/travelers-dilemma-and-bonus-factor.html' title='Traveler&apos;s dilemma and bonus factor'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_hTm-LSlj8U4/SClIdz9FumI/AAAAAAAAAB4/fvXsgd6WrXM/s72-c/travel_dil.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-5893167735862710726</id><published>2008-05-07T10:26:00.000-07:00</published><updated>2009-10-04T10:08:38.930-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='chart'/><title type='text'>Google chart API in .NET</title><content type='html'>Yes I know - there are good .NET libraries for using google chart API, but I was interested to dig a little bit deeper into google chart API. And I have to say that google chart is worse than opensource program GNUPLOT (in the sense of functionality), but ok whatever... And second target was - to have as less code (including libraries) as possible for charting VERY simple XY graphs. So after studing a bit google chart documentation- I wrote very primitive class for plotting simple XY graph. For plotting graphs with this code you need:&lt;br /&gt;- Internet connection&lt;br /&gt;- .NET framework 3.5&lt;br /&gt;- Internet browser (whatever you like)&lt;br /&gt;So this is the code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            double[] xval;&lt;br /&gt;            double[] ysin, yexp;&lt;br /&gt;&lt;br /&gt;            xval = new double[] { 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5 };&lt;br /&gt;            ysin = Array.ConvertAll(xval, v =&gt; { return Math.Sin(v); }); &lt;br /&gt;            yexp = Array.ConvertAll(xval, v =&gt; { return Math.Exp(v); }); &lt;br /&gt;            &lt;br /&gt;            GoogleChart.PlotLineChart(xval, ysin, "x values", "sin(x)", "sin(x) function", null);&lt;br /&gt;            GoogleChart.PlotLineChart(xval, yexp, "x values", "exp(x)", "exp(x) function", null);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    class GoogleChart&lt;br /&gt;    {&lt;br /&gt;        public static void PlotLineChart(double[] Xvalues, &lt;br /&gt;                                        double[] Yvalues, &lt;br /&gt;                                        string Xlabel, &lt;br /&gt;                                        string Ylabel, &lt;br /&gt;                                        string Title, &lt;br /&gt;                                        string imgsize)&lt;br /&gt;        {&lt;br /&gt;            string urltemplate = "http://chart.apis.google.com/chart?cht=lxy&amp;chs=@imgsize@&amp;chd=t:@xvalues@%7C@yvalues@&amp;chds=@xmin@,@xmax@,@ymin@,@ymax@&amp;chxr=0,@xmin@,@xmax@%7C1,@ymin@,@ymax@&amp;chxt=x,y,x,y&amp;chxl=2:%7C@xlabel@%7C3:%7C@ylabel@%7C&amp;chxp=2,50%7C3,50&amp;chtt=@title@";&lt;br /&gt;            string xvalagg = Xvalues.Aggregate("", (old, next) =&gt; &lt;br /&gt;                             old + ((old == "") ? "" : ",") + next.ToString(CultureInfo.InvariantCulture));&lt;br /&gt;            string yvalagg = Yvalues.Aggregate("", (old, next) =&gt; &lt;br /&gt;                             old + ((old == "") ? "" : ",") + next.ToString(CultureInfo.InvariantCulture));&lt;br /&gt;&lt;br /&gt;            if (imgsize == null) imgsize = "300x200";&lt;br /&gt;&lt;br /&gt;            urltemplate = urltemplate.Replace("@imgsize@", imgsize);&lt;br /&gt;            urltemplate = urltemplate.Replace("@xvalues@", xvalagg);&lt;br /&gt;            urltemplate = urltemplate.Replace("@yvalues@", yvalagg);&lt;br /&gt;            urltemplate = urltemplate.Replace("@xmin@", Xvalues.Min().ToString(CultureInfo.InvariantCulture));&lt;br /&gt;            urltemplate = urltemplate.Replace("@xmax@", Xvalues.Max().ToString(CultureInfo.InvariantCulture));&lt;br /&gt;            urltemplate = urltemplate.Replace("@ymin@", Yvalues.Min().ToString(CultureInfo.InvariantCulture));&lt;br /&gt;            urltemplate = urltemplate.Replace("@ymax@", Yvalues.Max().ToString(CultureInfo.InvariantCulture));&lt;br /&gt;            urltemplate = urltemplate.Replace("@xlabel@", Xlabel);&lt;br /&gt;            urltemplate = urltemplate.Replace("@ylabel@", Ylabel);&lt;br /&gt;            urltemplate = urltemplate.Replace("@title@", Title);&lt;br /&gt;&lt;br /&gt;            System.Diagnostics.Process.Start(urltemplate);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With this sample code there are generated these nice graphs:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_hTm-LSlj8U4/SCK6A2mb6iI/AAAAAAAAABc/iknDzkR50iY/s1600-h/sin.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_hTm-LSlj8U4/SCK6A2mb6iI/AAAAAAAAABc/iknDzkR50iY/s400/sin.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5197921443758467618" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_hTm-LSlj8U4/SCK6Mmmb6jI/AAAAAAAAABk/JVHQIxFT820/s1600-h/exp.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_hTm-LSlj8U4/SCK6Mmmb6jI/AAAAAAAAABk/JVHQIxFT820/s400/exp.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5197921645621930546" /&gt;&lt;/a&gt;&lt;br /&gt;This is it. Have fun with charting !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-5893167735862710726?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/5893167735862710726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=5893167735862710726&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/5893167735862710726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/5893167735862710726'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/05/google-chart-api-in-net.html' title='Google chart API in .NET'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_hTm-LSlj8U4/SCK6A2mb6iI/AAAAAAAAABc/iknDzkR50iY/s72-c/sin.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-760640245622554221</id><published>2008-05-06T05:44:00.000-07:00</published><updated>2009-10-04T10:04:12.021-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><title type='text'>Project Euler p59 - breaking encryption</title><content type='html'>Problem definition:&lt;br /&gt;------------------------------------------------&lt;br /&gt;Each character on a computer is assigned a unique code and the preferred standard is ASCII (American Standard Code for Information Interchange). For example, uppercase A = 65, asterisk (*) = 42, and lowercase k = 107.&lt;br /&gt;&lt;br /&gt;A modern encryption method is to take a text file, convert the bytes to ASCII, then XOR each byte with a given value, taken from a secret key. The advantage with the XOR function is that using the same encryption key on the cipher text, restores the plain text; for example, 65 XOR 42 = 107, then 107 XOR 42 = 65.&lt;br /&gt;&lt;br /&gt;For unbreakable encryption, the key is the same length as the plain text message, and the key is made up of random bytes. The user would keep the encrypted message and the encryption key in different locations, and without both "halves", it is impossible to decrypt the message.&lt;br /&gt;&lt;br /&gt;Unfortunately, this method is impractical for most users, so the modified method is to use a password as a key. If the password is shorter than the message, which is likely, the key is repeated cyclically throughout the message. The balance for this method is using a sufficiently long password key for security, but short enough to be memorable.&lt;br /&gt;&lt;br /&gt;Your task has been made easy, as the encryption key consists of three lower case characters. Using &lt;a href="http://projecteuler.net/project/cipher1.txt"&gt;cipher1.txt&lt;/a&gt; (right click and 'Save Link/Target As...'), a file containing the encrypted ASCII codes, and the knowledge that the plain text must contain common English words, decrypt the message and find the sum of the ASCII values in the original text.&lt;br /&gt;------------------------------------------------&lt;br /&gt;&lt;br /&gt;C# brute-force solution, running in 42 seconds:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;        static byte[] ReadCipher(string file)&lt;br /&gt;        {&lt;br /&gt;            StreamReader sr = new StreamReader(file);&lt;br /&gt;            string[] buf = sr.ReadToEnd().Trim().Split(",".ToCharArray());&lt;br /&gt;            byte[] res = Array.ConvertAll&lt;string, byte&gt;(buf, s =&gt; { return byte.Parse(s); });&lt;br /&gt;            sr.Close();&lt;br /&gt;&lt;br /&gt;            return res;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static byte[] TryDecipher(byte[] cip, string key)&lt;br /&gt;        {&lt;br /&gt;            int ind = 0;&lt;br /&gt;            byte[] dec = new byte[cip.Length];&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &lt; cip.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                dec[i] = (byte)((int)cip[i] ^ (int)key[ind]);&lt;br /&gt;                ind = (ind &gt;= 2) ? 0 : ind + 1;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return dec;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static int KeywordsInText(string text, string[] keywords)&lt;br /&gt;        {&lt;br /&gt;            int kc = 0;&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &lt; keywords.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                if (text.ToLower().IndexOf(" " + keywords[i] + " ") &gt; -1) kc++;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return (kc*100) / keywords.Length;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void Decipher(string file)&lt;br /&gt;        {&lt;br /&gt;            string[] keywords = new string[] {"the","be","is","are","was","to","of","and","a","in","into","that","have","has","had","I","it","for","not","on","with","he","as","you","do","did","done","at","this","but","his","by","from","they","we","say","her","she","or","an","will","shall","my","one","all","would","should","there","here","their","what","so","up","out","if","about","who","get","got","which","go","went","gone","me"};&lt;br /&gt;            string passchars = "qwertyuioplkjhgfdsazxcvbnm";&lt;br /&gt;            string curkey = "";&lt;br /&gt;            byte[] cipher = ReadCipher(file);&lt;br /&gt;            byte[] decoded = new byte[cipher.Length];&lt;br /&gt;            string dectext;&lt;br /&gt;            int keywordcount = 0;&lt;br /&gt;            int maxkeywords = 0;&lt;br /&gt;            string bestkey = "";&lt;br /&gt;            byte[] bestbytes = new byte[cipher.Length];&lt;br /&gt;            string besttext = "";&lt;br /&gt;            long bytesum = 0;&lt;br /&gt;&lt;br /&gt;            for (int i1 = 0; i1 &lt; passchars.Length; i1++)&lt;br /&gt;            {&lt;br /&gt;                for (int i2 = 0; i2 &lt; passchars.Length; i2++)&lt;br /&gt;                {&lt;br /&gt;                    for (int i3 = 0; i3 &lt; passchars.Length; i3++)&lt;br /&gt;                    {&lt;br /&gt;                        curkey = passchars[i1].ToString() + passchars[i2].ToString() + passchars[i3].ToString();&lt;br /&gt;                        decoded = TryDecipher(cipher, curkey);&lt;br /&gt;                        dectext = ASCIIEncoding.ASCII.GetString(decoded);&lt;br /&gt;                        keywordcount = KeywordsInText(dectext, keywords);&lt;br /&gt;                        &lt;br /&gt;                        if (keywordcount &gt; maxkeywords)&lt;br /&gt;                        {&lt;br /&gt;                            maxkeywords = keywordcount;&lt;br /&gt;                            bestkey = curkey;&lt;br /&gt;                            bestbytes = decoded;&lt;br /&gt;                            besttext = dectext;&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &lt; bestbytes.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                bytesum += (long)bestbytes[i];&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            Console.WriteLine("Byte sum: {0}\nPassword: {1}\nDecoded message 50 chars: {2}\nMessage has {3}% common words",&lt;br /&gt;                                      bytesum,bestkey,besttext.Substring(0,50),maxkeywords);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();&lt;br /&gt;            sw.Start();&lt;br /&gt;            Decipher("C:\\ProjectEuler\\cipher1.txt");&lt;br /&gt;            sw.Stop();&lt;br /&gt;            Console.WriteLine("Decryption time: {0} seconds",sw.Elapsed.Seconds);&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-760640245622554221?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/760640245622554221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=760640245622554221&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/760640245622554221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/760640245622554221'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/05/project-euler-p59-breaking-encryption.html' title='Project Euler p59 - breaking encryption'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-6639180852644612297</id><published>2008-04-29T14:18:00.000-07:00</published><updated>2009-10-04T10:02:40.720-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><title type='text'>Project Euler p79 - cracking passcode</title><content type='html'>This one is very interesting. Problem description:&lt;br /&gt;-------------------------------------------&lt;br /&gt;A common security method used for online banking is to ask the user for three random characters from a passcode. For example, if the passcode was 531278, they may asked for the 2nd, 3rd, and 5th characters; the expected reply would be: 317.&lt;br /&gt;The text file, &lt;a href="http://projecteuler.net/project/keylog.txt"&gt;keylog.txt&lt;/a&gt;, contains fifty successful login attempts.&lt;br /&gt;Given that the three characters are always asked for in order, analyse the file so as to determine the shortest possible secret passcode of unknown length.&lt;br /&gt;-------------------------------------------&lt;br /&gt;&lt;br /&gt;So solution in C# is this, not optimized, but works (in a 16 seconds):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;        static int[] ReadKeyLog(string file)&lt;br /&gt;        {&lt;br /&gt;            int[] dig;&lt;br /&gt;            string buf;&lt;br /&gt;            string[] barr;&lt;br /&gt;            StreamReader sr = new StreamReader(file);&lt;br /&gt;            buf = sr.ReadToEnd().TrimEnd("\n".ToCharArray());&lt;br /&gt;            barr = buf.Split("\n".ToCharArray());&lt;br /&gt;            dig = Array.ConvertAll(barr, s =&gt; { return Int32.Parse(s); });&lt;br /&gt;            sr.Close();&lt;br /&gt;            return dig;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static bool KeyPartExists(long testnumber, int keypart)&lt;br /&gt;        {&lt;br /&gt;            int n1 = keypart / 100;&lt;br /&gt;            int n2 = (keypart / 10) % 10;&lt;br /&gt;            int n3 = keypart % 10;&lt;br /&gt;            bool n1e = false;&lt;br /&gt;            bool n2e = false;&lt;br /&gt;            bool n3e = false;&lt;br /&gt;&lt;br /&gt;            for (long i = testnumber; i &gt; 0; i /= 10)&lt;br /&gt;            {&lt;br /&gt;                if (!n3e)&lt;br /&gt;                    n3e = (i % 10) == n3;&lt;br /&gt;                else&lt;br /&gt;                    if (!n2e)&lt;br /&gt;                        n2e = (i % 10) == n2;&lt;br /&gt;                    else&lt;br /&gt;                        if (!n1e)&lt;br /&gt;                            n1e = (i % 10) == n1;&lt;br /&gt;                        else&lt;br /&gt;                            break;&lt;br /&gt;            }&lt;br /&gt;            if (n1e &amp;&amp; n2e &amp;&amp; n3e)&lt;br /&gt;                return true;&lt;br /&gt;            else&lt;br /&gt;                return false;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static bool HasAllKeyParts(long testnum, int[] keylog)&lt;br /&gt;        {&lt;br /&gt;            bool res = true;&lt;br /&gt;&lt;br /&gt;            for (int i = 0; i &lt; keylog.Length; i++)&lt;br /&gt;            {&lt;br /&gt;                if (!KeyPartExists(testnum, keylog[i]))&lt;br /&gt;                {&lt;br /&gt;                    res = false;&lt;br /&gt;                    break;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            return res;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static long FindPassCode(string file)&lt;br /&gt;        {&lt;br /&gt;            int[] keylog = ReadKeyLog(file);&lt;br /&gt;            long num = 10000;&lt;br /&gt;            &lt;br /&gt;            while (true)&lt;br /&gt;            {&lt;br /&gt;                if (HasAllKeyParts(num, keylog))&lt;br /&gt;                    return num;&lt;br /&gt;                num++;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();&lt;br /&gt;            sw.Start();&lt;br /&gt;            Console.WriteLine("Bruteforced passcode is {0}",&lt;br /&gt;                                FindPassCode("C:\\ProjectEuler\\keylog.txt")&lt;br /&gt;            );&lt;br /&gt;            sw.Stop();&lt;br /&gt;            Console.WriteLine("Cracking time {0} seconds", sw.Elapsed.Seconds);&lt;br /&gt;            Console.ReadLine();&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-6639180852644612297?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/6639180852644612297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=6639180852644612297&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/6639180852644612297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/6639180852644612297'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/04/project-euler-p79-cracking-passcode.html' title='Project Euler p79 - cracking passcode'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7408569574805188613.post-6443471092119372504</id><published>2008-04-24T11:46:00.000-07:00</published><updated>2009-10-04T09:58:45.781-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Project Euler'/><title type='text'>Project Euler Problem 17</title><content type='html'>Definition:&lt;br /&gt;---------------------------------------------&lt;br /&gt;If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.&lt;br /&gt;If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?&lt;br /&gt;NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.&lt;br /&gt;&lt;br /&gt;---------------------------------------------&lt;br /&gt;&lt;br /&gt;C# code solution:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#990000;"&gt;static long LettersOfNumber(long num, long[,] bases)&lt;br /&gt;{&lt;br /&gt;long count = 0;&lt;br /&gt;long tempnum;&lt;br /&gt;if (num &gt; 1000  num &lt; 1)&lt;br /&gt;count = -1;&lt;br /&gt;else if (num == 1000)&lt;br /&gt;count = 11;&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;tempnum = num % 100;&lt;br /&gt;if (tempnum &lt; 20)&lt;br /&gt;count += bases[tempnum, 0];&lt;br /&gt;else&lt;br /&gt;count += bases[num % 10, 0] + bases[(num / 10) % 10, 1];&lt;br /&gt;if (num &gt; 99)&lt;br /&gt;count += bases[(num / 100), 0] + 7 + ((tempnum == 0) ? 0 : 3);&lt;br /&gt;}&lt;br /&gt;return count;&lt;br /&gt;}&lt;br /&gt;static long LettersUntilNumber(int num)&lt;br /&gt;{&lt;br /&gt;long letcount = 0;&lt;br /&gt;long[,] bas = new long[20, 2] { { 0, 0 }, { 3, 0 }, { 3, 6 }, { 5, 6 }, { 4, 5 }, { 4, 5 }, { 3, 5 }, { 5, 7 }, { 5, 6 }, { 4, 6 }, { 3, 0 }, { 6, 0 }, { 6, 0 }, { 8, 0 }, { 8, 0 }, { 7, 0 }, { 7, 0 }, { 9, 0 }, { 8, 0 }, { 8, 0 } };&lt;br /&gt;for (int i = 1; i &lt;= num; i++)&lt;br /&gt;letcount += LettersOfNumber(i, bas);&lt;br /&gt;return letcount;&lt;br /&gt;}&lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;Console.WriteLine(LettersUntilNumber(1000));&lt;br /&gt;Console.ReadLine();&lt;br /&gt;} &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7408569574805188613-6443471092119372504?l=coding-experiments.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://coding-experiments.blogspot.com/feeds/6443471092119372504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=7408569574805188613&amp;postID=6443471092119372504&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/6443471092119372504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7408569574805188613/posts/default/6443471092119372504'/><link rel='alternate' type='text/html' href='http://coding-experiments.blogspot.com/2008/04/project-euler-problem-17.html' title='Project Euler Problem 17'/><author><name>Agnius Vasiliauskas</name><uri>http://www.blogger.com/profile/10940660947742989178</uri><email>vasiliauskas.agnius@gmail.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='11008976029392309679'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>