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]
Seggan
7,11227 silver badges53 bronze badges
asked Jul 5, 2016 at 18:36
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Is it OK if I return an iterator, rather than a list? \$\endgroup\$ Commented 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\$ Commented 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\$ Commented Jul 5, 2016 at 20:00

96 Answers 96

1 2 3
4
0
\$\begingroup\$

Arturo, (削除) 45 (削除ここまで) (削除) 36 (削除ここまで) 20 bytes

$=>[collect&=>even?]

Try it

answered Nov 9, 2022 at 19:32
\$\endgroup\$
0
\$\begingroup\$

Julia 0.6, 22 bytes

!x=x[cumprod(@.x%2<1)]

Try it online!

also works in julia 1.x

there is Iterators.takewhile but it is way too long

answered Nov 4, 2023 at 16:27
\$\endgroup\$
0
\$\begingroup\$

C (GCC), 43 bytes

i;f(a,n)int*a;{for(;i<n&&~a[i]%2;i++);a=i;}

Attempt This Online!

I/O format: Takes a list and its length, returns the length to which the input list needs chopped. Tricks: ~a[i]%2 checks if a[i] is even, a=i; loads i to rax with -O0, hence avoiding a return. Also uses K&R function declaration and implicit int.

answered Nov 5, 2023 at 16:13
\$\endgroup\$
0
\$\begingroup\$

Perl 5 -p, 9+1 = 10 bytes

(Scored under the system in place at the time of the question.)

$_%2&&die

Try it online!

Input and output both have the entries line separated.

answered Nov 6, 2023 at 17:28
\$\endgroup\$
0
\$\begingroup\$

Vyxal 3, 3 bytes

(1)e⊖

Vyxal It Online!

(1)e⊖­⁡​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁣‏‏​⁡⁠⁡‌­
(1) # ‎⁡next element as lambda:
 e # ‎⁢is-even?
 ⊖ # ‎⁣take from implicit input while function is true
💎

Created with the help of Luminespire.

<script type="vyxal3">
(1)e⊖
</script>
<script>
 args=[["[14, 42, 2324, 97090, 4080622, 171480372]"],["[42, 14, 42, 2324]"],["[7,14,42]"],["[]"],["[171480372, 13, 14, 42]"],["[42, 14, 42, 43, 41, 4080622, 171480372]"]]
</script>
<script src="https://themoonisacheese.github.io/snippeterpreter/snippet.js" type="module"/>

answered Aug 27 at 8:08
\$\endgroup\$
0
\$\begingroup\$

Type(削除) Script (削除ここまで) (TS Type System), (削除) 100 (削除ここまで) 96

type W<T,B=[]>=T extends[infer H,...infer R]?`${H}`extends`${any}${2|4|6|8|0}`?W<R,[...B,H]>:B:B

Input is standard decimal numbers. I wasn't sure if inlining the predicate was allowed based on others' submissions. In case that matters, the even-check can be easily extracted into its own type: type M=${H}`extends`${infer S}${2|4|6|8|0}?1:0.

Since basic arithmetic is really difficult in TS, we have to take whatever exploits we can get. In this case, it's the fact that all even numbers end with [24680].

Type safe version:

type W2<T extends number[],B extends any[]=[]>=
 T extends [infer H, ...infer R]
 ? (H extends number ?
 (`${H}` extends `${any}${2 | 4 | 6 | 8 | 0}`
 ? W<R, [...B, H]>
 : B)
 : never)
 : B;

TS Playground

answered Aug 28 at 15:45
\$\endgroup\$
1 2 3
4

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.