Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.programming > #10691 > unrolled thread

Coding while drunk and stoned take 2. (Yes, I know this is a cross post)

Started by"Chad Altenburg, Ph.D." <cdalten@gmail.com>
First post2020-02-27 06:04 -0800
Last post2020-02-27 21:06 +0000
Articles 7 — 3 participants

Back to article view | Back to comp.programming


Contents

  Coding while drunk and stoned take 2. (Yes, I know this is a cross post) "Chad Altenburg, Ph.D." <cdalten@gmail.com> - 2020-02-27 06:04 -0800
    Re: Coding while drunk and stoned take 2. (Yes, I know this is a cross post) Julio Di Egidio <julio@diegidio.name> - 2020-02-27 07:24 -0800
    Re: Coding while drunk and stoned take 2. (Yes, I know this is a cross post) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-02-27 15:55 +0000
      Re: Coding while drunk and stoned take 2. (Yes, I know this is a cross post) Julio Di Egidio <julio@diegidio.name> - 2020-02-27 08:06 -0800
        Re: Coding while drunk and stoned take 2. (Yes, I know this is a cross post) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-02-27 21:00 +0000
          Re: Coding while drunk and stoned take 2. (Yes, I know this is a cross post) "Chad Altenburg, Ph.D." <cdalten@gmail.com> - 2020-02-27 15:18 -0800
    Re: Coding while drunk and stoned take 2. (Yes, I know this is a cross post) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-02-27 21:06 +0000

#10691 — Coding while drunk and stoned take 2. (Yes, I know this is a cross post)

From"Chad Altenburg, Ph.D." <cdalten@gmail.com>
Date2020-02-27 06:04 -0800
SubjectCoding while drunk and stoned take 2. (Yes, I know this is a cross post)
Message-ID<0b8d1b58-3651-47ed-a2b8-63dc1d659c91@googlegroups.com>
I was drunk and stoned because my girlfriend had just dump me. And I needed something to take my mind off the situation. So I attacked one problem that I couldn't solve on coding bat. Here is a link to the problem.. 

https://codingbat.com/prob/p180759 

And here is the problem statement... 

Look for patterns like "zip" and "zap" in the string -- length-3, starting with 'z' and ending with 'p'. Return a string where for all such words, the middle letter is gone, so "zipXzap" yields "zpXzp". 

zipZap("zipXzap") → "zpXzp" 
zipZap("zopzop") → "zpzp" 
zipZap("zzzopzop") → "zzzpzp" 


But the solution that I somehow managed to come up with when I was drunk, stoned, depressed, and pissed off, is well, ugly... 

Here is the solution 

public String zipZap(String str) {
  String newString = "";
  
  if (str.length() < 3) {
    return str;
  }
  
  for (int i = 0; i < str.length() - 3; i++) {
    if (str.charAt(i) == 'z' && str.charAt(i + 2) == 'p' ) {
      newString = newString +  "zp";
      i = i + 2;
    }
    else {
      newString = newString + str.charAt(i);
    }
    
  }
  
  for (int i = str.length() - 3; i < str.length(); i++ ) {
    if (str.charAt(i) == 'z' && str.charAt(i + 2) == 'p' ) {
      newString = newString +  "zp";
      i = i + 2;
    }
    else {
      newString = newString + str.charAt(i);
    }
  }
  
  return newString;
}

The problem is that I have two loops. This is because I didn't know how to attack the case when I have to search for a pattern at the *end* of the string. If I use str.length(), I go out of bounds. So I ended up using a second loop to handle the end of the string case. 

My gut feeling says this isn't right. But I have no idea how this could be done in one loop.

[toc] | [next] | [standalone]


#10692

FromJulio Di Egidio <julio@diegidio.name>
Date2020-02-27 07:24 -0800
Message-ID<277769d2-0f7f-46ca-87ca-8380f28839ee@googlegroups.com>
In reply to#10691
On Thursday, 27 February 2020 15:04:57 UTC+1, Chad Altenburg, Ph.D.  wrote:
> 
> I was drunk and stoned because my girlfriend had just dump me. And I needed something to take my mind off the situation. So I attacked one problem that I couldn't solve on coding bat. Here is a link to the problem.. 
> 
> https://codingbat.com/prob/p180759 
> 
> And here is the problem statement... 

LOL.  For the fun of it as well as to answer your question directly, here is
a solution along the lines of what you wrote:

<code>
public String zipZap(String str) {
  String newStr = "";
  
  int i = 0;
  
  for (; i < str.length() - 2; ++i) {
    if (str.charAt(i) == 'z' && str.charAt(i + 2) == 'p') {
      newStr += "zp";
      i += 2;
    }
    else {
      newStr += str.charAt(i);
    }
  }
  
  for (; i < str.length(); ++i) {
    newStr += str.charAt(i);
  }
  
  return newStr;
}
</code>

Of course there is a much better approach: roughly speaking, while you can
find the index of the next "p", copy at once all characters up to that point:
i.e. instead of going one character at the time...

Julio

[toc] | [prev] | [next] | [standalone]


#10693

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-02-27 15:55 +0000
Message-ID<87y2souis2.fsf@bsb.me.uk>
In reply to#10691
"Chad Altenburg, Ph.D." <cdalten@gmail.com> writes:

> And here is the problem statement... 
>
> Look for patterns like "zip" and "zap" in the string -- length-3,
> starting with 'z' and ending with 'p'. Return a string where for all
> such words, the middle letter is gone, so "zipXzap" yields "zpXzp".
>
> zipZap("zipXzap") → "zpXzp" 
> zipZap("zopzop") → "zpzp" 
> zipZap("zzzopzop") → "zzzpzp" 
>
>
> But the solution that I somehow managed to come up with when I was
> drunk, stoned, depressed, and pissed off, is well, ugly...
>
> Here is the solution 
>
> public String zipZap(String str) {
>   String newString = "";
>   
>   if (str.length() < 3) {
>     return str;
>   }
>   
>   for (int i = 0; i < str.length() - 3; i++) {
>     if (str.charAt(i) == 'z' && str.charAt(i + 2) == 'p' ) {
>       newString = newString +  "zp";
>       i = i + 2;
>     }
>     else {
>       newString = newString + str.charAt(i);
>     }
>     
>   }
>   
>   for (int i = str.length() - 3; i < str.length(); i++ ) {
>     if (str.charAt(i) == 'z' && str.charAt(i + 2) == 'p' ) {
>       newString = newString +  "zp";
>       i = i + 2;
>     }
>     else {
>       newString = newString + str.charAt(i);
>     }
>   }
>   
>   return newString;
> }
>
> The problem is that I have two loops. This is because I didn't know
> how to attack the case when I have to search for a pattern at the
> *end* of the string. If I use str.length(), I go out of bounds. So I
> ended up using a second loop to handle the end of the string case.
>
> My gut feeling says this isn't right. But I have no idea how this
> could be done in one loop.

Here's a C solution.  It's messy because the natural way to do string
things in C is to pass an array to take the result.  You then need to
pass a size so the function does not write out-of-bounds.  But to be
useful the function should keep going and return the size that's needed
even when there was no room this time:

#include <stdio.h>

size_t zipzap(const char *src, char *dst, size_t n)
{
     size_t i = 0;
     while (*src) {
          if (i < n)
               dst[i] = *src;
          i += 1;
          if (src[0] == 'z' && src[1] && src[2] == 'p') {
               if (i < n)
                    dst[i] = 'p';
               i += 1;
               src += 3;
          }
          else src += 1;
     }
     dst[i <= n ? i : n-1] = 0;
     return i + 1;
}

int main(int argc, char **argv)
{
     char z[10];
     for (int a = 1; a < argc; a++) {
          size_t required = zipzap(argv[a], z, sizeof z);
          printf("%s -> %s (%zu)\n", argv[a], z, required);
     }
}

The more "scripty" way -- allocating the result -- looks simpler:

char *zipzap_str(const char *src)
{
     char result[strlen(src) + 1], *dst = result;
     while (*src) {
          *dst++ = *src++;
          if (src[-1] == 'z' && src[0] && src[1] == 'p') {
               *dst++ = 'p';
               src += 2;
          }
     }
     *dst++ = 0;
     char *rp = malloc(dst - result);
     return rp ? strcpy(rp, result) : 0;
}

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#10694

FromJulio Di Egidio <julio@diegidio.name>
Date2020-02-27 08:06 -0800
Message-ID<bcc61784-004c-4bf9-bc09-fa44d22f83c8@googlegroups.com>
In reply to#10693
On Thursday, 27 February 2020 16:55:29 UTC+1, Ben Bacarisse  wrote:
> "Chad Altenburg, Ph.D." <cdalten@gmail.com> writes:
<snip>
> > My gut feeling says this isn't right. But I have no idea how this
> > could be done in one loop.
> 
> Here's a C solution.  It's messy because the natural way to do string
> things in C is to pass an array to take the result.  You then need to
> pass a size so the function does not write out-of-bounds.  But to be
> useful the function should keep going and return the size that's needed
> even when there was no room this time:
> 
> #include <stdio.h>
> 
> size_t zipzap(const char *src, char *dst, size_t n)
> {
>      size_t i = 0;
>      while (*src) {
>           if (i < n)
>                dst[i] = *src;
>           i += 1;
>           if (src[0] == 'z' && src[1] && src[2] == 'p') {
>                if (i < n)
>                     dst[i] = 'p';
>                i += 1;
>                src += 3;
>           }
>           else src += 1;
>      }
>      dst[i <= n ? i : n-1] = 0;
>      return i + 1;
> }
> 
> int main(int argc, char **argv)
> {
>      char z[10];
>      for (int a = 1; a < argc; a++) {
>           size_t required = zipzap(argv[a], z, sizeof z);
>           printf("%s -> %s (%zu)\n", argv[a], z, required);
>      }
> }
> 
> The more "scripty" way -- allocating the result -- looks simpler:
> 
> char *zipzap_str(const char *src)
> {
>      char result[strlen(src) + 1], *dst = result;
>      while (*src) {
>           *dst++ = *src++;
>           if (src[-1] == 'z' && src[0] && src[1] == 'p') {
>                *dst++ = 'p';
>                src += 2;
>           }
>      }
>      *dst++ = 0;
>      char *rp = malloc(dst - result);
>      return rp ? strcpy(rp, result) : 0;
> }

Man, that hurts...

Julio

[toc] | [prev] | [next] | [standalone]


#10695

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-02-27 21:00 +0000
Message-ID<87ftevvj7v.fsf@bsb.me.uk>
In reply to#10694
Julio Di Egidio <julio@diegidio.name> writes:

> On Thursday, 27 February 2020 16:55:29 UTC+1, Ben Bacarisse  wrote:
>> "Chad Altenburg, Ph.D." <cdalten@gmail.com> writes:
> <snip>
>> > My gut feeling says this isn't right. But I have no idea how this
>> > could be done in one loop.
>> 
>> Here's a C solution.  It's messy because the natural way to do string
>> things in C is to pass an array to take the result.  You then need to
>> pass a size so the function does not write out-of-bounds.  But to be
>> useful the function should keep going and return the size that's needed
>> even when there was no room this time:
>> 
>> #include <stdio.h>
>> 
>> size_t zipzap(const char *src, char *dst, size_t n)
>> {
>>      size_t i = 0;
>>      while (*src) {
>>           if (i < n)
>>                dst[i] = *src;
>>           i += 1;
>>           if (src[0] == 'z' && src[1] && src[2] == 'p') {
>>                if (i < n)
>>                     dst[i] = 'p';
>>                i += 1;
>>                src += 3;
>>           }
>>           else src += 1;
>>      }
>>      dst[i <= n ? i : n-1] = 0;
>>      return i + 1;
>> }
>> 
>> int main(int argc, char **argv)
>> {
>>      char z[10];
>>      for (int a = 1; a < argc; a++) {
>>           size_t required = zipzap(argv[a], z, sizeof z);
>>           printf("%s -> %s (%zu)\n", argv[a], z, required);
>>      }
>> }
>> 
>> The more "scripty" way -- allocating the result -- looks simpler:
>> 
>> char *zipzap_str(const char *src)
>> {
>>      char result[strlen(src) + 1], *dst = result;
>>      while (*src) {
>>           *dst++ = *src++;
>>           if (src[-1] == 'z' && src[0] && src[1] == 'p') {
>>                *dst++ = 'p';
>>                src += 2;
>>           }
>>      }
>>      *dst++ = 0;
>>      char *rp = malloc(dst - result);
>>      return rp ? strcpy(rp, result) : 0;
>> }
>
> Man, that hurts...

Yes, it's grim.  It's just three explicit patterns in Haskell:

zipzap s = case s of
  []               -> []
  'z':_:'p' : rest -> 'z':'p' : zipzap rest
  c         : rest -> c       : zipzap rest

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#10697

From"Chad Altenburg, Ph.D." <cdalten@gmail.com>
Date2020-02-27 15:18 -0800
Message-ID<66bce9c1-5bbf-4308-8b5b-9fd5cf5dd0d7@googlegroups.com>
In reply to#10695
On Thursday, February 27, 2020 at 1:00:40 PM UTC-8, Ben Bacarisse wrote:
> Julio Di Egidio <julio@diegidio.name> writes:
> 
> > On Thursday, 27 February 2020 16:55:29 UTC+1, Ben Bacarisse  wrote:
> >> "Chad Altenburg, Ph.D." <cdalten@gmail.com> writes:
> > <snip>
> >> > My gut feeling says this isn't right. But I have no idea how this
> >> > could be done in one loop.
> >> 
> >> Here's a C solution.  It's messy because the natural way to do string
> >> things in C is to pass an array to take the result.  You then need to
> >> pass a size so the function does not write out-of-bounds.  But to be
> >> useful the function should keep going and return the size that's needed
> >> even when there was no room this time:
> >> 
> >> #include <stdio.h>
> >> 
> >> size_t zipzap(const char *src, char *dst, size_t n)
> >> {
> >>      size_t i = 0;
> >>      while (*src) {
> >>           if (i < n)
> >>                dst[i] = *src;
> >>           i += 1;
> >>           if (src[0] == 'z' && src[1] && src[2] == 'p') {
> >>                if (i < n)
> >>                     dst[i] = 'p';
> >>                i += 1;
> >>                src += 3;
> >>           }
> >>           else src += 1;
> >>      }
> >>      dst[i <= n ? i : n-1] = 0;
> >>      return i + 1;
> >> }
> >> 
> >> int main(int argc, char **argv)
> >> {
> >>      char z[10];
> >>      for (int a = 1; a < argc; a++) {
> >>           size_t required = zipzap(argv[a], z, sizeof z);
> >>           printf("%s -> %s (%zu)\n", argv[a], z, required);
> >>      }
> >> }
> >> 
> >> The more "scripty" way -- allocating the result -- looks simpler:
> >> 
> >> char *zipzap_str(const char *src)
> >> {
> >>      char result[strlen(src) + 1], *dst = result;
> >>      while (*src) {
> >>           *dst++ = *src++;
> >>           if (src[-1] == 'z' && src[0] && src[1] == 'p') {
> >>                *dst++ = 'p';
> >>                src += 2;
> >>           }
> >>      }
> >>      *dst++ = 0;
> >>      char *rp = malloc(dst - result);
> >>      return rp ? strcpy(rp, result) : 0;
> >> }
> >
> > Man, that hurts...
> 
> Yes, it's grim.  It's just three explicit patterns in Haskell:
> 
> zipzap s = case s of
>   []               -> []
>   'z':_:'p' : rest -> 'z':'p' : zipzap rest
>   c         : rest -> c       : zipzap rest
> 
> -- 

I know the basics of Haskell. Ie, just enough to know that I have absolutely no idea what I'm doing. I gave up somewhere between Monads and Algebraic Data Types? I think that is what the latter is called. I remember reading this and thinking "My gawd do I need another beer right about now because this crap is giving me a massive headache."

[toc] | [prev] | [next] | [standalone]


#10696

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-02-27 21:06 +0000
Message-ID<87a753viy4.fsf@bsb.me.uk>
In reply to#10691
"Chad Altenburg, Ph.D." <cdalten@gmail.com> writes:

> https://codingbat.com/prob/p180759 
>
> And here is the problem statement... 
>
> Look for patterns like "zip" and "zap" in the string -- length-3,
> starting with 'z' and ending with 'p'. Return a string where for all
> such words, the middle letter is gone, so "zipXzap" yields "zpXzp".
>
> zipZap("zipXzap") → "zpXzp" 
> zipZap("zopzop") → "zpzp" 
> zipZap("zzzopzop") → "zzzpzp"

There's are some interesting corner cases.  What about

  zipZap("zipp") → "zpp" or "zp"?

And if "overlapping" zXp strings like this are to be ignored, the
problem statement is not clear about

  zipZap("zzpp") → "zpp" or "zzp"?

You get different result from forward and reverse scans.

-- 
Ben.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.programming


csiph-web