# Even-Odd chunks

(Inspired by the Keg utility of this challenge)

Given a non-empty input string, e.g. s c 1= e(a"E"), split the input into even-odd chunks.

## Example (Feel free to suggest more)

I can only think of this test case, fee free to suggest more.

This input string, when mapped to its code points, yields the list [115, 32, 99, 32, 49, 61, 32, 101, 40, 97, 34, 69, 34, 41]. When applied modulo-2 for every item, this returns [1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1].

In this list let's find the longest possible chunk that is consistent with even and odd code points:

[1, 0, 1, 0, 1], [1, 0, 1, 0, 1, 0, 1, 0, 1]


For the first chunk, this yields [1, 0, 1, 0, 1] because this is the longest chunk that follows the pattern

Odd Even Odd Even Odd Even ...


or

Even Odd Even Odd Even Odd ...


. Adding another codepoint into [1, 0, 1, 0, 1, 1] breaks the pattern, therefore it is the longest possible even-odd chunk that starts from the beginning of the string.

Using this method, we should split the input into chunks so that this rule applies. Therefore the input becomes (the ; here is simply a separator; this can be any separator that is not an empty string, Including the string itself):

s c 1;= e(a"E")


However, returning a list of strings is also permitted.

## Rules

• This is so the shortest solution wins. Let it be known that flags don't count towards being in the pattern. They also don't count towards byte count in this challenge.

• The input will only be in ASCII, and the mapping will always be in ASCII (as far as I can tell most golflangs use a superset of ASCII).

• You may output strings as lists of codepoints.

• "Any separator" includes the input string itself.

• You may insert other characters like the MATL answer, such as alphanumeric characters.

• You may not use integers as input instead of ASCII. Doing that will trivialize the challenge.

• Some more test cases would be helpful. Also, can the input be empty? Commented Dec 22, 2019 at 13:56
• May we insert other characters / strings like the MATL answer? Commented Dec 22, 2019 at 15:02
• May we simply return a list of strings, like the Japt answer used to, and the 05AB1E answer does? Commented Dec 22, 2019 at 15:04
• Can we use integers as input instead of ASCII? It seems needlessly complex to require ASCII as input when we only care about their code points. Commented Dec 22, 2019 at 16:50
• ...Can output be a list of lists of code-points? Commented Dec 23, 2019 at 13:17

# 05AB1E, 1264 5 bytes

Ç.¬+È


Input as a string, output as a 2D list of ASCII codepoint integers.

-6 bytes thanks to @Grimmy.
+1 byte now that the allowed I/O rules are finally settled..

Explanation:

Ç      # Transform the (implicit) input-string to a list of codepoint integers
.¬    # Split this list of integers at:
+   #  Sum the two codepoint at both sides of the potential split
È  #  And check whether it is odd
# (after which the resulting 2D integer list is output implicitly)

• Commented Dec 22, 2019 at 14:55
• The output has more than just the string joined by a separator string. If this is allowed then a function returning a list of strings should be allowed. I have inquired. Commented Dec 22, 2019 at 15:07
• @Grimmy I wasn't even aware we had a .¬ builtin (and it worked like that - I had to add debug-lines to see it was checking between a pair of characters). Thanks! Commented Dec 22, 2019 at 18:31
• @JonathanAllan Ah, missed that part about the delimiter. I assumed a flexible output was allowed by default, since it wasn't mentioned (I read past it). I'll await clarification from OP, but I've added the three trailing characters required to fix it in my answer. Commented Dec 22, 2019 at 18:34
• @JonathanAllan OP has clarified that an output as list or using the input as delimiter is allowed. Commented Dec 23, 2019 at 11:11

# Japt-R, 9 bytes

óÈcv ¦Ycv


Try it

óÈcv ¦Ycv     :Implicit input of string
ó             :Partition
È            :Between characters X & Y where
c           :Charcode of X
v          :Parity
¦        :Is not equal to
Ycv     :Parity of charcode of Y
:Implicit output, joined by newlines

• The output has more than just the string joined by a separator string. If this is allowed then a function returning a list of strings should be allowed. I have inquired. Commented Dec 22, 2019 at 14:52
• @JonathanAllan: Updated. Commented Dec 22, 2019 at 15:02
• Oh ha ha Japt's flags to the rescue. Commented Dec 22, 2019 at 15:03

# Python 2, 72 71 bytes

lambda s:''.join(x+(ord(x)-~ord(y))%2*';'for x,y in zip(s,s[1:]))+s[-1]


Try it online!

1 byte thx to Jonathan Allan

# Charcoal, 19 bytes

⭆θ⁺×¶∧κ¬﹪⁺℅ι℅§θ⊖κ²ι


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

 θ                  Input string
⭆                   Map over characters and join
¶               Literal newline
×                Repeated by
κ             Current index
∧              Logical And
¬            Logical Not
ι        Current character
℅         Ordinal
⁺          Plus
θ     Input string
§      Indexed by
κ   Current index
⊖    Decremented
℅       Ordinal
﹪           Modulo
²  Literal 2
⁺                 Concatenated with
ι Current character
Implicitly print


# Jelly 6 bytes

(7 if we must return a list of strings - add Ọ.)

ḂI¬Żœṗ


A monadic Link accepting a list of integers which yields a list of lists of integers.

Try it online!

### How?

ḂI¬Żœṗj⁷ - Main Link: list of characters (A)
Ḃ        - least significant bit (vectorises)
I       - incremental differences
¬      - logical NOT (vectorises)
Ż     - prepend a zero
œṗ   - at truthy indices (of left) partition (right=A)


### Original challenge 7 bytes

żOḂMḊƲƝ


A full program using 2 as the separator.

Try it online!

### How?

żOḂMḊƲƝ - Main Link: list of characters, S    e.g. ['4','5','7','4','0']
(from program argument '45740')
Ɲ - for neighbours of S:                     ['4','5'] ['5','7'] ['7','4'] ['4','0']
O      -     to ordinal (vectorises)              [52,53]   [53,55]   [55,52]   [52,48]
Ḃ     -     least significant bit (vectorises)   [0,1]     [1,1]     [1,0]     [0,0]
M    -     maximal indices                      [2]       [1,2]     [1]       [1,2]
Ḋ   -     dequeue                              []        [2]       []        [2]
- }                                        [[],[2],[],[2]]
ż       - (S) zip with (that)                      [['4',[]],['5',[2]],['7',[]],['4',[2]],['0']]
- implicit, smashing print                 4527420


# C (clang), 49 bytes

f(char*s){for(;*s;)putchar(*s)+*++s&1||puts("");}


Try it online!

• Very nice idea with the least significant bit sum! Applause!! :-) Commented Dec 24, 2019 at 10:39

# J, 18 14 bytes

<;.1~1,2=/\2|]


Try it online!

-4 bytes thanks to Bubbler

• 2|] remainders mod 2
• 2=/\ consecutive pairs of those, are the equal?
• 1, start it off with a group
• <;.1~ cut into groups using the first element as a delimiter, ie, starting a new group whenever we consecutive items are equal, odd odd or even even
• 14 bytes. Cut works better in this case. Commented Dec 23, 2019 at 6:37

# JavaScript (Node.js), 53 bytes

s=>s.flatMap((c,i)=>c-s[i-1]&1?l.push(c)&&[]:[l=[c]])


Try it online!

# C (clang), 90 ... 67 66 bytes

b;f(char*s){for(b=*s&1;*s;putchar(*s++))b^~*s&1?b=!b:putchar(59);}


Try it online!

Saved 9 10 11 bytes thanks to @ceilingcat!!!

# MATL, 10 bytes

"I@2\XI=f@


Outputs each character on a different line. The separator is 1.

Try it online!

### Explanation

"      % Input: string (implicit). For each
I    %   Push contents of clipboard I, initially 3
@    %   Push current character
2\   %   Modulo 2 of (code point) of that character. Gives 0 or 1
XI   %   Copy result into clipboard I
=    %   Equal? This compares the current and previous contents of
%   clipboard I. Gives true or false
f    %   Find. This outputs indices of true entries. Gives 1 or []
@    %   Push current character
% End (implicit)
% Display stack (implicit), bottom to top. Each entry is displayed
% on a different line. [] is not shown and doesn't start a new line


# JavaScript (Node.js), 9497 95 bytes

+1 byte for allowing more than 1 cut. Had to completely rewrite my code but had a lot of help from tsh's answer

s=>(r=[...s]).map(c=>c.charCodeAt()%2).flatMap((c,i,l)=>c-l[i-1]&1?b.push(r[i])&&[]:[b=[r[i]]])


Try it online!

• This only work if the input should be split into two strings. Wont work for "aaa", "abcdef".
– tsh
Commented Dec 24, 2019 at 2:49
• @tsh thanks for pointing it out, I made the wrong assumption that was the only expected input. Commented Dec 24, 2019 at 10:22

# Ruby, 35 bytes

Returns an Enumerator that yields arrays of code points.

->s{s.bytes.slice_when{_1%2==_2%2}}


Attempt This Online!