20
\$\begingroup\$

Inspiration.

Task

Reverse runs of odd numbers in a given list of 2 to 215 non-negative integers.

Examples

0 1 → 0 1
1 3 → 3 1
1 2 3 → 1 2 3
1 3 2 → 3 1 2
10 7 9 6 8 9 → 10 9 7 6 8 9
23 12 32 23 25 27 → 23 12 32 27 25 23
123 123 345 0 1 9 → 345 123 123 0 9 1

\$\endgroup\$
9
  • 4
    \$\begingroup\$ 1. I only understood the challenge after looking at the examples. I think runs of odd integers would be clearer than sequences. 2. I don't think setting an explicit upper limit is a good thing. If a language has only 8-bit integers, participating will be a lot harder. \$\endgroup\$
    – Dennis
    Jul 3 '16 at 4:59
  • \$\begingroup\$ Also, I'm not sure what further numeric computation refers to. Does it mean that I cannot return an immutable tuple or simply print the numbers? \$\endgroup\$
    – Dennis
    Jul 3 '16 at 5:10
  • \$\begingroup\$ @Dennis Updated as you suggested. It is to prevent input/output as string. Any suggestion for better wording? \$\endgroup\$
    – Adám
    Jul 3 '16 at 5:14
  • 4
    \$\begingroup\$ Why do you want to prevent string output? \$\endgroup\$
    – Dennis
    Jul 3 '16 at 5:16
  • 2
    \$\begingroup\$ Yes, looking at the other challenge, most of the answers rely on splitting on zeroes, whereas here you'd have to split on a condition, which most languages don't have a built-in for. \$\endgroup\$
    – xnor
    Jul 3 '16 at 7:14

25 Answers 25

8
\$\begingroup\$

Python 2, 75 68 63 bytes

5 bytes thanks to Dennis.

And I have outgolfed Dennis.

Credits to Byeonggon Lee for the core of the algorithm.

o=t=[]
for i in input():o+=~i%2*(t+[i]);t=i%2*([i]+t)
print o+t

Ideone it!

Old version: 75 bytes

\$\endgroup\$
3
  • \$\begingroup\$ Tied, really. Also, I'm counting 81, not 75. I'm guessing you counted it with tabs, but the SE editor filled in spaces. \$\endgroup\$
    – DJMcMayhem
    Jul 3 '16 at 6:02
  • \$\begingroup\$ @DrGreenEggsandIronMan Your guess is correct. Tabs for readability. Either count the source or count the ideone one. \$\endgroup\$
    – Leaky Nun
    Jul 3 '16 at 6:05
  • 1
    \$\begingroup\$ print doesn't need parens. Also, you only use a once, so there's no need for a variable. \$\endgroup\$
    – Dennis
    Jul 3 '16 at 6:20
6
\$\begingroup\$

APL, 21 20 bytes

{∊⌽¨⍵⊂⍨e⍲¯1↓0,e←2|⍵}

Try it || All test cases

Explanation:

                  2|⍵ Select all the odd numbers
                e←    Save that to e
              0,      Append a 0
           ¯1↓        Delete the last element
         e⍲           NAND it with the original list of odd numbers
     ⍵⊂⍨             Partition the list: (even)(even)(odd odd odd)(even)
  ⌽¨                 Reverse each partition
 ∊                    Flatten the list

Edit: Saved a ~ thanks to De Morgan's laws

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Hello, and welcome to PPCG! This is a good post. \$\endgroup\$ Jul 3 '16 at 19:43
5
\$\begingroup\$

Python 2, 79 75 73 bytes

def f(x):
 i=j=0
 for n in x+[0]:
    if~n%2:x[i:j]=x[i:j][::-1];i=j+1
    j+=1

This is a function that modifies its argument in place. Second indentation level is a tabulator.

Test it on Ideone.

\$\endgroup\$
3
5
\$\begingroup\$

Haskell, 46 44 bytes

h%p|(l,r)<-span(odd.(h*))p=l++h:r
foldr(%)[]

Thanks to @xnor for recognizing a fold and saving two bytes.

\$\endgroup\$
2
  • \$\begingroup\$ Nice method, especially the (h*)! You can save a byte on the base case by writing f x=x second to match the empty list, though it looks like a foldr is yet shorter: h%p|(l,r)<-span(odd.(h*))p=l++h:r;foldr(%)[]: \$\endgroup\$
    – xnor
    Jul 5 '16 at 0:32
  • \$\begingroup\$ I knew it was just a foldr after all! Thank you. \$\endgroup\$
    – Lynn
    Jul 5 '16 at 7:02
4
\$\begingroup\$

Jelly, 10 bytes

Ḃ¬ðœpUżx@F

Try it online! or verify all test cases.

How it works

Ḃ¬ðœpUżx@F  Main link. Argument: A (array)

Ḃ           Bit; return the parity bit of each integer in A.
 ¬          Logical NOT; turn even integers into 1's, odds into 0's.
  ð         Begin a new, dyadic link.
            Left argument: B (array of Booleans). Right argument: A
   œp       Partition; split A at 1's in B.
     U      Upend; reverse each resulting chunk of odd numbers.
       x@   Repeat (swapped); keep only numbers in A that correspond to a 1 in B.
      ż     Zipwith; interleave the reversed runs of odd integers (result to the
            left) and the flat array of even integers (result to the right).
         F  Flatten the resulting array of pairs.
\$\endgroup\$
4
\$\begingroup\$

Python 2, 78 75 bytes

def r(l):
 def k(n):o=~n%2<<99;k.i+=o*2-1;return k.i-o
 k.i=0;l.sort(key=k)

Super hacky :)

\$\endgroup\$
4
  • \$\begingroup\$ what is k.i ? \$\endgroup\$
    – Leaky Nun
    Jul 3 '16 at 6:04
  • \$\begingroup\$ @LeakyNun k.i=0 on the last line. It's just a variable. \$\endgroup\$
    – orlp
    Jul 3 '16 at 6:04
  • \$\begingroup\$ I don't get it. Are k and k.i related? \$\endgroup\$
    – Leaky Nun
    Jul 3 '16 at 6:05
  • \$\begingroup\$ @LeakyNun No. k.i is a persistent variable between calls of k. See it as a makeshift global without having to use the global keyword. \$\endgroup\$
    – orlp
    Jul 3 '16 at 6:06
4
\$\begingroup\$

Python3, 96 bytes

Saved a lot of bytes thanks to Leaky Nun!

o=l=[]
for c in input().split():
 if int(c)%2:l=[c]+l
 else:o+=l+[c];l=[]
print(" ".join(o+l))
\$\endgroup\$
1
  • \$\begingroup\$ 93 bytes \$\endgroup\$
    – l4m2
    Jun 4 '20 at 17:50
3
\$\begingroup\$

C, 107 bytes

i;b[65536];f(){for(;i;)printf("%d ",b[--i]);}main(n){for(;~scanf("%d",&n);)n%2||f(),b[i++]=n,n%2||f();f();}
\$\endgroup\$
3
\$\begingroup\$

Pyth, 14 bytes

s_McQshMBx0%R2

           %R2Q   Take all elements of the input list modulo 2
         x0       Get the indices of all 0s
      hMB         Make a list of these indices and a list of these indices plus 1
     s            Concatenate them
   cQ             Chop the input list at all those positions
 _M               Reverse all resulting sublists
s                 Concatenate them

Test cases

\$\endgroup\$
3
\$\begingroup\$

MATL, 20 bytes

TiodgvYsG8XQ!"@gto?P

Input is a column array, using ; as separator.

Try it online!

Explanation

Consider as an example the input array [1;2;3;5;7;4;6;7;9]. The first part of the code, Tiodgv, converts this array into [1;1;1;0;0;1;0;1;0], where 1 indicates a change of parity. (Specifically, the code obtains the parity of each entry of the input array, computes consecutive differences, converts nonzero values to 1, and prepends a 1.)

Then Ys computes the cumulative sum, giving [1;2;3;3;3;4;4;5;5]. Each of these numbers will be used as a label, based on which the elements of the input will be grouped. This is done by G8XQ!, which splits the input array into a cell array containing the groups. In this case it gives {[1] [2] [3;5;7] [4;6] [7;9]}.

The rest of the code iterates (") on the cell array. Each constituent numeric array is pushed with @g. to makes a copy and computes its parity. If (?) the result is truthy, i.e. the array contents are odd, the array is flipped (P).

The stack is implicitly displayed at the end. Each numeric vertical array is displayed, giving a list of numbers separated by newlines.

\$\endgroup\$
2
\$\begingroup\$

Clojure, 86 bytes

#(flatten(reduce(fn[a b](if(odd? b)(conj(pop a)(conj[b](last a)))(conj a b[])))[[]]%))

Here is the ungolfed version

#(flatten ; removes all empty vectors and flattens odd sequences
    (reduce 
        (fn[a b]
            (if(odd? b) ; if we encounter odd number in the seq
                (conj(pop a)(conj[b](last a))) ; return all elements but last and the element we encountered plus the last element of current result
                (conj a b[])) ; else just add the even number and the empty vector
            )
        [[]] ; starting vector, we need to have vector inside of vector if the sequence starts with odd number
        %    ; anonymous function arg
    )   
)

Basically it goes through the input sequence and if it encounters even number it adds the number and the empty vector otherwise if it's an odd number it replaces the last element with this number plus what was in the last element.

For example for this seq 2 4 6 1 3 7 2 it goes like this:

  • []<=2
  • [2 []]<=4
  • [2 [] 4 []]<=6
  • [2 [] 4 [] 6 []]<=1
  • [2 [] 4 [] 6 [1 []]]<=3
  • [2 [] 4 [] 6 [3 [1 []]]]<=7
  • [2 [] 4 [] 6 [7 [3 [1 []]]]]<=2
  • [2 [] 4 [] 6 [7 [3 [1 []]]] 2 []]

And then flattening this vector gives the correct output. You can see it online here: https://ideone.com/d2LLEC

\$\endgroup\$
2
\$\begingroup\$

J, 33 31 30 bytes

[:;]<@(A.~2-@|{.);.1~1,2|2-/\]

Usage

   f =: [:;]<@(A.~2-@|{.);.1~1,2|2-/\]
   f 0 1
0 1
   f 1 3
3 1
   f 1 2 3
1 2 3
   f 1 3 2
3 1 2
   f 10 7 9 6 8 9
10 9 7 6 8 9
   f 23 12 32 23 25 27
23 12 32 27 25 23
   f 123 123 345 0 1 9
345 123 123 0 9 1
\$\endgroup\$
2
\$\begingroup\$

Husk, 7 bytes

ṁ↔ġ¤&%2

Try it online!

Explanation

ṁ↔ġ¤&%2  Implicit input, a list of integers.
  ġ      Group by equality predicate:
   ¤ %2   Arguments modulo 2
    &     are both truthy.
ṁ        Map and concatenate
 ↔       reversing.
\$\endgroup\$
2
\$\begingroup\$

C#, 179 178 177 bytes

s=>{var o=new List<int>();var l=new Stack<int>();foreach(var n in s.Split(' ').Select(int.Parse)){if(n%2>0)l.Push(n);else{o.AddRange(l);o.Add(n);l.Clear();}}return o.Concat(l);}

I use a C# lambda. You can try it on .NETFiddle.

The code less minify:

s => {
    var o=new List<int>();var l=new Stack<int>();
    foreach (var n in s.Split(' ').Select(int.Parse)) {
        if (n%2>0)
            l.Push(n);
        else {
            o.AddRange(l);
            o.Add(n);
            l.Clear();
        }
    }
    return o.Concat(l);
};

Kudos to Byeonggon Lee for the original algorithm.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can drop the space at the foreach(var and change if(n%2==1) to if(n%2>0) to save 2 bytes (or actually 1, because your current answer is 179 bytes instead of 178). \$\endgroup\$ Feb 27 '18 at 8:12
  • \$\begingroup\$ @KevinCruijssen It was changed in the less minify section but not in the minify one. Also thank you for the foreach space! \$\endgroup\$
    – aloisdg
    Feb 27 '18 at 12:54
2
\$\begingroup\$

JavaScript (ES6) 70 66 bytes

Edit 4 bytes saved thx @Neil

a=>[...a,[]].map(x=>x&1?o=[x,...o]:r=r.concat(o,x,o=[]),r=o=[])&&r
\$\endgroup\$
4
  • \$\begingroup\$ :r=r.concat(o,x,o=[]), saves you a couple of bytes. I think you can then go on to save another two like this: a=>[...a,[]].map(x=>x&1?o=[x,...o]:r=r.concat(o,x,o=[]),r=o=[])&&r. \$\endgroup\$
    – Neil
    Jul 3 '16 at 11:26
  • \$\begingroup\$ What is the meaning of ...o? \$\endgroup\$
    – aloisdg
    Jul 3 '16 at 16:20
  • 1
    \$\begingroup\$ @aloisdg codegolf.stackexchange.com/a/37723/21348 \$\endgroup\$
    – edc65
    Jul 3 '16 at 18:13
  • \$\begingroup\$ @Neil the empty array used as the added element is a master stroke \$\endgroup\$
    – edc65
    Jul 4 '16 at 9:18
2
\$\begingroup\$

Ruby, 51 bytes

->l{l.chunk(&:odd?).flat_map{|i,j|i ?j.reverse: j}}

Try it online!

Some slight variations:

->l{l.chunk(&:odd?).flat_map{|i,j|i&&j.reverse||j}}
->l{l.chunk(&:odd?).flat_map{|i,j|!i ?j:j.reverse}}
->l{l.chunk(&:even?).flat_map{|i,j|i ?j:j.reverse}}

Ruby 2.7, 48 bytes

->l{l.chunk{_1%2}.flat_map{_1>0?_2.reverse: _2}}

Unsupported by TIO :(

\$\endgroup\$
1
\$\begingroup\$

Pyth, 29 28 bytes

JYVQ=+J*%hN2+YN=Y*%N2+NY;+JY

Test suite.

Direct translation of my python answer (when has translating from python to pyth become a good idea?)

\$\endgroup\$
1
\$\begingroup\$

TSQL 118 bytes

DECLARE @ TABLE(i int identity, v int)
INSERT @ values(123),(123),(345),(0),(1),(9)

SELECT v FROM(SELECT sum((v+1)%2)over(order by i)x,*FROM @)z
ORDER BY x,IIF(v%2=1,max(i)over(partition by x),i),i desc

Fiddle

\$\endgroup\$
1
\$\begingroup\$

Stax, 15 10 bytesCP437

Çⁿ╜"}☻≥º╚(

Try it online!

Tied Jelly! So sad that packing only saved one byte.

Unpacked version with 11 bytes:

{|e_^*}/Frm

Explanation

{|e_^*} is a block that maps all even numbers n to n+1, and all odd numbers n to 0.

{|e_^*}/Frm
{     }/       Group array by same value from block
 |e            1 if the element is even, 0 if odd.
   _^          Get another copy of the current element and increment by 1
     *         Multiply them
        F      For each group execute the rest of the program
         r     Reverse the group
          m    Print elements from the group, one element per line.
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 11 bytes

.γÉ}ε¬ÉiR]˜

Try it online or verify all test cases.

Explanation:

.γ           # Group the (implicit) input-list by:
  É          #  Check if the value is odd
   }ε        # After the group-by: map each sublist to:
     ¬       #  Get the first value of the subslist (without popping)
      Éi     #  If it's odd:
        R    #   Reverse the sublist
         ]   # Close both the if-statement and map
          ˜  # Flatten the list of lists
             # (after which the result is output implicitly) 
\$\endgroup\$
1
\$\begingroup\$

R, 69 bytes

v=scan();ifelse(o<-v%%2,v[rep(2*cumsum(r<-rle(o)$l)-r+1,r)-seq(v)],v)

Try it online!

Ungolfed, commented version:

o=v%%2              # get the odd numbers in the list
r=rle(o)$l          # find the run lengths of odd/even numbers

# reverse the indices of all the runs:
e=cumsum(r)         # the indices of the ends of each run
ie=rep(e,r)         # for each index in v, the index of the end of its run
is=rep(e-r+1,r)     # for each index in v, the index of the start of its run
irev=is+(ie-seq(v)) # reverses all runs

# the above 4 steps can be combined as:
irev=rep(2*cumsum(r)-r+1,r)-seq(v)

# so: use the reversed indices for odd numbers, and leave the even numbers unchanged
ifelse(o,v[irev],v)
\$\endgroup\$
1
\$\begingroup\$

Clojure, 66 bytes

#(mapcat(fn[x](if(some odd? x)(reverse x)x))(partition-by odd? %))

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Perl 5 with -p, 42 bytes

map{$_%2?$\=$_.$\:print$\.$_,$\=""}$_,<>}{

Try it online!

\$\endgroup\$
0
\$\begingroup\$

J, 27 bytes

[:;]<@(|.^:{.);.1~1,2|2-/\]

Try it online!

A minor improvement over miles' J answer.

How it works

[:;]<@(|.^:{.);.1~1,2|2-/\]  NB. Input: an integer vector V
                  1,2|2-/\]  NB. Pairwise difference modulo 2 and prepend 1
                             NB. giving starting positions for same-parity runs
   ]          ;.1~  NB. Cut V at ones of ^ as the starting point and
      (|.^:{.)      NB. reverse each chunk (head of the chunk) times
                    NB.   (effectively, reverse odd chunks only)
    <@              NB. and enclose it
[:;                 NB. Finally, flatten the result
\$\endgroup\$
0
\$\begingroup\$

JavaScript (Node.js), 53 bytes

a=>a.map((c,k)=>o.splice(n=c&1?+n:k+1,0,c),o=n=[])&&o

Try it online!

JavaScript (Node.js), 54 bytes

a=>a.map((c,k)=>o.splice(n=c&1?n:k+1,0,c),o=[],n=0)&&o

Try it online!

\$\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.