20
\$\begingroup\$

Context

After attempting to program in Grass for the entire morning, you decide to go outside and mow some real grass. The grass can be viewed as a string consisting exclusively of the following characters: wWv. w denotes tall grass which takes \$ 1 \$ unit of energy to mow. W denotes extremely tall grass which takes \$ 2 \$ units of energy to mow. Lastly v denotes short grass which does not need to be mowed.

Task

You decide to mow the grass from left to right (beginning to the end of the string). However, every time you encouter a v (short grass), you stop to take a break to replenish your energy, before carrying on with the mowing. Your task is to calculate the maximum amount of energy expended while mowing. In other words, find the maximum total energy of mowing a patch of grass, that of which does not contain v.

Example

In the example input below, the answer is \$ 8 \$. Although the patch wwwwwww is a longer patch of grass, it only costs \$ 7 \$ units of energy, whereas the optimal patch WWWW expends \$ 2 \times 4 = 8 \$ units of energy.

Input: WwwvWWWWvvwwwwwwwvWwWw
Output: 8 

Here is an example Python program -> Try It Online!.

Test Cases

WwwvWWWWvvwwwwwwwvWwWw -> 8
w -> 1
W -> 2
vwww -> 3
vWWW -> 6
v -> 0
vvvvvvv -> 0
vwvWvwvWv -> 2
vWWWWWWWWWWvwwwwwwwwwwwwwwwwwwwwwv -> 21
vWWWWWWWWWWvwwwwwwwwwwwwwwwwwwwv -> 20
vvWvv -> 2

This is , so the shortest code in bytes wins!

\$\endgroup\$
  • 2
    \$\begingroup\$ @Shaggy Only the 3 characters I've mentioned are allowed, otherwise it may not look like grass :P \$\endgroup\$ – dingledooper May 7 at 20:14
  • 1
    \$\begingroup\$ Mowing the Grass, to stop it from Growing the Mass! \$\endgroup\$ – xnor May 7 at 21:31
  • 1
    \$\begingroup\$ As someone who has actually mowed quite a bit of grass in my life, I'd say this checks out. \$\endgroup\$ – Lyxal May 7 at 23:52
  • 4
    \$\begingroup\$ Can anyone do it in Grass? \$\endgroup\$ – user92069 May 8 at 0:42
  • 4
    \$\begingroup\$ Hmm, v doesn't look much shorter than w. \$\endgroup\$ – Paŭlo Ebermann May 8 at 9:01

24 Answers 24

18
\$\begingroup\$

Python 2, 49 bytes

lambda s:len(max(s.replace("W","ww").split('v')))

Try it online!

Here's how it works:

  1. Replace each W with ww
  2. Split on v's to produce chunks of consecutive w's
  3. Take the max to get the longest one
  4. Get its length
| improve this answer | |
\$\endgroup\$
12
\$\begingroup\$

Python 3.8, 55 46 44 bytes

Thanks @xnor for saving 2 bytes!
Thanks @dingledooper for saving 2 bytes!

lambda s,t=0:max((t:=c%2*t+c%5%3)for c in s)

Try it online!

A function that takes in a byte string, and returns the max energy.


Cool trick with eval.

Python 2, 61 bytes

lambda s:max(eval("+".join(s+"v").replace("v","0,")))
w=1;W=2

Try it online!

Transforms the given string by adding + between characters, then replaces v with comma (e.g wWvW -> w+W+0,W).

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ Wow, that is some crazy eval! For the 3.8 one, it looks like you can do stuff-~t for t+1+stuff, or directly express t:=t+[2,-t,1][ord(c)%3] since it happens the three chars are distinct mod 3. \$\endgroup\$ – xnor May 7 at 20:44
  • \$\begingroup\$ @xnor Thanks! I was reluctant to go down the mod chain route, but it seems like everything lines up perfectly this time. \$\endgroup\$ – Surculose Sputum May 7 at 21:14
  • 3
    \$\begingroup\$ Oh wow, your mapping the mod to the value is super clean too. \$\endgroup\$ – xnor May 7 at 21:16
  • \$\begingroup\$ Is it a default that we can accept a list of integers/bytes when it states "string"? \$\endgroup\$ – Jonathan Allan May 8 at 1:01
  • \$\begingroup\$ @JonathanAllan I'm not sure myself, but I've seen people done this before. I think this should be allowed, since Python bytes quacks like a string: gets printed like a string, and supports all string operations. Here is a demonstration. \$\endgroup\$ – Surculose Sputum May 8 at 1:11
10
\$\begingroup\$

Jelly,  9  8 bytes

O’%3ṣ0§Ṁ

Try it online!

How?

O’%3ṣ0§Ṁ - Link: list of characters   e.g. "wwwvWvwWww"
O        - ordinals                        [119,119,119,118,87,118,119,87,119,119]
 ’       - decremented                     [118,118,118,117,86,117,118,86,118,118]
  %3     - modulo three                    [1,1,1,0,2,0,1,2,1,1]
    ṣ0   - split at zeros                  [[1,1,1],[2],[1,2,1,1]]
      §  - sums                            [3,2,5]
       Ṁ - maximum                         5
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Wow, works out perfectly with modulo \$\endgroup\$ – QBrute May 8 at 8:20
7
\$\begingroup\$

JavaScript (Node.js), 50 bytes

s=>Math.max(...Buffer(s).map(c=>e+=c%5%3||-e,e=0))

Try it online!

Or 42 bytes if we can take a Buffer (or an array of ASCII codes) as input:

s=>Math.max(...s.map(c=>e+=c%5%3||-e,e=0))

Try it online!

| improve this answer | |
\$\endgroup\$
7
\$\begingroup\$

K (oK), 19 18 13 bytes

Solution:

|/+/'3!5!"v"\

Try it online!

Explanation:

Might be further golfable...

|/+/'3!5!"v"\ / the solution
         "v"\ / split on "v"
       5!     / modulo 5 (turns "vwW" into 3 4 2)
     3!       / modulo 3 (turns 3 4 2 into 0 1 2)
  +/'         / sum (+/) each (')
|/            / take maximum
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ The split fails on the single char test cases. Perhaps you should do |/+/'3!5!"v"\(),. \$\endgroup\$ – Traws May 13 at 13:30
  • \$\begingroup\$ I'd argue that "v" is a char and ,"v" is a string of length 1, which works :) \$\endgroup\$ – streetster May 13 at 20:01
  • 1
    \$\begingroup\$ A fair point, indeed \$\endgroup\$ – Traws May 13 at 20:09
4
\$\begingroup\$

PowerShell 6+ for Windows, 48 bytes

port of math junkie's answer for Retina.

$args-creplace'W','ww'-split'v'|% len*|sort -b 1

Try it online!

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Retina 0.8.2, 19 17 bytes

-2 bytes thanks to @Neil!

W
ww
S_`v
O^`
\Gw

Try it online!

Replaces W with ww, splits at v, sorts by length, then counts the w's in the largest chunk.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Nice; I've never needed to use S_ before. Tip: \Gw counts the number of ws at the beginning of the buffer. You can use this to help shave 2 bytes off your answer. \$\endgroup\$ – Neil May 7 at 20:39
  • \$\begingroup\$ @Neil Cool tip, thanks! \$\endgroup\$ – math junkie May 7 at 20:41
4
\$\begingroup\$

Charcoal, 12 bytes

I⌈E⪪Sv⁺Lι№ιW

Try it online! Link is to verbose version of code. Explanation:

    S           Input string
   ⪪ v          Split on literal `v`
  E             Map over chunks
          ι     Current chunk
         № W    Count of literal `W`
      ⁺         Plus
       Lι       Length of current chunk
 ⌈              Maximum
I               Cast to string for implicit print
| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

J, 26 21 bytes

[:>./0+/;.1@,3|2+3&u:

Try it online!

  • 3&u: Change input to unicode int values
  • 3|2+ Add 2 and then mod 3: Now v becomes 0, w becomes 1, and W 2.
  • 0..., Prepend 0
  • +/;.1 Split by first element (0) and sum the elements of each split chunk
  • [:>./ Take the max
| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

APL (Dyalog Unicode), 21 bytes

(((⌈/+/¨)×⊆⊢)'vwW'∘⍳)

Try it online! Assumes IO is 0.

How it works:

  • we convert v, w and W into 0, 1, 2 respectively;
  • we split on 0s;
  • we sum each run of non-zeroes;
  • and find the max of those.
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Perl 5 with -p0166 -l -MList::Util+max , 22 bytes

$\=max$\,y///c+y/W//}{

Try it online!

Explanation

-p reads STDIN into $_ breaking on each $\, -0166 sets $\ to v and -l strips $\ from the end of each $_ and enables automatically printing $\ when printing the output.

This stores the larger of $\ (initialised to v which is 0 when compared numerically) or y///c (which 'replaces' the empty set of characters with the empty set of characters for every character in the string, returning the count) added to the number of W in the string.

Since $\ is globally scoped, storing it here lasts for each iteration of the script the }{ breaks out of the while (<STDIN>) { loop that -p inserts and terminates it so that instead of the current value of $_ being printed alongside $\, $_ is empty and only $\ is printed.

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

C (gcc), 69 \$\cdots\$ 62 60 bytes

Saved 5 bytes thanks to Arnauld!!!
Saved 2 4 btes thanks to dingledooper!!!

e;m;f(char*g){for(e=m=0;*g;m=m>e?m:e)e=*g%2*e+*g++%5%3;e=m;}

Try it online!

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

05AB1E, 8 bytes

Port of the Jelly answer.

Ç<3%0¡Oà

Try it online!

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Haskell, 51 45 bytes

-6 bytes thanks to Ad Hoc Garf Hunter! Unfortunately all the grass-like operators were already taken :(

g=maximum.scanl(#)0
x#'w'=x+1
x#'W'=x+2
x#_=0

Try it online!

Explanation

scanl is basically a "running total", where for each element of a list, it applies a function to the element and an accumulator, and saves the accumulator at each step. So scanl (+) 0 [1,2,3] gives [0,1,3,6]. We're giving it the function (#) which we've defined to add 1 to the accumulator if the element of the list is 'w', add 2 to the accumulator if it's 'W' or set the accumulator to 0 if it's anything else ('v'). Then we just get the maximum number of the new list, which will be the largest sum we managed to accumulate.

Cool idea I couldn't get to work: mapping = zip "vwW" [(*0),(+1),(+2)]

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Cheers @AdHocGarfHunter :) \$\endgroup\$ – willmcpherson2 May 10 at 13:36
  • \$\begingroup\$ We also don't require you to score the g= since maximum.scanl(#)0 is a function on its own. So if you would like to drop 2 bytes off you may. \$\endgroup\$ – Wheat Wizard May 10 at 17:25
3
\$\begingroup\$

Ruby -naFv, 35 bytes

-naFv enables input on STDIN with auto-split on v into the $F global array.

p$F.map{|w|w.gsub(?W){11}.size}.max

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Jelly, 9 bytes

ṣ”v<”w‘§Ṁ

Try it online!

Explanation

ṣ”v<”w‘§Ṁ  Main Link
ṣ”v        Split on "v"
   <”w     Check if less than "w" ("w" = 0, "W" = 1)
      ‘    Add one to every element
       §   Sum every sublist
        Ṁ  Find the maximum
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 62 bytes

s->{int m=0,n=0;for(var c:s)m=(n=c%2*n+c%5%3)>m?n:m;return m;}

Try it online!

After finishing it, it seems to be a port of Noodle9's C answer.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

C# (Visual C# Interactive Compiler), 69 bytes

Func<string,int>g=s=>s.Replace("W","ww").Split('v').Max(x=>x.Length);

Try it online!

Heavy inspiration from @xnor

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

AWK, 85 82 69 bytes

{FS="v";gsub("W","ww");for(;i<NF;){s=length($++i);m=m>s?m:s;}print m}

Try it online!

Thanks to @dingledooper for cutting off 13 bytes.

The code could be even less, 62 bytes accounting for the field separator flag being a parameter and not part of the actual code.

pretty straightforward: change all W into w, get lenght of words, v counts as field separator. Retain max score with ternary operator.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ A couple basic golf ideas for 69 bytes \$\endgroup\$ – dingledooper May 9 at 5:45
  • \$\begingroup\$ Thanks @dingledooper, very nice touch! I'm not familiar with the rules, but apparently I can put the -F"v" as argument and further reduce the total number of bytes. Is that a valid move? \$\endgroup\$ – Daemon Painter May 9 at 5:50
  • 1
    \$\begingroup\$ Yes you are allowed to add arguments, just make sure you include it in the header. Personally, I rarely use flags, since it seems a bit of a "cheap" golf, but it's up to you :) \$\endgroup\$ – dingledooper May 9 at 5:56
1
\$\begingroup\$

Bash, 28 bytes

sed 's,W,ww,g;y/v/\n/'|wc -L

Input from stdin, output to stdout

There might be a better way.

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I am unsure if "Bash" is really the programming language you are using ... It really depends on the core utils your shell calls. \$\endgroup\$ – Jonathan Frech May 27 at 22:50
  • \$\begingroup\$ @JonathanFrench The language is defined by the interpreter and the interpreter I'm using is the Bash on TIO. \$\endgroup\$ – S.S. Anne May 27 at 23:30
1
\$\begingroup\$

Mathematica, 53 bytes

Max[#~(s=StringCount)~"W"+#~s~_&@StringSplit[#,"v"]]&

More readable, un-golfed code:

Max[StringCount[#,"W"]+StringCount[#,_]&[StringSplit[#,"v"]]]&

StringSplit[#,"v"] takes a string and turns it into a list of strings, seperated by 'v', then add together the length of the string, and the count of 'W's, and take the max value.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Crystal, 57 bytes

def f(a);a.split('v').max_of {|s|s.count('W')+s.size};end

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Rust, 67 bytes

Port of xnor's answer

|s:&str|s.replace("W","ww").split('v').map(str::len).max().unwrap()

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Stax, 14 bytes

π├♦.8Σ0└ó?∟X≈Æ

Try it online!

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.