<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Hungry Hacker &#187; Code</title>
	<atom:link href="http://www.hungryhacker.com/topics/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.hungryhacker.com</link>
	<description>The Hungry Hacker&#039;s Explanation of Everything</description>
	<lastBuildDate>Mon, 05 Sep 2011 03:44:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PostgreSQL libpq Programming Example</title>
		<link>http://www.hungryhacker.com/code/postgresql-libpq-programming-example/</link>
		<comments>http://www.hungryhacker.com/code/postgresql-libpq-programming-example/#comments</comments>
		<pubDate>Wed, 21 Sep 2005 22:18:40 +0000</pubDate>
		<dc:creator>fwaggle</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[database]]></category>

		<guid isPermaLink="false">http://www.hungryhacker.com/?p=122</guid>
		<description><![CDATA[Update: After years of sitting idle, and moving across about three or four different CMS systems, almost all of which decided to arbitrarily munge various portions of this code, I honestly have no idea if it works or not. I&#8217;d suggest giving it a shot, and consulting the manual frequently. My apologies for WordPress eating the white space, there&#8217;s not really much I can do about it.
Honestly, the programming examples on the official PostgreSQL website aren&#8217;t that  bad. I just thought that I could write my own, and show ...]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong> After years of sitting idle, and moving across about three or four different CMS systems, almost all of which decided to arbitrarily munge various portions of this code, I honestly have no idea if it works or not. I&#8217;d suggest giving it a shot, and consulting the manual frequently. My apologies for WordPress eating the white space, there&#8217;s not really much I can do about it.</p>
<p>Honestly, the programming examples on the official <a href="http://www.postgresql.org/">PostgreSQL website</a> aren&#8217;t that  bad. I just thought that I could write my own, and show people how I  like to use the libpq API in C (and for <a href="http://www.google.com/search?q=Cee">Google</a> purposes, Cee).</p>
<h2>Initializing and Connecting</h2>
<p>The first thing you&#8217;ll need is the <code>libpq-fe.h</code> header, to allow you to  use all the goodies that libpq has to offer:</p>
<p><code>#include libpq-fe.h </code></p>
<p>Connecting to the database server is done via the <code>PQconnectdb()</code> function, with the configuration being passed as a string. Of course, this is a terribly nasty way of doing things in my humble opinion, but  I&#8217;m sure there are alternatives if you look for them.</p>
<p><code>PGconn *psql;<br />
psql = PQconnectdb("hostaddr = '127.0.0.1' port = '' dbname = 'fwaggle'  user = 'fwaggle' password = 'password' connect_timeout = '10'");<br />
/* init  connection */<br />
if (!psql) {<br />
fprintf(stderr, "libpq error: PQconnectdb returned NULL.\n\n");<br />
exit(0);<br />
}<br />
if (PQstatus(psql) != CONNECTION_OK) {<br />
fprintf(stderr, "libpq error: PQstatus(psql) != CONNECTION_OK\n\n");<br />
exit(0);<br />
} </code></p>
<p>As you can see, everything&#8217;s done for you with a single function call,  and we simply check to see if we&#8217;re connected by 1) checking if the  pointer was <code>NULL</code> and 2) checking <code>PQstatus()</code>&#8216;s return value. If you&#8217;re  not writing CGI and you&#8217;re writing a long-term daemon of some sort, you  probably want to include multiple <code>PQstatus()</code> calls in your application.</p>
<h2>Cleanup</h2>
<p>I wouldn&#8217;t be a good little hacker if I didn&#8217;t show you how to cleanup  after yourself, would I? Thankfully, it&#8217;s trivial:</p>
<p><code>PQfinish(psql);</code></p>
<h2>Queries</h2>
<p>Queries aren&#8217;t handled the greatest with libpq, so I much prefer to  write my own wrapper function for them using variable argument lists  (<code>va_arg</code>) if it&#8217;s available:</p>
<p><code>PGresult *pq_query(const char *format, ...) {<br />
va_list argv;<br />
char *ptrQuery;<br />
PGresult *result;<br />
va_start(argv, format);<br />
vasprintf(ptrQuery, format, argv);<br />
va_end(argv);<br />
if (!ptrQuery)<br />
return(0);<br />
result = PQexec(psql, ptrQuery);<br />
free(ptrQuery);<br />
return(result);<br />
} </code></p>
<p>Then, it&#8217;s simply a matter of calling <code>pq_query()</code> with <code>sprintf()</code> style  arguments:</p>
<p><code>#define WORD "this is a test"<br />
PGresult *result;<br />
result = db_query("SELECT now(), md5('%s');", WORD);</code></p>
<p>Doing something with the data set that result will (hopefully) point to  generally requires some kind of loop, unless you&#8217;re only expecting a  single row. Even though the above SQL will only ever return one row,  we&#8217;ll still use a loop just in case. In this case, we&#8217;re introducing the  <code>PQntuples()</code> function, which returns the number of tuples (rows) for a  given result set.</p>
<p>I&#8217;m not sure if it&#8217;s necessary (RTFM, as they say) but I like to check  for a <code>NULL</code> result set anyway. We&#8217;ll also introduce the <code>PQgetvalue()</code> function, for grabbing values from rows:</p>
<p><code>int i, j;<br />
if (!result || !(j = PQntuples(result))) {<br />
fprintf(stderr, "libpq error: no rows returned or bad result set\n\n");<br />
PQfinish(psql);<br />
exit(0);<br />
}<br />
for (i = 0; i  j; i++) {<br />
printf("Time: %s\n", PQgetvalue(result, i, 0);<br />
printf("MD5: %s\n", PQgetvalue(result, i, 1);<br />
}<br />
PQclear(result);</code></p>
<p>In case you didn&#8217;t figure it out, the arguments for <code>PQgetvalue()</code> are:  &#8220;result set&#8221;, &#8220;row&#8221;, &#8220;column&#8221;. Everything starts at 0.</p>
<h2>Sanitizing Data</h2>
<p>When dealing with any kind of data that comes from user land &#8211; whether it  be user input, environment variables, whatever &#8211; it&#8217;s always a good  idea to sanitize the data to ensure no one meddles with your SQL  queries. libpq provides the <code>PQescapeString()</code> function, but it&#8217;s  invocation isn&#8217;t the cleanest, so again, I like to wrap it in a wrapper  function and toast lightly:</p>
<p><code>char * pq_escape (char *input) {<br />
int len;<br />
char *output;<br />
len = strlen(input);<br />
if (len  1)<br />
return(NULL);<br />
output = malloc((len * 2) + 1);<br />
if (!output)<br />
return(NULL);<br />
PQescapeString(output, input, len);<br />
return(output);<br />
} </code></p>
<p>Of course, the return value is a pointer to a dynamically allocated  variable, which you&#8217;ll need to free on your own when you&#8217;re done with  it. But nonetheless, we can use this wrapper function to easily escape  user-provided data:</p>
<p><code>char *data_safe;<br />
if (argc &gt; 1) {<br />
data_safe = pq_escape(argv[1]);<br />
result = pq_query("SELECT MD5('%s');", data_safe);<br />
if (!result || PQntuples(result)  1) 	{<br />
fprintf(stderr, "libpq error: no results returned or NULL resultset  pointer.\n\n");<br />
PQfinish(psql);<br />
exit(0);<br />
}<br />
printf("data: %s (data safe: %s)\n", argv[0]);<br />
printf("MD5: %s\n", PQgetvalue(result, 0, 0));<br />
PQclear(result);<br />
} </code></p>
<h2>Putting it all together:</h2>
<p>Putting the whole mess together, you should have a fully compilable,  executable program that takes next to no time to execute and does a  couple of measly features:</p>
<p><code> /*<br />
** libpq example<br />
** fwaggle@hungryhacker.com<br />
** http://www.hungryhacker.com/<br />
*/<br />
#include stdio.h<br />
#include stdarg.h<br />
#include libpq-fe.h<br />
&amp;nsbp;<br />
#define WORD "this is a test"<br />
PGconn *psql;<br />
&amp;nsbp;<br />
PGresult *pq_query(const char *format, ...)<br />
{<br />
va_list argv;<br />
char *ptrQuery;<br />
PGresult *result;<br />
va_start(argv, format);<br />
vasprintf(ptrQuery, format, argv);<br />
va_end(argv);<br />
if (!ptrQuery)<br />
return(0);<br />
result = PQexec(psql, ptrQuery);<br />
free(ptrQuery);<br />
return(result);<br />
}<br />
&amp;nsbp;<br />
char * pq_escape (char *input)<br />
{<br />
int len;<br />
char *output;<br />
len = strlen(input);<br />
if (len  1)<br />
return(NULL);<br />
output = malloc((len * 2) + 1);<br />
if (!output)<br />
return(NULL);<br />
PQescapeString(output, input, len);<br />
return(output);<br />
}<br />
&amp;nsbp;<br />
int main (int argc, char **argv)<br />
{<br />
char *data_safe;<br />
int i, j;<br />
PGresult *result;<br />
psql = PQconnectdb("hostaddr = '127.0.0.1' port = '' dbname = 'fwaggle'  user = 'fwaggle' password = 'password' connect_timeout = '10'");<br />
&amp;nsbp;<br />
/*  init connection */<br />
if (!psql)<br />
{<br />
fprintf(stderr, "libpq error: PQconnectdb returned NULL.\n\n");<br />
exit(0);<br />
}<br />
if (PQstatus(psql) != CONNECTION_OK)<br />
{<br />
fprintf(stderr, "libpq error: PQstatus(psql) != CONNECTION_OK\n\n");<br />
exit(0);<br />
}<br />
result = pq_query("SELECT now(), md5('%s');", WORD);<br />
if (!result || !(j = PQntuples(result)))<br />
{<br />
fprintf(stderr, "libpq error: no rows returned or bad result  set\n\n");<br />
PQfinish(psql);<br />
exit(0);<br />
}<br />
for (i = 0; i  j; i++)<br />
{<br />
printf("Time: %s\n", PQgetvalue(result, i, 0));<br />
printf("MD5: %s\n", PQgetvalue(result, i, 1));<br />
}<br />
PQclear(result);<br />
if (argc &gt; 1)<br />
{<br />
data_safe = pq_escape(argv[1]);<br />
result = pq_query("SELECT MD5('%s');", data_safe);<br />
if (!result || PQntuples(result)  1)<br />
{<br />
fprintf(stderr, "libpq error: no results returned or NULL resultset  pointer.\n\n");<br />
PQfinish(psql);<br />
exit(0);<br />
}<br />
printf("data: %s (data safe: %s)\n", argv[0]);<br />
printf("MD5: %s\n", PQgetvalue(result, 0, 0));<br />
PQclear(result);<br />
}<br />
PQfinish(psql);<br />
}</code></p>
<h2>Compiling</h2>
<p>On my system, I have to play some <code>Makefile</code> games to get libpq to compile  in, I&#8217;ve seen some Redhat systems that are worse though. Basically,  find where <code>libpq-fe.h</code> and the libpq libraries are, and modify your gcc  command to suit:</p>
<p><code>fwaggle@diglett:~$ gcc -I/usr/local/include -L/usr/local/lib -o  test_psql -lpq test_psql.c </code></p>
<p>If it doesn&#8217;t work, and barfs on <code>PQconnectdb()</code>, try leaving the <code>hostaddr</code> blank, as that will often cause libpq to connect via a UNIX domain  socket, as opposed to TCP/IP (in case your PostgreSQL server isn&#8217;t  listening on a TCP/IP port). That worked for me:</p>
<p><code>fwaggle@diglett:~$ ./test_psql Time: 2005-09-21 02:00:28.213502+01 MD5: 54b0c58c7ce9f2a8b551351102ee0938 fwaggle@diglett:~$ </code></p>
<p>Enjoy, and if you have any questions, leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hungryhacker.com/code/postgresql-libpq-programming-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An elegant programming language: Brainfuck</title>
		<link>http://www.hungryhacker.com/code/brainfuck/</link>
		<comments>http://www.hungryhacker.com/code/brainfuck/#comments</comments>
		<pubDate>Fri, 15 Dec 2000 18:20:16 +0000</pubDate>
		<dc:creator>MagicTux</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.hungryhacker.com/?p=159</guid>
		<description><![CDATA[This article is a re-print from DoJ Issue #10.
This text is supposed to explain the brainfuck language and its  elegance. I hope to wake your interest in esoteric programming  languages, such as intercal, dis, malbolge and befunge.
I will continue to use the word &#8216;brainfuck&#8216; and not something  like &#8216;brainf*ck&#8217;. If you are too sensitive to stand foul language, then  please ignore this article, though I would find that extremely  ridiculous.
What is brainfuck?
Brainfuck is a programming language with only 8 commands, each one symbol, that  ...]]></description>
			<content:encoded><![CDATA[<p><em>This article is a re-print from DoJ Issue #10.</em></p>
<p>This text is supposed to explain the <strong>brainfuck</strong> language and its  elegance. I hope to wake your interest in esoteric programming  languages, such as intercal, dis, malbolge and befunge.</p>
<p>I will continue to use the word &#8216;<strong>brainfuck</strong>&#8216; and not something  like &#8216;brainf*ck&#8217;. If you are too sensitive to stand foul language, then  please ignore this article, though I would find that extremely  ridiculous.</p>
<h2>What is <strong>brainfuck</strong>?</h2>
<p><strong>Brainfuck</strong> is a programming language with only 8 commands, each one symbol, that  is Turing-complete. It was originally implemented and designed for Amiga  OS 2.0 by Urban Mueller.</p>
<p>A <strong>brainfuck</strong> program has an array of 30000 elements (lets call it A for simplicity),  all with an initial value of 0 and a pointer (we&#8217;ll call it P) pointing  to the first element of A.</p>
<h2>Commands</h2>
<p>As previously mentioned, <strong>brainfuck</strong> only uses 8 commands. These are: &#8216;+&#8217;,  &#8216;-&#8217;, &#8216;&gt;&#8217;, &#8216;&lt;&#8217;, &#8216;[', ']&#8216;, &#8216;.&#8217;, &#8216;,&#8217;. In case that was unreadable:  +-&gt;&lt;[].,</p>
<p>Let&#8217;s examine them more closely, what does each one of them do?</p>
<ul>
<li>the &#8216;+&#8217; command increments the element of A currently pointed at  by P</li>
<li>the &#8216;-&#8217; command decrements the element of A currently pointed at  by P</li>
<li>the &#8216;&gt;&#8217; command increments P</li>
<li>the &#8216;&lt;&#8217; command decrements P</li>
<li>the &#8216;[' command starts a loop, which is looped until the element  of A currently pointed at by P is 0.</li>
<li>the ']&#8216; command ends the execution block of a previously started  loop.</li>
<li>the &#8216;.&#8217; command prints out the ascii character of the element of A  currently pointed at by P.</li>
<li>the &#8216;,&#8217; command reads a character and saves its ascii value to  the element of A currently pointed at by P.</li>
</ul>
<p>It may be easier to understand this in comparison to the C  language.</p>
<p><code>Command | C-Equivalent --------+------------- +       | a[p]++ -       | a[p]-- &gt;       | p++ &lt;       | p-- [       | while(a[p]) { ]       | } .       | putchar(a[p]) ,       | a[p] = getchar() </code></p>
<h2>Taking apart the &#8216;hello world&#8217; program</h2>
<p>Let&#8217;s take a look at the original <strong>brainfuck</strong> code of the &#8216;hello  world&#8217; program first:</p>
<p><code>&gt;+++++++++[&lt;++++++++&gt;-]&lt;.&gt;+++++++[&lt;++++&gt;-]&lt;+.+++++++..+++.[-]&gt;++++++++[&lt;++++&gt;-]&lt;. &gt;+++++++++++[&lt;+++++&gt;-]&lt;.&gt;++++++++[&lt;+++&gt;-]&lt;.+++.------.--------.[-]&gt;++++++++[&lt;++++ &gt;-]&lt;+.[-]++++++++++. </code></p>
<p>We know that a &#8216;.&#8217; will print out a character, so we can assume  that &gt;+++++++++[&lt;++++++++&gt;-]&lt;. prints &#8216;H&#8217;. The ascii value  of &#8216;H&#8217; is 72, so how do we get 72 into a[p] without writing 72 &#8216;+&#8217;s? We  run a loop. So, first we set P to 1 and then a[1] to 9. Now we go into a  loop. In the body of the loop we decrement P and add 8 to a[0]. Then we  increment P again and subtract one from a[1].</p>
<p>At the beginning we have a[0] = 0 and a[1] = 9. After going through  the loop the first time, we have a[0] = 8 and a[1] = 8. After going  through the loop the second time, we have a[0] = 16 and a[1] = 7. This  continues 9 times, so what this results in, basically is a[0] = 9 * 8.</p>
<p>Let&#8217;s take a look at &#8216;[-]&#8216; now. So, what does this do and how does  it work?</p>
<p>Assuming a[p] = 5, what would &#8216;while(a[p]) a[p]&#8211;;&#8217; do? It would  loop until a[p] is 0 &#8230; that&#8217;s it. It&#8217;s a simple way to reset a[p].</p>
<p>To help you understand how this works, here&#8217;s the code in C:</p>
<p><code>/* Begin C code */ #include &lt;stdio.h&gt;   long a[30000]; int p = 0;   int main(void) {     /*        Print 'H'        */   p++;                  /* &gt; */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   while(a[p]) {         /* [ */     p--;                /* &lt; */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     p++;                /* &gt; */     a[p]--;             /* - */   }                     /* ] */   p--;                  /* &lt; */   putchar(a[p]);        /* . */     /*        Print 'e'        */   p++;                  /* &gt; */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   while(a[p]) {         /* [ */     p--;                /* &lt; */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     p++;                /* &gt; */     a[p]--;             /* - */   }                     /* ] */   p--;                  /* &lt; */   a[p]++;               /* + */   putchar(a[p]);        /* . */     /*        Print 'l'        */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   putchar(a[p]);        /* . */     /*        Print 'l'        */   putchar(a[p]);        /* . */     /*        Print 'o'        */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   putchar(a[p]);        /* . */     /*        Print ' '        */   while(a[p]) {         /* [ */     a[p]--;             /* - */   }                     /* ] */   p++;                  /* &gt; */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   while(a[p]) {         /* [ */     p--;                /* &lt; */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */      p++;                /* &gt; */     a[p]--;             /* - */   }                     /* ] */   p--;                  /* &lt; */   putchar(a[p]);        /* . */     /*        Print 'W'        */   p++;                  /* &gt; */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   while(a[p]) {         /* [ */     p--;                /* &lt; */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     p++;                /* &gt; */     a[p]--;             /* - */   }                     /* ] */   p--;                  /* &lt; */   putchar(a[p]);        /* . */     /*       Print 'o'         */   p++;                  /* &gt; */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   while(a[p]) {         /* [ */     p--;                /* &lt; */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     p++;                /* &gt; */     a[p]--;             /* - */   }                     /* ] */   p--;                  /* &lt; */   putchar(a[p]);        /* . */     /*       Print 'r'         */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   putchar(a[p]);        /* . */     /*       Print 'l'         */   a[p]--;               /* - */   a[p]--;               /* - */   a[p]--;               /* - */   a[p]--;               /* - */   a[p]--;               /* - */   a[p]--;               /* - */   putchar(a[p]);        /* . */     /*       Print 'd'         */   a[p]--;               /* - */   a[p]--;               /* - */   a[p]--;               /* - */   a[p]--;               /* - */   a[p]--;               /* - */   a[p]--;               /* - */   a[p]--;               /* - */   a[p]--;               /* - */   putchar(a[p]);        /* . */     /*       Print '!'         */   while(a[p]) {         /* [ */     a[p]--;             /* - */   }                     /* ] */   p++;                  /* &gt; */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   while(a[p]) {         /* [ */     p--;                /* &lt; */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     a[p]++;             /* + */     p++;                /* &gt; */     a[p]--;             /* - */   }                     /* ] */   p--;                  /* &lt; */   a[p]++;               /* + */   putchar(a[p]);        /* . */     /*         Newline         */   while(a[p]) {         /* [ */     a[p]--;             /* - */   }                     /* ] */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   a[p]++;               /* + */   putchar(a[p]);        /* . */     return 0;   }  /* End C code */ </code></p>
<h2>Notes on efficiency in <strong>brainfuck</strong></h2>
<p>If you&#8217;re aiming for efficiency, <strong>brainfuck</strong> is definitely not  the programming language you&#8217;ll want to use. To make <strong>brainfuck</strong> code as  efficient as possible, you should translate it to C using, for example,  bfc, which optimizes the code. Then you should definitely compile the C  code with optimization flags ofyour compiler, eg. -O2 for gcc. It will  still probably be faster to just write int main(void) { printf(&#8220;Hello  World!\n&#8221;); return 0; }though <img src='http://www.hungryhacker.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Also, obviously it will be faster to just decrement a[p] by 3  instead of using [-] and then setting up the value again, just 3 less,  when you for example just printed &#8216;m&#8217; and now wish to print &#8216;j&#8217;.</p>
<p>Running through a loop less often will probably be faster, so  instead of having&#8217;&gt;++++++++[&lt;++++&gt;-]&#8216; you should use  &#8216;&gt;++++[&lt;++++++++&gt;-]&#8216;, though I must admit Ihaven&#8217;t timed these  possibilities or tested results.</p>
<h2>Last program</h2>
<p>Note: I wrote this <strong>brainfuck</strong> program rather quickly so it may not  be the mostefficient or shortest way to write it &#8230; this is left as an  exercise for thereader (as substitute for my laziness) <img src='http://www.hungryhacker.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> Well, here it  is:</p>
<p><code>&gt;++++++++[&lt;+++++++++&gt;-]&lt;++.&gt;+++++++[&lt;++++++&gt;-]&lt;+.--.+.[-]&gt;++++[&lt;++++++++&gt;-]&lt;. &gt;++++[&lt;++++++++&gt;-]&lt;+.&gt;+++++[&lt;+++++++++&gt;-]&lt;.+.+++++.&gt;++[&lt;------&gt;-]&lt;.---.&gt;++[&lt;+ +++++&gt;-]&lt;+.[-]&gt;++++[&lt;++++++++&gt;-]&lt;.&gt;++++[&lt;++++++++&gt;-]&lt;++.&gt;++++++[&lt;++++++++&gt;-]&lt; .&gt;++++[&lt;----&gt;-]&lt;-.++++++++.+++++.[-]&gt;++++[&lt;++++++++&gt;-]&lt;.[-]&gt;++++++++[&lt;+++++++ ++&gt;-]&lt;--.&gt;+++++[&lt;+++++++++&gt;-]&lt;++.&gt;+++[&lt;------&gt;-]&lt;.++++++++.------.&gt;++[&lt;++++++ &gt;-]&lt;+.[-]&gt;++[&lt;+++++&gt;-]&lt;. </code></p>
<h2>What is so elegant about <strong>brainfuck</strong>?</h2>
<p><strong>Brainfuck</strong> just simply is the most elegant programming language around. It only  has 8 commands, only 6 being necessary for it to be turing-complete. If  you don&#8217;t find that makes it elegant &#8230; well, that&#8217;s your opinion then,  I suppose. Many people enjoy writing their own interpreters and/or  compilers/translaters to other programming languages for <strong>brainfuck</strong>.  <strong>Brainfuck</strong> is just a lot of fun and it&#8217;s a lifetime experience coding programs in  it <img src='http://www.hungryhacker.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Also you can impress colleagues by the cryptic look of its code.</p>
<p>Well, that&#8217;s it for this article &#8230; hope you enjoyed it.</p>
<h2>Resources</h2>
<ul>
<li><a href="http://www.catseye.mb.ca/esoteric/bf/">http://www.catseye.mb.ca/esoteric/bf/</a> &#8211; the current <strong>brainfuck</strong> site</li>
<li><a href="http://freshmeat.net/">http://freshmeat.net</a> &#8211; has  various <strong>brainfuck</strong> compilers/interpreters</li>
<li><a href="http://www.muppetlabs.com/%7Ebreadbox/bf/">http://www.muppetlabs.com/~breadbox/bf/</a> &#8211; a great site about <strong>brainfuck</strong></li>
<li><a href="http://home.wxs.nl/%7Efaase009/Ha_bf_Turing.html">http://home.wxs.nl/~faase009/Ha_bf_Turing.html</a> &#8211; <strong>brainfuck</strong> in relation to turing-completeness and URM.</li>
<li><a href="http://obiwan.uvi.edu/computing/turing/ture.htm">http://obiwan.uvi.edu/computing/turing/ture.htm</a> &#8211; paper on the turing machine</li>
<li><a href="http://www.ionet.net/%7Etimtroyr/funhouse/beer/beer_a_c.html#brainfuck">http://www.ionet.net/~timtroyr/funhouse/beer/beer_a_c.html#<strong>brainfuck</strong></a> &#8211; 99 bottles of beer on the wall in <strong>brainfuck</strong></li>
<li><a href="http://cydathria.com/bf/brainfuck.html">http://cydathria.com/bf/<strong>brainfuck</strong>.html</a> &#8211; Guide on programming in <strong>brainfuck</strong></li>
</ul>
<p>Markus Kliegl &lt;markus.kliegl@t-online.de&gt;, December 2000</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hungryhacker.com/code/brainfuck/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

