Even-Odd chunks

4

(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).

Answering some of the comments

  • 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.

user85052

Posted 2019-12-22T12:10:18.320

Reputation:

2Some more test cases would be helpful. Also, can the input be empty? – Luis Mendo – 2019-12-22T13:56:52.837

@LuisMendo Other than leading to some confusion for the viewer, this will not affect the program execution, because this separator will also be interpreted as part of the input string. – None – 2019-12-22T14:02:24.763

Does "any separator that is not an empty string" include the input string itself? – Jonathan Allan – 2019-12-22T14:45:54.127

2May we insert other characters / strings like the MATL answer? – Jonathan Allan – 2019-12-22T15:02:40.400

4May we simply return a list of strings, like the Japt answer used to, and the 05AB1E answer does? – Jonathan Allan – 2019-12-22T15:04:47.113

5Can 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. – Post Rock Garf Hunter – 2019-12-22T16:50:49.230

@WheatWizard, why ask that and not ask whether output can too. Feels like you may as well have asked "Can we take a list of the least significant bits and return a list of lists of bits", since that's all we really care about. I feel like dealing with the I/O was actually most of the challenge here. – Jonathan Allan – 2019-12-23T13:16:21.040

1...Can output be a list of lists of code-points? – Jonathan Allan – 2019-12-23T13:17:08.850

... A string is technically a list of codepoints. – None – 2019-12-23T13:17:41.530

@LuisMendo I have edited the answers into the challenge body. May you point out the parts that are unclearly specified? – None – 2019-12-23T14:11:40.000

I have removed my comments that have been addressed. I suggest you do not refer to specific comment numbers in the challenge text. Comments are temporary – Luis Mendo – 2019-12-24T12:20:23.927

Answers

7

05AB1E, 12 6 4 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..

Try it online or try it online with output as a list of strings instead.

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)

Kevin Cruijssen

Posted 2019-12-22T12:10:18.320

Reputation: 67 575

2

7: Ç¥È0šÅ¡, 6: .¬JÇOÈ

– Grimmy – 2019-12-22T14:55:08.840

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. – Jonathan Allan – 2019-12-22T15:07:06.090

@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! – Kevin Cruijssen – 2019-12-22T18:31:58.840

2@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. – Kevin Cruijssen – 2019-12-22T18:34:14.217

@JonathanAllan OP has clarified that an output as list or using the input as delimiter is allowed. – Kevin Cruijssen – 2019-12-23T11:11:34.707

Note output as a list of list of code-points was never added as an option. I feel like taking a string should never have been changed since it changes the challenge quite a lot, but I've asked for clarification about the output. sigh – Jonathan Allan – 2019-12-23T13:19:21.073

@JonathanAllan Looks like the I/O rules have settled at last, so edited for the final 5-byte result. – Kevin Cruijssen – 2019-12-24T13:03:53.077

5

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

Shaggy

Posted 2019-12-22T12:10:18.320

Reputation: 24 623

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. – Jonathan Allan – 2019-12-22T14:52:20.667

@JonathanAllan: Updated. – Shaggy – 2019-12-22T15:02:29.893

2Oh ha ha Japt's flags to the rescue. – Jonathan Allan – 2019-12-22T15:03:51.400

5

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

Chas Brown

Posted 2019-12-22T12:10:18.320

Reputation: 8 959

4

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

Neil

Posted 2019-12-22T12:10:18.320

Reputation: 95 035

3

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']
     Ʋ  -   last four links as a monad:
 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

Jonathan Allan

Posted 2019-12-22T12:10:18.320

Reputation: 67 804

3

C (clang), 49 bytes

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

Try it online!

AZTECCO

Posted 2019-12-22T12:10:18.320

Reputation: 2 441

1Very nice idea with the least significant bit sum! Applause!! :-) – Noodle9 – 2019-12-24T10:39:20.013

2

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

Luis Mendo

Posted 2019-12-22T12:10:18.320

Reputation: 87 464

2

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

Jonah

Posted 2019-12-22T12:10:18.320

Reputation: 8 729

114 bytes. Cut works better in this case. – Bubbler – 2019-12-23T06:37:38.113

2

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!!!

Noodle9

Posted 2019-12-22T12:10:18.320

Reputation: 2 776

2

JavaScript (Node.js), 94 97 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!

Joost K

Posted 2019-12-22T12:10:18.320

Reputation: 210

1This only work if the input should be split into two strings. Wont work for "aaa", "abcdef". – tsh – 2019-12-24T02:49:18.490

@tsh thanks for pointing it out, I made the wrong assumption that was the only expected input. – Joost K – 2019-12-24T10:22:40.800

1

JavaScript (Node.js), 53 bytes

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

Try it online!

tsh

Posted 2019-12-22T12:10:18.320

Reputation: 13 072