{"id":6573,"date":"2024-09-21T00:01:13","date_gmt":"2024-09-21T07:01:13","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=6573"},"modified":"2024-09-13T21:45:01","modified_gmt":"2024-09-14T04:45:01","slug":"the-look-and-say-sequenceas-much-as-the-computer-can","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=6573","title":{"rendered":"The Look-and-Say Sequence<br>(As Much as the Computer Can)"},"content":{"rendered":"<p>Coding a Look-and-Say sequence should be fun, just like any C programming project where you&#8217;re not under pressure from a deadline. From <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6566\">last week&#8217;s Lesson<\/a>, I was able to create a nested loop that takes a number and outputs its Look-and-Say values. It&#8217;s time to update this code to output a sequence.<br \/>\n<!--more--><br \/>\nI tried to keep the entire sequence in the <em>main()<\/em> function, though after a while it became obvious that a function is required. This function, which I name <em>looksay()<\/em>, requires an integer value as its argument and returns an integer value, the next number in the sequence.<\/p>\n<p>This code went through several iterations before I recognized that the sequence quickly overflows the integer data type container. The range of an integer on most modern computers is between -2,147,483,684 and 2,147,483,647 signed, or zero to 4,294,967,295 unsigned. While I wanted to see 20 values of the sequence output, I was barely able to get six!<\/p>\n<p>To ensure that the <em>looksay()<\/em> function could handle larger values, I used an <em>unsigned long long<\/em> value, which has a range from 0 to 18,446,744,073,709,551,615. Here is the code:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2024_09_21-Lesson.c\" rel=\"noopener\" target=\"_blank\">2024_09_21-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n#include &lt;limits.h&gt;\r\n\r\nunsigned long long looksay(unsigned long long v)\r\n{\r\n    const int size = 128;\r\n    char number[size],temp[size],*n,c;\r\n    static char value[128];\r\n    int count;\r\n    unsigned long long r;\r\n\r\n    <span class=\"comments\">\/* convert and process the string *\/<\/span>\r\n    snprintf(number,size,\"%lld\",v);\r\n    value[0] = '\\0';        <span class=\"comments\">\/* cap the buffer for strcat() *\/<\/span>\r\n    n = number;                <span class=\"comments\">\/* initialize the pointer *\/<\/span>\r\n    while(*n)                <span class=\"comments\">\/* loop through the string *\/<\/span>\r\n    {\r\n        count = 0;            <span class=\"comments\">\/* digit count *\/<\/span>\r\n        c = *n;                <span class=\"comments\">\/* save the current digit *\/<\/span>\r\n        while( *n==c )        <span class=\"comments\">\/* loop while the digits match *\/<\/span>\r\n        {\r\n            count++;\r\n            n++;\r\n        }\r\n        <span class=\"comments\">\/* convert the result into a string *\/<\/span>\r\n        snprintf(temp,size,\"%d%c\",count,c);\r\n        <span class=\"comments\">\/* build the new value string *\/<\/span>\r\n        strcat(value,temp);\r\n    }\r\n\r\n    <span class=\"comments\">\/* convert the string back into a long *\/<\/span>\r\n    r = strtoll(value,NULL,10);\r\n\r\n    <span class=\"comments\">\/* check for overflow *\/<\/span>\r\n    if( r==LONG_MAX )\r\n    {\r\n        puts(\"OVERFLOW\");\r\n        exit(1);\r\n    }\r\n\r\n    return(r);\r\n}\r\n\r\nint main()\r\n{\r\n    unsigned long long start;\r\n    int x;\r\n\r\n    printf(\"Starting value: \");\r\n    scanf(\"%llu\",&amp;start);\r\n\r\n    <span class=\"comments\">\/* loop through 10 iterations *\/<\/span>\r\n    printf(\"%llu\\n\",start);\r\n    for( x=0; x&lt;10; x++ )\r\n    {\r\n        start = looksay(start);\r\n        printf(\"%llu\\n\",start);\r\n    }\r\n\r\n    return 0;\r\n}<\/pre>\n<p>The <em>main()<\/em> function uses <em>unsigned long long<\/em> variable <code>start<\/code>, obtained from the user. The <em>scanf()<\/em> function requires the <code>%llu<\/code> placeholder to represent an <em>unsigned long long<\/em> value. A <em>for<\/em> loop repeats ten times, obtaining the Look-and-Say values in the sequence and outputting each one.<\/p>\n<p>The <em>looksay()<\/em> function is base on code presented in last week&#8217;s Lesson, though with the <em>unsigned long long<\/em> used instead of <em>int<\/em>. The <em>snprintf()<\/em> function is updated with the <code>%llu<\/code> placeholder.<\/p>\n<p>The biggest change is building a string, <code>value<\/code>, which contains the Look-and-Say number. Two statements are used:<\/p>\n<p><code>snprintf(temp,size,\"%d%c\",count,c);<br \/>\nstrcat(value,temp);<\/code><\/p>\n<p>The first statement converts a Look-and-Say value for a series of digits into a string, stored in variable <code>temp<\/code>. This string is then appended (concatenated) to the string <code>value<\/code>.<\/p>\n<p>Once the nested loops build the next value in the sequence (as a string), the <em>strtoll()<\/em> function converts the string into a <em>long long<\/em> value stored in variable <code>r<\/code>.<\/p>\n<p>The code worked at first, but the final values output were always 9223372036854775807, which seemed odd to me. I debugged the code by outputting the string <code>value<\/code> created, which didn&#8217;t match the result returned from the <em>strtoll()<\/em> function.<\/p>\n<p>After a few frustrating moments, it occurred to me that the <em>strtoll()<\/em> function was overflowing. This is the reason why I added the test for overflow at the end of the function:<\/p>\n<p><code>if( r==LONG_MAX )<br \/>\n{<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;puts(\"OVERFLOW\");<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;exit(1);<br \/>\n}<\/code><\/p>\n<p>The <code>OVERFLOW<\/code> constant is defined in the <code>limits.h<\/code> header file. This test is trigged in the <em>looksay()<\/em> function, which removes the bogus value from the output, but proves that the function has its limits. Here is a sample run:<\/p>\n<p><code>Starting value: 1<br \/>\n1<br \/>\n11<br \/>\n21<br \/>\n1211<br \/>\n111221<br \/>\n312211<br \/>\n13112221<br \/>\n1113213211<br \/>\n31131211131221<br \/>\nOVERFLOW<\/code><\/p>\n<p>The <em>looksay()<\/em> function actually finds the next value in the sequence, 13211311123113112211. If you add a <em>puts()<\/em> function to output string <code>value<\/code> before the <em>strtoll()<\/em> function, you see this value properly generated. But it&#8217;s value is beyond the range of an <em>unsigned long long<\/em> integer &mdash; if you can fathom that.<\/p>\n<p>The code almost generates the results I wanted from the Look-and-Say sequence, shy one. A possible solution is to use the GMP Library, which I wrote about in a <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5532\">previous Lesson<\/a>. I may attempt to do so in the future, but I&#8217;m happy with the code now, and relieved that the issue with my attempt at a Look-and-Say sequence is overflow and not any booboo that I may have made.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few changes are required for my Look-and-Say sequence algorithm to output the sequence. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6573\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-6573","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6573","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6573"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6573\/revisions"}],"predecessor-version":[{"id":6578,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6573\/revisions\/6578"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6573"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6573"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6573"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}