18
\$\begingroup\$

The aim is to trim elements in from the ends of a list, depending on if they are in a second list of "falsey" results.

For example, if the first list is [-1, 1, 2, 0, -1, 3, -1, 4, -1, -1] and the second is [-1], then we would remove all leading and trailing -1s from the first input, but not any -1s in the middle: [1, 2, 0, -1, 3, -1, 4]

You may take input in any allowed method and this is so the shortest code in bytes wins.

\$\endgroup\$
3
  • \$\begingroup\$ Let us continue this discussion in chat to prevent extended discussion in comments. \$\endgroup\$
    – Makonede
    Mar 30, 2021 at 17:32
  • 13
    \$\begingroup\$ Additionally, I would suggest adding in some more test cases, including ones where the "falsey" list has more than one element \$\endgroup\$ Mar 30, 2021 at 18:28
  • \$\begingroup\$ From being closed, to being reopened, and finally to making it to the HNQ, this post has seen it all... \$\endgroup\$
    – Arjun
    Apr 2, 2021 at 1:27

25 Answers 25

7
\$\begingroup\$

Haskell, 37 36 bytes

f v|g<-reverse.snd.span(`elem`v)=g.g

Try it online!

  • -1 byte thanks to xnor.

How?

f v                     -- define a function f that takes as input a list v of falsey values
  |g<-                  --   inside the definition, define a new function g that...
    reverse             --     reverses...
    .snd                --     the second element of...
    .span               --     a tuple (say (x,y)) where x is the longest prefix of elements that...
      (`elem`v)         --       belong to v...
                        --     and y is the rest of the list
  =g.g                  --   f is defined as the composition g.g (basically apply g twice)
\$\endgroup\$
1
  • 4
    \$\begingroup\$ I think you can use snd.span for dropWhile \$\endgroup\$
    – xnor
    Mar 30, 2021 at 18:41
6
\$\begingroup\$

Pyth, 3 bytes

.sF

Try it here!

\$\endgroup\$
2
  • \$\begingroup\$ I'm not sure how Pyth handles 2 inputs, but is it possible to remove the F and take the two inputs separately? \$\endgroup\$ Mar 30, 2021 at 21:30
  • \$\begingroup\$ Pyth takes input from the lines of stdin. Unfortunately, only the first input (i.e. the first line) can be implicit. You could take the inputs separately, but it wouldn't save any bytes. \$\endgroup\$
    – hakr14
    Mar 30, 2021 at 22:00
4
\$\begingroup\$

Factor + math.unicode, 19 bytes

[ '[ _ ∈ ] trim ]

Try it online!

Explanation:

It's a quotation (anonymous function) that takes two sequences as input and returns one sequence as output.

  • '[ _ ∈ ] Push a fried quotation to the data stack to be used later by trim. Whatever is on top of the data stack gets slotted into the quotation at the _. This will be the list of elements to trim.
  • trim Take a sequence and a quotation and apply the quotation to elements on both ends of the sequence, removing elements for which the quotation returns t. Stop when f is encountered.
  • Take an object and a sequence and return t if the object is in the sequence. Shorthand for member?.
\$\endgroup\$
1
  • \$\begingroup\$ Nice, exactly what I thought of when I saw the challenge. \$\endgroup\$
    – Bubbler
    Mar 30, 2021 at 23:09
4
\$\begingroup\$

APL (Dyalog Extended), 4 bytes (SBCS)

Anonymous infix function.

⌂deb

Try it online!

A library function: delete ending blanks using the left argument as a list of what is considered "blanks".

Notes, comments, and APL implementation.

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

Java, 89 bytes

a->b->a.dropWhile(b::contains).sorted((c,d)->-1).dropWhile(b::contains).sorted((c,d)->-1)

Try it online!

Java, 125 bytes

a->b->{int i=-1,j=a.length;for(;b.contains(a[++i]););for(;b.contains(a[--j]););return java.util.Arrays.copyOfRange(a,i,j+1);}

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ 86 bytes, using LinkedList \$\endgroup\$ Apr 1, 2021 at 10:44
  • \$\begingroup\$ @OlivierGrégoire Nice idea. You could post that as another answer. \$\endgroup\$ Apr 1, 2021 at 13:04
  • 1
    \$\begingroup\$ Okay, I've done it. \$\endgroup\$ Apr 1, 2021 at 14:38
3
\$\begingroup\$

05AB1E, 1 byte

Ú

Try it online!

A builtin which trims.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Hey, I was about to post this… >:( \$\endgroup\$
    – Makonede
    Mar 30, 2021 at 19:34
3
\$\begingroup\$

JavaScript (V8), 78 62 bytes

-16 bytes thanks to @Original Original Original VI

(a,s,g=x=>s.includes(x[0])?g(x.slice(1)):x.reverse())=>g(g(a))

Old:

a=>n=>(t=z=>z.findIndex(d=>!n.includes(d)),a.slice(t(a),-t([...a].reverse())))

Can probably be shortened by a ton

\$\endgroup\$
3
  • \$\begingroup\$ f([-1, 1, 2, 0, -1, 3, -1, 4, -1, -1])([2, -1, 1]) seems to give an empty array, am I doing something wrong or is there a bug in the code? \$\endgroup\$ Mar 30, 2021 at 18:33
  • \$\begingroup\$ @CommandMaster Not sure, I just golfed it and that seemed to fix it \$\endgroup\$ Mar 30, 2021 at 18:35
  • 1
    \$\begingroup\$ You can get to 62 bytes by shifting stuff around a bit and not using findIndex. \$\endgroup\$
    – user
    Mar 30, 2021 at 18:38
3
\$\begingroup\$

Scala, 46 bytes

s=>1.to(2)./:(_)((a,_)=>a.reverse dropWhile s)

Try it in Scastie!

s =>                            //The Set of falsy items
  1.to(2)                       //Make a range [1, 2] to trim twice
    ./:                         //Fold over it,
    (_)                         //starting with the list to trim
    ((a, _) =>                  //The list a and the number, which is ignored
     a.reverse                  //Reverse the list
      dropWhile                 //And drop while
      s)                        //Each item is present in s

Same length, but more boring

s=>_.dropWhile(s).reverse.dropWhile(s).reverse

Try it in Scastie!

Boring.

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

Python 3, 68 bytes

f=lambda a,b:a[-1]in b and f(a[:-1],b)or a[0]in b and f(a[1:],b)or a

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You can save 3 bytes by using python 2: Try it online! \$\endgroup\$
    – qwatry
    Mar 30, 2021 at 22:24
  • 2
    \$\begingroup\$ @qwatry That's a significantly different answer; you should post it as your own. \$\endgroup\$
    – Neil
    Mar 31, 2021 at 9:04
  • \$\begingroup\$ Ok. Yeah, I was wondering if I should. \$\endgroup\$
    – qwatry
    Mar 31, 2021 at 10:27
3
\$\begingroup\$

R, 57 55 bytes

function(x,y,`+`=cumprod)x[!+x%in%y&!rev(+rev(x)%in%y)]

Try it online!

Finds matching elements (x %in% y) as vector of TRUE/FALSE values, and calculates the cumulative product (cumprod, re-assigned to + here to save bytes) to convert everything after the first FALSE to zero. Then does the same from the other end (by reversing x and the cumprod). Finally, negates (!) to select only the non-terminal-matching elements of x.

\$\endgroup\$
1
  • \$\begingroup\$ I had some hopelessly complicated scheme with outer(x,y,'=='), didn't even think about %in%! \$\endgroup\$
    – Giuseppe
    Mar 31, 2021 at 14:19
3
\$\begingroup\$

Python 2, 64 bytes

a,f=input()
for i in-1,0:
 while a and a[i]in f:a.pop(i)
print a

The a and is necessary if the falsey list, f, contains all the elements of a and the completely stripped list will be empty. Without it, the program errors with IndexError: list index out of range.

Try it online!

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

Husk, 7 5 bytes

Edit: -2 bytes thanks to Leo

‼(↔↓€

Try it online!

How?

↔↓€ removes the falsy elements from one end of the list, and then flips it:

 ↓    # drop the longest prefix of arg2 with elements that satisfy:
  €   # are present in arg1
↔     # then reverse the result

So we just need to do this twice (to remove from both ends of the list, and to restore the list to its original orientation):
( groups ↔↓€ together (the parentheses are automatically closed at the end of the program), and the higher-order function runs a function provided as an argument twice.

\$\endgroup\$
1
  • \$\begingroup\$ Wanna do something twice? There's a builtin for that‼ Try it online! \$\endgroup\$
    – Leo
    Mar 31, 2021 at 5:15
3
\$\begingroup\$

J, 21 19 bytes

[#~1-(*/\.>.*/\)@e.

Try it online!

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

Jelly, 1 byte

t

Try it online!

A builtin that does exactly this. Works with multiple "falsey" values as well: Try it online!

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

JavaScript (ES6), 56 bytes

Expects (a)(b), where a is the array to trim, using the values in the set b.

a=>b=>(g=a=>a.reverse().filter(i=c=>i|=!b.has(c)))(g(a))

Try it online!

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

Wolfram Language (Mathematica), 33 bytes

#//.{e=#|##&@@#2,a___,e...}:>{a}&

Try it online!

-6 bytes and correction from @att

\$\endgroup\$
3
  • \$\begingroup\$ How do you take a list to trim on? It seems like it can only take a single falsey value, though maybe I'm missing something \$\endgroup\$ Mar 30, 2021 at 18:28
  • \$\begingroup\$ @CommandMaster fixed.. \$\endgroup\$
    – ZaMoC
    Mar 30, 2021 at 18:42
  • \$\begingroup\$ 33 bytes (Fold is also insufficient if the ends of the list aren't ordered the same way as in the falsy list) \$\endgroup\$
    – att
    Mar 30, 2021 at 22:36
1
\$\begingroup\$

Red, 70 bytes

func[b t][while[find t b/1][take b]while[find t last b][take/last b]b]

Try it online!

Using parse, 123 bytes

func[b t][r: copy[]foreach n t[append r reduce['quote n '|]]take/last r
parse b[remove some r to[any r end]remove some r]b]

Try it online!

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

Retina 0.8.2, 52 bytes

m`^|$
,
(^)?,(([^,]+,)(?=.*¶.*,\3))*(¶.*)?(?(1)|$)

Try it online! Explanation:

m`^|$
,

Wrap both lists in additional commas.

(^)?,

Record whether this match is at the very start, but at the very least start at a comma.

(([^,]+,)(?=.*¶.*,\3))*

Match any number of terms which exist in the second array.

(¶.*)?

Optionally match the second array.

(?(1)|$)

If the match did not begin at the start, then it must end at the end.


Delete the matching values.

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

Java (JDK), 86 bytes

l->b->{while(b.contains(l.peek()))l.pop();while(b.contains(l.getLast()))l.pollLast();}

Try it online!

Uses a LinkedList as input/output.

\$\endgroup\$
2
  • \$\begingroup\$ You could also make it accept the more general Deque interface. \$\endgroup\$ Apr 1, 2021 at 14:39
  • \$\begingroup\$ @iota Yes that was my first idea, but since the challenge speaks of list, I tried to stay in the spirit of it. \$\endgroup\$ Apr 2, 2021 at 9:49
1
\$\begingroup\$

Excel, 70 bytes

=LET(x,A1#,r,ROW(x),y,IF(x>-1,r,""),FILTER(x,(r>=MIN(y))*(r<=MAX(y))))
\$\endgroup\$
1
\$\begingroup\$

Desmos, 227 215 bytes

z(A)=length(A)
h(l,a,k)=\left\{l[a]=k:0,1\right\}
f(a,b)=\sum_{n=1}^{z(b)}(1-h(b,n,a))
s=f(A,B)
j(A,B)=A[\sum_{N=1}^{z(s)}N(1-h(s,N,0))\prod_{a=1}^{N-1}h(s,a,0)...z(A)]
p=j(A,B)
q=j(p[z(p)...1],B)
m(A,B)=q[z(q)...1]

Try It On Desmos!

Try It On Desmos!(Prettified Version)

Final function is \$m(a,b)\$, where \$a\$ is the list that is being trimmed, and \$b\$ is the list of "falsey" values that are trimmed from \$a\$.

Much harder than I initially anticipated because Desmos has limited list functionality. Hopefully it's fine if I output an one-element list with the one element being undefined([undefined]) when the output is supposed to be an empty list([]). If it isn't fine then tell me and I can fix(but it would cost more bytes ☹️)

Note: Not too sure why, but you can't directly paste the code into Desmos for some reason. You have to paste each expression one at a time in order for it to work.

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

Haskell + hgl, 14 bytes

jn m<rv.^dW<fe

Try it online!

(.^ has been renamed to << since this was posted)

Explanation

To start we want to do the much simpler:

f x y=rv$dW(fe x)$rv$dw(fe x)y

This drops all things in x off the front, reverses it, then drops all things in x off the new front and reverses it back.

From here we can start by removing the y.

f x=rv<dW(fe x)<rv<dw(fe x)

Now we have the expression rv<dW(fe x) twice so let's fix that. jn will take a function on two arguments and pass the same value as both of its arguments.

f x=(rv<dW(fe x))<(rv<dW(fe x))
f x=jn m(rv<dW(fe x))

Now x is at the end so we can eta-reduce it away as well:

f x=jn m<rv.^dW<fe

Reflection

Usually I would use Rv to reverse a list however .^ next to Rv breaks the Haskell parser, so I had to use rv instead. I've been aware of this danger for a while now and this was a pretty close call. I will probably rename .^ to <<.

"Compose a function with itself" achieved here with jn m is something that should probably have it's own name. It would have saved a byte here at least.

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

Uiua SBCS, 11 bytes

▽¬↥⇌∩\×⇌.∊,

Try it!

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

BQN, 16 bytes

(⌽(∨`·∧˝≠⌜)/⊢)⍟2

Takes the list as its right argument and the elements to trim as its left argument. Try it at BQN online!

Explanation

(⌽(∨`·∧˝≠⌜)/⊢)⍟2
         ≠⌜         Make an inequality table of the two lists: 0 when elements are
                    equal, 1 when they aren't
       ∧˝           Fold each column on logical AND: 1 for elements in the list
                    that aren't one of the elements to trim, 0 for those that are
    ∨`·             Scan with logical OR: keep leading run of 0s but turn everything
                    after the first 1 into 1s
   (       )/⊢      Remove elements of the original list that correspond to 0s in
                    that list; keep elements that correspond to 1s
 ⌽                  Reverse
(              )⍟2  Do that twice
\$\endgroup\$
0
\$\begingroup\$

Perl 5 -a, 59 bytes

$_=<>;for$i(0,-1){splice@F,$i,1while/(^| )$F[$i]\b/}say"@F"

Try it online!

\$\endgroup\$

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.