37
\$\begingroup\$

Introduction and Credit

Today without a fancy prelude: Please implement takewhile.

A variation of this (on a non-trivial data structure) was an assignment at my university functional programming course. This assignment is now closed and has been discussed in class and I have my professor's permission to post it here (I asked explicitly).

Specification

Input

The input will be a list (or your language's equivalent concept) of positive integers.

Output

The output should be a list (or your language's equivalent concept) of positive integers.

What to do?

Your task is to implement takewhile (language built-ins are allowed) with the predicate that the number under consideration is even (to focus on takewhile).

So you iterate over the list from start to end and while the condition (is even) holds, you copy to the output-list and as soon as you hit an element that doesn't make the condition true, you abort the operation and output (a step-by-step example is below). This higher-order functionality is also called takeWhile (takewhile).

Potential corner cases

The order of the output list compared to the input list may not be changed, e.g. [14,42,2] may not become [42,14].

The empty list is a valid in- and output.

Who wins?

This is code-golf so the shortest answer in bytes wins!

Standard rules apply of course.

Test Vectors

[14, 42, 2324, 97090, 4080622, 171480372] -> [14, 42, 2324, 97090, 4080622, 171480372]
[42, 14, 42, 2324] -> [42, 14, 42, 2324]
[7,14,42] -> []
[] -> []
[171480372, 13, 14, 42] -> [171480372]
[42, 14, 42, 43, 41, 4080622, 171480372] -> [42, 14, 42]

Step-by-Step Example

Example Input: [42, 14, 42, 43, 41, 4080622, 171480372]

Consider first element: 42
42 is even (21*2)
Put 42 into output list, output list is now [42]

Consider second element: 14
14 is even (7*2)
Put 14 into output list, output list is now [42,14]

Consider third element: 42
42 is even (21*2)
Put 42 into output list, output list is now [42,14,42]

Consider fourth element: 43
43 is not even (2*21+1)
Drop 43 and return the current output list

return [42,14,42]
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Is it OK if I return an iterator, rather than a list? \$\endgroup\$
    – DJMcMayhem
    Jul 5, 2016 at 19:45
  • 2
    \$\begingroup\$ @DrGreenEggsandIronMan I'm guessing your function has to be able to take its output as its input, guaranteeing they are in the same format. \$\endgroup\$
    – mbomb007
    Jul 5, 2016 at 19:47
  • \$\begingroup\$ @DrGreenEggsandIronMan, I don't think that returning a sublist should be exploited here in the output format. (It's still up to you if you exploit this in your code though). Mbomb's criterion looks most appropriate and compatible with the current challenge so it will be "your output should be a valid input at the very least". \$\endgroup\$
    – SEJPM
    Jul 5, 2016 at 20:00

94 Answers 94

29
\$\begingroup\$

Mathematica, 18 bytes

#~TakeWhile~EvenQ&

Another glorious built-in that is beaten by a factor of 3 by golfing languages without the built-in...

\$\endgroup\$
4
  • 4
    \$\begingroup\$ How many built-ins does Mathematica have? Seems as if it has one for almost anything. \$\endgroup\$
    – Emigna
    Jul 5, 2016 at 19:06
  • 38
    \$\begingroup\$ @Emigna I haven't counted, but Rule #110 of the internet is, "If it exists, there's a Mathematica built-in for it." \$\endgroup\$ Jul 5, 2016 at 19:07
  • 5
    \$\begingroup\$ @MartinEnder Too bad that Rule #110.5 of the internet is, "If it involves strings in any way whatsoever, then it is not considered to exist for the purposes of Rule #110." \$\endgroup\$ Jul 6, 2016 at 11:26
  • \$\begingroup\$ @LegionMammal978 The workaround is to make strings heads of expressions :) \$\endgroup\$
    – LLlAMnYP
    Jul 7, 2016 at 11:03
28
\$\begingroup\$

Haskell, 13 bytes

fst.span even

span splits the input list into a pair of lists just before the first element where the predicate (-> even) is false. fst takes the first element of the pair.

Alternative version, 13 bytes:

fst.break odd

break is the opposite of span, i.e. it splits the list at the first element where the predicate is true.

Of course there's also

takeWhile even

but that's 14 bytes.

\$\endgroup\$
25
\$\begingroup\$

MATL, 6 bytes

toYs~)

Try it online!

Explanation

t    % Input array implicitly. Duplicate
o    % Parity of each entry. Gives 0 for even entries, 1 for odd
Ys   % Cumulative sum
~    % Logical negate. Gives true for the first run of even entries, and then false
)    % Use this as logical index into the original array. Implicitly display
\$\endgroup\$
2
  • 25
    \$\begingroup\$ Is this normal, that the code says "toys" with a smile there? \$\endgroup\$
    – SEJPM
    Jul 5, 2016 at 18:56
  • 5
    \$\begingroup\$ @SEJPM to~Y<) also works, but I like this one better :-) \$\endgroup\$
    – Luis Mendo
    Jul 5, 2016 at 18:56
14
\$\begingroup\$

Hexagony, 19

2.}<@>%?<{>$"/\M!8;

Readable:

  2 . }
 < @ > %
? < { > $
 " / \ M
  ! 8 ;

Try it online!

This can probably be golfed by a byte or two, but that might require some truly ingenious layout, that might be more easily found via brute force (even if it might take rather long to find it).

High level explanation

The program mostly follows this pseudocode:

while (read number is not zero) 
{
    if (number is even) 
        print number;
} 

Which abuses how Hexagony tries to read a number once STDIN is empty (it returns a zero). Big thanks to Martin for help with coming up with this approach.

Full Explanation

I still haven't fiddled around with Mono to get Timwi's fantastic esoteric IDE running, so I've leant on Martin to provide me with some helpful pretty pictures!

First, a little primer on basic control flow in Hexagony. The first instruction pointer (IP), which is the only one used in this program, starts at the top left of the hexagonal source code, and begins moving towards the right. Whenever the IP leaves the edge of the hexagon, it moves side_length - 1 rows towards the middle of the hexagon. Since this program uses a side length three hexagon, the IP will always be moving two rows when this happens. The only exception is if it moves off of the middle row, where it conditionally moves towards the top or bottom of the hexagon, depending on the value of the current memory edge.

Now a bit about conditionals. The only conditionals in Hexagony for control flow are >, < and the middle edge of the hexagon. These all follow a constant rule: if the value on the current memory edge is zero or negative control flow moves left and if is positive the control flows right. The greater than and less than brackets redirect the IP at sixty degree angles, while the edge of the hexagon controls to which row the IP jumps.

Hexagony also has a special memory model, where all data is stored on the edges of an infinite hexagonal grid. This program only uses three edges: one to store a two, one for the currently read number, and one for the number modulo two. It looks something like:

Mod  \ / Input
      |
      2

I'm not going to carefully explain where we are in memory at each point during the explanation of the program, so come back here if you get confused by where we are in memory.

With all of that out of the way, the actual explanation can begin. First, we populate the "2" edge in memory with a 2, then we execute a no-op and move the memory pointer to the right (2.}).

Next, we begin the main program loop. We read the first number from STDIN and then we hit a conditional (?<). If there are no numbers left in STDIN, this reads a zero into the current memory edge, so we turn left onto the @, which ends the program. Otherwise, we bounce off a mirror, move the memory pointer backwards and to the left, wrap around the hexagon to calculate the remainder of dividing the input by 2 and then hit another conditional (/"%>).

Odd Path

If the remainder was one (i.e. the number was odd), we turn right following the blue path above starting by executing the no-op again, then we wrap around to the bottom of the hexagon, multiply the current edge by 10 and then add eight, bounce off a couple mirrors, do the same multiplication and addition again, getting 188 on the current edge, wrapping back around to the top of the hexagon, executing the no-op again, and finally ending the program (.8/\8.@). This convoluted result was a happy accident, I originally had written a much simpler bit of logic, but noticed that I could remove it in favour of the no-op, which I thought was more in the spirit of Hexagony.

Even Path

If the remainder was zero we instead turn left following the red path, above. This causes us to move the memory pointer to the left, and then print the value there (the input value) as a number. The mirror we encounter acts as a no-op because of the direction we are moving ({/!). Then we hit the edge of the hexagon which acts a conditional with only one outcome, as the input value from before was already tested to be positive, so we always move towards the right (if you imagine yourself facing in the direction of the IP). We then multiple the input by 10 and add two, only to change direction, wrap around and overwite the new value with the ascii value of the capital letter M, 77. Then we hit some mirrors, and exit over the edge of the middle of the hexagon with a trampoline (2<M\>$). Since 77 is positive, we move right towards the bottom of the hexagon and because of the trampoline skip the first instruction (!). We then multiply the current memory edge by 10 and add 8, getting 778. We then output this value mod 256 (10) as an ASCII character, which happens to be newline. Finally we exit the hexagon and wrap back around to the first ? which overrides the 778 with the next input value.

\$\endgroup\$
1
  • 9
    \$\begingroup\$ Readable yeah right \$\endgroup\$
    – Taylan
    Jul 6, 2016 at 13:09
11
\$\begingroup\$

ed, 13

/[13579]$/,$d

Because real programmers use The Standard Text Editor.

Takes input as one integer on each line; outputs in the same format.

This simply finds the first odd number (number ending in an odd digit) and deletes from that line until the end of the file.

\$\endgroup\$
1
  • \$\begingroup\$ uhhhhh. so that's what that program is for. \$\endgroup\$
    – cat
    Jul 6, 2016 at 2:32
10
\$\begingroup\$

Pyth, 13 9 7 bytes

uPWs%R2

Credits to @FryAmTheEggman for 2 (quite tricky) bytes!

Explanation:

u       Q    keep applying to input until invariant:
 PW          drop last element if...
   s%R2G     ...any one is odd, G is the argument originally given the value of input

Test it here.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ This is not quite a correct variable introduction description. There should be two Gs introduced, one for the condition s%R2G and one as the argument to the function P. \$\endgroup\$
    – isaacg
    Nov 7, 2017 at 4:48
9
\$\begingroup\$

Jelly, 5 bytes

Ḃœp⁸Ḣ

Try it online! or verify all test cases.

How it works

Ḃœp⁸Ḣ  Main link. Argument: A (array)

Ḃ      Bit; yield 1 for odd integers, 0 for even ones.
   ⁸   Yield A.
 œp    Partition A, splitting at 1's in the bit array.
       This yields a 2D array of runs of even integers.
    Ḣ  Head; extract the first chunk.
\$\endgroup\$
8
\$\begingroup\$

Python 2, 43 42 bytes

def f(x):
 while"1'"in`map(bin,x)`:x.pop()

The function modifies its argument in place.

Thanks to @xnor for golfing off a byte in a really clever way!

Test it on Ideone.

\$\endgroup\$
2
  • 5
    \$\begingroup\$ This is crazy, but I think you can check for an odd element as "1'"in`map(bin,x)` for Python 2. \$\endgroup\$
    – xnor
    Jul 5, 2016 at 23:34
  • \$\begingroup\$ That's brilliant. Thanks! \$\endgroup\$
    – Dennis
    Jul 5, 2016 at 23:47
7
\$\begingroup\$

Clojure, 21 bytes

#(take-while even? %)

Clojure is kinda nearly competing at last! (thanks to the task being a built-in) See it online https://ideone.com/BEKmez

\$\endgroup\$
6
\$\begingroup\$

Python, 45 44 bytes

f=lambda x:x and~x[0]%2*x and x[:1]+f(x[1:])

Test it on Ideone.

\$\endgroup\$
7
  • \$\begingroup\$ Aww man.. And there goes any chance I thought I had at winning a bounty \$\endgroup\$
    – DJMcMayhem
    Jul 5, 2016 at 19:51
  • 1
    \$\begingroup\$ Only pure code-golf questions with no restrictions posted before July 22, 2015 are eligible. \$\endgroup\$
    – Dennis
    Jul 5, 2016 at 19:52
  • \$\begingroup\$ @DrGreenEggsandIronMan Mine has been shorter than yours the entire time. I posted mine first. :P \$\endgroup\$
    – mbomb007
    Jul 5, 2016 at 19:53
  • 2
    \$\begingroup\$ Outgolfed by Dennis, who would've thought :) \$\endgroup\$
    – shooqie
    Jul 5, 2016 at 19:53
  • \$\begingroup\$ @mbomb007 sure about that? \$\endgroup\$
    – DJMcMayhem
    Jul 5, 2016 at 19:54
6
\$\begingroup\$

Brainf***, 263 bytes

I took a little snippet from here

>>>>>>,[>>>>>>,]>++++[<++++++++>-]>>>>>+>>>>>>>++++[<++++++++>-]<<<<<<<[<<<<<<]>>>>>>[[>>>>>>>++++[<-------->-]<]<<<<<<[->>>+<<<]>>>[-<+<<+>>>]<>>+>+<<<[-[->]<]+>>>[>]<[-<]<[-]<-[<[<<<<<<]>>>>>>.>>>>>>[>[-]++++[<++++++++>-]<.>>>>>>]>++++[-<++++++++>]<.[-]]>>>>>>]

I'd give an explanation but even I don't have a clue how this works anymore.

Expects input as space-seperated numbers (eg 2 432 1)

\$\endgroup\$
4
  • \$\begingroup\$ Takewhile in BF ._. +1 \$\endgroup\$ Jul 8, 2016 at 20:31
  • \$\begingroup\$ You can probably golf the chains of + and > using some logic? \$\endgroup\$
    – Riker
    Jul 8, 2016 at 20:33
  • \$\begingroup\$ @EᴀsᴛᴇʀʟʏIʀᴋ quite a few of the chains are already golfed (otherwise there would be a lot of rows of 32 '+'s), and I could probably make some of the >s more efficient but I don't understand them enough now \$\endgroup\$ Jul 8, 2016 at 20:35
  • \$\begingroup\$ That's why you should comment your code as you write it in Notepad. :P \$\endgroup\$
    – mbomb007
    Jul 8, 2016 at 21:02
5
\$\begingroup\$

R, 25 bytes

x=scan()
x[!cumsum(x%%2)]

Or equivalently

(y=scan())[!cumsum(y%%2)]
\$\endgroup\$
1
  • \$\begingroup\$ this is elegant. \$\endgroup\$ Aug 10, 2016 at 15:58
5
\$\begingroup\$

05AB1E, 8 7 bytes

[DÉO_#¨

Explanation

[        # infinite loop start
 DÉO     # count odd numbers
    _    # push negative bool (turning 0->1, X->0)
     #   # if true (no odd numbers exist), break out of loop and implicitly print
      ¨  # else, remove last element from list

Try it online

Previous 8 byte solution

vyÈiyˆëq

Explanation

v         # for each y in input
 yÈi      # if y is even
    yˆ    # push y to global array
      ëq  # else terminate program
          # implicitly print global array

Try it online

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

Labyrinth, 14 bytes

?:
"`#
"@%
\!;

Input and output are linefeed-separated lists (although in principle, the input could use any non-digit separator).

Try it online!

This is probably the most compact Labyrinth program I've ever written.

Interestingly, takewhile(odd) is lot simpler:

?:#
" %
\!/

Explanation

The usual Labyrinth primer:

  • The memory model is a stack (there's actually two, but we'll only need one for this program), which holds arbitrary-precision integers and initially holds an (implicit) infinite number of zeros.
  • There are no control flow instructions. Instead, the movement of the instruction pointer (IP) is determinated by the layout of the code (spaces are considered "walls" and cannot be traversed by the IP). Normally, the code is supposed to resemble a maze, where the IP follows straight corridors and bends, but whenever it reaches a junction, this acts as a conditional where the IP's new direction is determined based on the current state. The rules for choosing a direction boil down to this: if the top of the stack is zero, the IP keeps moving forward; if the top is positive, the IP turns right; if the top is negative the IP turns left. If one of these directions is blocked by a wall, the IP takes the opposite direction instead. This means that programs without clear corridors are usually incredibly tough to work with, because every single command would act as a junction. The fact that this worked out in this case is a bit of a miracle.
  • The IP starts at the first non-space character in reading order (? in this case), moving east.

The main flow through the program is a single loop around the perimeter:

>v
^>v
^@v
^<<

As it happens, we know that the top of the stack is zero after ! and " so that the IP is guaranteed not to turn towards the centre. ` and % on the other hand are used as conditionals where the IP might move towards the centre such that @ terminates the program, or it might keep moving around the perimeter.

Let's look at the code in the loop:

?   Read decimal integer N from STDIN, or 0 at EOF.
:   Duplicate. Since this is just a corner, the IP always turns south.
`   Negate the copy of the input (i.e. multiply by 1). At EOF, the result
    is still zero and the IP keeps moving south into the @. Otherwise, the
    top of the stack is now negative, and the IP turns east.
#   Push the stack depth (i.e. 2). Again, this is a corner, and the IP
    is forced to turn south.
%   Computer (-N % 2), which is identical to (N % 2) to determine the
    parity of the input. If input was odd, this gives 1, and the IP turns
    west into the @. Otherwise, the result is 0 and the IP keeps moving
    south, continuing the loop.
;   Discard the 0. This is a corner, so the IP is forced to turn west.
!   Print (and discard) N. The top of the stack is now one of the implicit
    zeros at the bottom, so the IP keeps moving west.
\   Print a linefeed. The IP is forced to turn north in the corner.
""  Two no-ops. The top of the stack is still zero, so the IP keeps moving north.

And then the loop starts over.

That raises the question why takewhile(odd) is so much simpler. There's two reasons:

  • Since EOF is returned as 0 (which is even), we don't need a separate EOF check. The list would be cut off at that point anyway.
  • Now we want to terminate when N % 2 is 0 (as opposed to 1), which means instead of conditional control flow we can simply divide the other copy N by N % 2: if the input is odd, that just leaves N and we even got rid of the N % 2 (so we don't need ;), but if the input is even, that simply terminates the program with a (silent) division-by-zero error.

Hence, the other code is a simple loop that doesn't allow for any branching at all.

\$\endgroup\$
4
\$\begingroup\$

Pyth, 7 bytes

<x%R2Q1

Try it here!

What I attempted to do in Pyke but index is broken in that atm

\$\endgroup\$
4
\$\begingroup\$

Racket, 22 bytes

(λ(n)(takef n even?))

The λ character is counted as 2 bytes.

I haven't seen Racket used before in any of the code golfing answers I've seen, so I had to do it at least once!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ I used to golf in Racket, hooray for Racket! \$\endgroup\$
    – cat
    Jul 6, 2016 at 1:17
4
\$\begingroup\$

Perl 5 + Perligata, 173 bytes

145 bytes, plus 28 for -MLingua::Romana::Perligata

Use as perl -MLingua::Romana::Perligata foo.pl; input (from stdin) and output (to stdout) are underscore-separated strings of decimal integers. Tested on Strawberry 5.20.2 with version 0.6 of Perligata, released two days ago; I don't know whether it works with Perligata version 0.50.

huic vestibulo perlegementum da.his _ scindementa da.per in his fac sic
si recidementum hoc tum II fac sic I exi cis
hoc tum _ egresso scribe
cis

Obviously this is clear as a bell. In case it's not, run it with -MLingua::Romana::Perligata=converte instead of -MLingua::Romana::Perligata, and perl will, instead of running the script, output a translation into regular Perl:

 $_ = Lingua::Romana::Perligata::getline (*STDIN );
 @_ = split ( '_');
for $_ (@_) {if ( ($_ % 2)) {exit ( 1)}
;
print (STDOUT $_, '_')}

For a token-by-token analysis, use -MLingua::Romana::Perligata=discribe.


Golfing notes:

  • It seems from the documentation that ultimus si recidementum hoc tum II fac. would work instead of si recidementum hoc tum II fac sic ultimus cis, saving 7 bytes. But it doesn't (it gives a "iussa absentia" error).
  • Undocumented (but unsurprising), you don't need a space after ..
  • (Also unsurprising,) scinde doesn't need a second argument, and uses hoc. Alas, exi needs an argument.
  • Instead of huic vestibulo perlegementum da, I tried -pMLingua::Romana::Perligata, but couldn't get it to work.

Just for kicks (although this whole answer was just for kicks):

  • After cleaning it up to Huic vestibulo perlegementum da. His lacunam scindementa da. Per in his fac sic si recidementum hoc tum II fac sic I exi cis. Hoc tum lacunam egresso scribe cis., Google Translate gives This court perlegementum grant. His gap scindementa grant. 2 By that time, do so in the following 1, Go out and do so if recidementum on this side. This was the gap as soon as write on this side..
\$\endgroup\$
1
  • 1
    \$\begingroup\$ what is this witchery \$\endgroup\$ Jul 8, 2016 at 15:57
4
\$\begingroup\$

Perl 6, 14 bytes

{|$_,1...^*%2}

Try it online!

Finally, a use for a neat trick I found involving .... This is an anonymous code block that basically filters the list until it reaches an element that succeeds in the condition *%2 i.e. odd. Then we return the list excluding the last element. Since an element has to pass the condition at some point, otherwise it attempts to extrapolate off the end of the list, we append a 1 to the input list.

Note this isn't the intended use for the sequence operator ..., which is usually used to create sequences based off several parameters. We're using the behaviour that the end condition is checked against the starting elements as well, and will stop even before any new elements are generated.

Explanation:

{            }  # Anonymous code block
 |$_,1          # Using the input list appended with 1
      ...       # Take up to
          *%2   # The element that is odd
         ^      # And exclude the last element
\$\endgroup\$
5
  • \$\begingroup\$ :P i think a lot of people know about the trick \$\endgroup\$
    – ASCII-only
    Apr 4, 2019 at 23:28
  • \$\begingroup\$ @ASCII-only Really? I haven't seen it before in the wild, if you could point me to any solutions that use ... to filter a list like this, I'd be very interested to see them \$\endgroup\$
    – Jo King
    Apr 4, 2019 at 23:31
  • \$\begingroup\$ it's not really filtering though, i thought it's just the conventional use of creating a range until a predicate is satisfied? \$\endgroup\$
    – ASCII-only
    Apr 4, 2019 at 23:33
  • \$\begingroup\$ well, the other conventional use \$\endgroup\$
    – ASCII-only
    Apr 4, 2019 at 23:35
  • 1
    \$\begingroup\$ i mean, i guess the "checked against the starting elements" usually isn't taken advantage of \$\endgroup\$
    – ASCII-only
    Apr 5, 2019 at 9:57
3
\$\begingroup\$

Dyalog APL, 11 bytes

{⍵/⍨∧\~2|⍵}

2| division remainder from dividing with 2

~ negate

∧\ AND-scan (turns off from first 0)

/⍨ select where

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

Brachylog, 19 16 bytes

hH:2%0,?b&~b.hH;[].

s.:Mc?,.:{:2%0}a

Explanation

s.                 Output is an ordered subset of Input
  :Mc?,            The concatenation of Output with a list M is Input
       .:{:2%0}a   All elements of Output are even

Today I learnt a neat trick (which was used in the 19 bytes answer): ~b.hH is shorter than :[H]rc. to append an element at the beginning of a list. The first one means "Output is the result with an extra item at the beginning, and the first item of the Output is H", whereas the other one is straightforwardly "Output is the concatenation of [[H], Result]".

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

J, 10 bytes

{.~2&|i.1:

Explanation

{.~2&|i.1:  Input: s
   2&|      Take each value in s mod 2
      i.1:  Find the index of the first 1
{.~         Take that many values from s and return
\$\endgroup\$
2
  • \$\begingroup\$ 1{.2&|<;._2] is interesting (although longer) \$\endgroup\$
    – Leaky Nun
    Jul 7, 2016 at 10:41
  • \$\begingroup\$ Use $ instead of {. \$\endgroup\$
    – FrownyFrog
    Mar 11, 2018 at 15:50
3
\$\begingroup\$

Python, 41 bytes

lambda l:l[:[x%2for x in l+[1]].index(1)]

Truncates l up to the index of the first occurrence of an odd number. The index is found by looking for a 1 in the values modulo 2. To guard against no odd number being found, a 1 is put on the end.

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

C#, 50 bytes

int[]f(int[]a)=>(a.TakeWhile(x=>x%2<1).ToArray());
\$\endgroup\$
1
  • \$\begingroup\$ You can use a lambda directly. It is valid as far as I know. a=>a.TakeWhile(x=>x%2<1); \$\endgroup\$
    – aloisdg
    Jul 6, 2016 at 17:02
3
\$\begingroup\$

CJam, 11 bytes

Thanks to @Dennis for two corrections and one byte off!

{1+_2f%1#<}

This is a code block (equivalent to a function; allowed by default) that expects the input array on the stack, and leaves the output array on the stack.

Try it online!

Explanation

{         }    e# define code block
 1+            e# attach 1 at the end of the array
   _           e# duplicate
    2f%        e# modulo 2 of each entry
       1#      e# find index of first occurrence of 1
         <     e# slice before
\$\endgroup\$
0
3
\$\begingroup\$

Retina, 17 bytes

 ?\d*[13579]\b.*

The trailing linefeed is significant. Input and output are space-separated lists.

Try it online!

This is a simple regex substitution, it matches the first odd number (i.e. a number ending in an odd digit), and if possible the space preceding it as well as everything after it and replaces it with an empty string, i.e. all elements from there onward are removed from the input.

As Leaky Nun points out, taking the list in binary, we can save 6 bytes, but it seems a bit cheaty, so I'll probably continue counting the decimal version:

 ?\d*1\b.*

\$\endgroup\$
1
  • \$\begingroup\$ You can take the list in binary? \$\endgroup\$
    – Leaky Nun
    Jul 7, 2016 at 10:37
3
\$\begingroup\$

JavaScript, 27 25 bytes

a=>a.filter(v=>a=a&&~v%2)

The filer expression repeatedly assigns to a and uses the value of a as a filter predicate. a holds either the initial array value (always truthy) or the boolean of whether only even values have been seen. When a turns false (i.e., an odd number appears), then subsequent runs of the a = a && ... logical AND operation short cirucits, and we use false for the rest of the run.

The bitwise NOT ~v turns even numbers to odd and vice versa, so ~v%2 returns a truthy value for even input and falsy values for odd input.

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

SML, 44 bytes

an assignment at my university functional programming course

Yay, functional programming! So as an assignment solution, this would probably look like this:

(* 'a takeWhile : ('a -> bool) -> 'a list -> 'a list *)
fun takeWhile p nil     = nil
  | takeWhile p (x::xr) = if p x then x :: takeWhile p xr else nil

(* takeWhileEven : int list -> int list *) 
val takeWhileEven = takeWhile (fn x => x mod 2 = 0)

which can be golfed to

fun t[]=[]|t($ :: &)=if$mod 2=0then$ ::t&else[]

However using foldr is 3 bytes shorter:

foldr(fn($,r)=>if$mod 2=0then$ ::r else[])[]
\$\endgroup\$
3
\$\begingroup\$

JavaScript (Firefox 30-57), 30 bytes

a=>[for(x of a)if(!(a|=x&1))x]
\$\endgroup\$
2
\$\begingroup\$

V, 13 bytes

íä*[13579]¾.*

Try it online!

Explanation:

í              "search for, on every line
 ä*            "Any number of digits
   [13579]     "Followed by an odd digit
          ¾    "Then the end of a word,
           .*  "Followed by anything
               "(implicit) and replace it with nothing.

Conveniently, the same code works to verify all test-cases simultaneously.

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

Ruby, 25 bytes

->a{a.take_while &:even?}

I think I lose...

\$\endgroup\$
2
  • \$\begingroup\$ Can you do ->a{a.take_while &:even?} or at least ->a{a.take_while(&:even?)}? \$\endgroup\$ Jul 5, 2016 at 19:11
  • \$\begingroup\$ @MartinEnder Thank you. I was looking for something like that, but I guess I am not well versed in ruby golfing syntax. \$\endgroup\$
    – MegaTom
    Jul 5, 2016 at 19:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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