| Bytes | Lang | Time | Link |
|---|---|---|---|
| 003 | Uiua | 231019T175019Z | chunes |
| 079 | Racket | 230722T173414Z | Ed The & |
| 002 | Thunno 2 | 230722T164810Z | The Thon |
| 045 | C clang m32 | 220807T182230Z | c-- |
| 038 | Arturo | 230115T033620Z | chunes |
| 026 | POSIX Shell + Utilities | 221226T014953Z | набиячлэ |
| 002 | Japt | 221224T154358Z | noodle m |
| 006 | sh + coreutils | 220807T180222Z | matteo_c |
| 024 | awk 24bytes solution — it's not all that short but it gets the job done* | 221225T091706Z | RARE Kpo |
| nan | 221224T173614Z | bigyihsu | |
| 055 | Dart 2.18.4 | 220808T110238Z | Alex Rin |
| 034 | brev | 220821T203721Z | Sandra |
| 008 | Scala | 220814T090729Z | corvus_1 |
| 029 | Ruby | 220813T144025Z | Pascal H |
| 028 | Python | 220807T165818Z | 97.100.9 |
| 022 | Raku | 220812T172101Z | Sean |
| 015 | GolfScript | 220812T135800Z | Samuel W |
| 048 | Red | 220812T103752Z | chunes |
| 020 | Regex ECMAScript or better | 220807T185548Z | Deadcode |
| 005 | Pip | 220809T153112Z | DLosc |
| 005 | Charcoal | 220808T113157Z | Neil |
| 003 | BQN | 220808T215456Z | Dominic |
| 024 | Nibbles | 220809T090814Z | Dominic |
| 005 | Haskell + hgl | 220809T081953Z | Wheat Wi |
| 010 | CJam | 220808T225102Z | Luis Men |
| 004 | K ngn/k | 220808T223332Z | Traws |
| 044 | JavaScript Node.js | 220808T122235Z | noodle m |
| 021 | Haskell | 220807T210313Z | c-- |
| 033 | C# | 220808T143558Z | Acer |
| 025 | MATLAB | 220808T123250Z | robbie c |
| 002 | Burlesque | 220808T103021Z | DeathInc |
| 001 | 05AB1E | 220808T085032Z | Kevin Cr |
| 041 | JavaScript Node.js | 220808T012902Z | Matthew |
| 020 | Rust | 220808T003913Z | Bubbler |
| 027 | PARI/GP | 220808T000240Z | alephalp |
| 016 | Wolfram Language Mathematica | 220807T224504Z | att |
| 006 | Factor | 220807T223251Z | chunes |
| 004 | Brachylog | 220807T222702Z | Unrelate |
| 063 | Knight | 220807T214811Z | naffetS |
| 016 | Haskell | 220807T212945Z | naffetS |
| 003 | Vyxal r | 220807T194740Z | naffetS |
| 015 | R | 220807T192336Z | pajonk |
| 070 | Rust | 220807T182646Z | mousetai |
| 020 | Haskell | 220807T180000Z | matteo_c |
| 054 | J | 220807T172608Z | Jonah |
| 001 | Jelly | 220807T174843Z | Jonathan |
| 001 | Dyalog APL | 220807T174246Z | rabbitgr |
Racket, 79 bytes
(define(p s a)(apply string(for/list([c s]#:when(string-contains? a(~a c)))c)))
Explanation
We create a function called p that receives two inputs s and a which are the string to match and the string of what to match respectively. We loop through the characters of s and see whether each character appears in a. When a character does appear, we accumulate that character into a list. Once the list is obtained, we convert the characters to a single string.
(define (projection s a)
(apply string
(for/list ([char s] #:when (string-contains? a (~a char)))
char)))
Conclusion
Have an amazing weekend!
Thunno 2, 2 bytes
Ƈị
I/O as a list of characters.
Explanation
# Implicit input
ị # Keep only the characters of the first input
Ƈ # which are contained in the second input
# Implicit output
C (clang) -m32, 54 53 45 bytes
-1 byte thanks to @ceilingcat
-8 bytes thanks to @jdt
f(*s,a){for(;*s;)write(1,s,!!index(a,*s++));}
Explanation
f(*s,a){ // function f() takes a wide-character string (s) and an int (a)
for(;*s;) // while we're not at the end of the string
write(1,s,N // write N bytes from s to stdout
!!<expr> // if <expr> is NULL, return 0, otherwise 1
index(a,c // if the character `c` is found in `(const char *) a`,
// return a pointer to it's occurrence, otherwise `NULL`
*s++ // return the current character and increment s
) // end call to index(3)
); // end call to write(2)
} // end function f()
Caveat
There is undefined behavior in the form of an unsequenced modification and access to s, but clang happened to evaluate s (the second parameter to write) before incrementing it in the call to index(3) so in this case it works.
POSIX Shell + Utilities, 26 bytes
printf %s "$1"|tr -cd "$2"
Fundamentally, the operation is tr -cd alphabet, all of 11 bytes on the right side of the pipe; more than half of the space is spent on turning the specified calling convention into data in a file. Unclear if taking the input from the standard input stream is allowed.
The tr alphabet accepts \n and \t for line and tab, but the spec does comment that it means a literal one, I think? Either work, but.
Transcript of test cases:
$ cat c.sh; echo; wc -c c.sh
printf %s "$1"|tr -cd "$2"
26 c.sh
$ ./c.sh "abcd" "12da34"; echo
ad
$ ./c.sh "hello, world!" "aeiou"; echo
eoo
$ ./c.sh "hello, world!" "abcdefghijklmnopqrstuvwxyz"; echo
helloworld
$ ./c.sh "Hello, World!" "abcdefghijklmnopqrstuvwxyz"; echo
elloorld
$ ./c.sh "Hello, World!" "abcdef"; echo
ed
$ ./c.sh "Hello, World!" "!,.
"; echo
, !
$ ./c.sh "172843905" "abc123"; echo
123
$ ./c.sh "fizzbuzz" ""; echo
$ ./c.sh "fizzbuzz" "fizzbuzz"; echo
fizzbuzz
$ ./c.sh "" "fizzbuzz"; echo
$ ./c.sh "fizzbuzz" "zzzzz"; echo
zzzz
$ ./c.sh "" ""
```
Japt, 3 2 bytes
fV
Takes input strings as character arrays
3 bytes w/ strings for input:
oV1
oV1
o : only keep characters in first input and
V : second input
1 : case sensitive
sh + coreutils, 6 bytes
tr -cd
Takes string s from stdin, alphabet a as an argument.
awk 24-bytes solution — it's not all that short but it gets the job done*
— *some bugs still exist
echo 'abcd 12da34' |
awk 'gsub("[^"$NF"]",_,$--NF)'
ad
echo 'hello, world!=naeiou' |
awk 'gsub("[^"$NF"]",_,$--NF)' FS== | awk NF=NF FS= OFS='\n' | awk '!__[$_]++' ORS=
- or
awk 'gsub("[^"$!_ "]",_,$NF) gsub("[^"$NF"]",_,$!_)($_=$NF)' FS==
eo
Go, 104 bytes
import."strings"
func f(s,a string)(o string){for i:=range s{r:=s[i:i+1]
if Contains(a,r){o+=r}}
return}
Dart (2.18.4), 55 bytes
f(s,a)=>s.split('').where((e)=>!!a.contains(e)).join();
brev, 34 bytes
(as-list(c lset-intersection eq?))
Brev imports all of srfi-1 by default. The partial application combinator c applies eq? and then the as-list combinator makes the list operator work on (and return) strings (and other stuff) as if they were lists.
Scala, 8 bytes
_.filter
This is an expression of type String => Set[Char] => String. It uses the fact that a Set[T] is a function T => Boolean, which is used the predicate here.
Ruby, 29 bytes
->s,a{s.gsub(/./){a[_1]&&_1}}
Previous version which had flaws indicated by Deadcode:
->s,a{s.tr(s.tr(a,""),"")}
Python, 35 28 bytes
lambda a,b:filter(b.count,a)
Takes in either strings or lists of characters, outputs a list of characters.
-7 bytes from @dingledooper by using filter + count instead of list comprehension and in
Raku, 22 bytes
{$^a.trans($^b=>""):c}
trans is Raku's beefed-up version of Perl 5's transliteration operator tr.
Regex (ECMAScript or better), 20 bytes
s/(.)(?!.*␀.*\1)//sg
Try it online! - ECMAScript 2018
Try it online! - Perl
Try it online! - PCRE2
Try it online! - Boost
Try it online! - Python
Try it online! - Ruby
Try it online! - .NET
This is a single regex substitution, to be applied once. Input is taken in the form of the two strings delimited by NUL (ASCII 0).
Above and below, ␀ represents what is actually a raw NUL character in the regex.
s/ # Begin substitution - match the following:
(.) # \1 = one character
(?! # Negative lookahead - match if the following can't match:
.* # Skip over as many characters as possible, minimum zero, to make
# the following match:
␀ # Skip over the NUL delimiter
.* # Skip over as many characters as possible, minimum zero, to make
# the following match:
\1 # Match the character we captured in \1
)
/ # Substitution - replace with the following:
# Empty string
/ # Flags:
s # single line - "." will match anything, including newline
g # global - find and replace all matches, going from left to right
This automatically erases the NUL and everything following it, because NUL and all characters following it are themselves not followed by NUL, so the negative lookahead matches for each of them.
(More test harnesses to come.)
As far as ECMAScript goes, this requires ECMAScript 2018 (aka ES9) due to the use of the s flag.
In Ruby, the m flag is used, which is the Ruby equivalent of what is s in most other regex engines.
\$\large\textit{Anonymous functions}\$
Perl, 42 bytes
sub{$_=join'␀',@_;s/(.)(?!.*␀.*\1)//sg;$_}
Takes the two strings as arguments.
Beaten by a 35 byte solution based on an unposted solution by Sisyphus: Try it online!
Ruby, 42 41 bytes
-1 byte thanks to Steffan
->s,a{(s+?␀+a).gsub /(.)(?!.*␀.*\1)/m,''}
PowerShell, 42 bytes
$args-join'␀'-creplace'(?s)(.)(?!.*␀.*\1)'
Takes the two strings as arguments.
JavaScript (ES9), 43 bytes
a=>a.join`␀`.replace(/(.)(?!.*␀.*\1)/sg,'')
Takes a list containing the two strings.
Java, 52 bytes
s->a->(s+"␀"+a).replaceAll("(?s)(.)(?!.*␀.*\\1)","")
\$\large\textit{Full programs}\$
Perl, 37 bytes
$_=join'',<>;s/(.)(?!.*␀.*\1)//sg;say
Takes multiline input (terminated by EOF) using NUL as a delimiter between the two strings.
Beaten by a 19 byte solution based on an unposted solution by Sisyphus: Try it online! (they should really post it), or 25 bytes to insert chomp; at the beginning if being picky about the output being followed by a NUL.
Pip, 5 bytes
a@X^b
Explanation
b Second command-line argument
^ Split into characters
X Convert to regex that matches any of those characters
@ Find all matches of the regex in
a First command-line argument
By default, the list of matches is concatenated together and output.
Charcoal, 5 bytes
Φθ№ηι
Try it online! Link is to verbose version of code. Explanation: Trivial port of @dingledooper's golf to adam's Python answer.
θ First input
Φ Filtered where
№ Count of
ι Current character
η In second input
Implicitly print
Newlines and other unprintables need to be entered using JSON format.
BQN, 3 bytes
∊/⊣
/ # Replicate elements of
⊣ # left argument
# by
∊ # 1 if each element of left argument is in right argument
# 0 otherwise
Nibbles, 2 bytes (4 nibbles)
|@?@
| # filter
@ # the (second) input array
# for truthy results of the function:
? # index (or 0 if not found)
@ # in the (first) input array
Haskell + hgl, 5 bytes
fl<fe
Pretty straight forward. fl filters fe checks if something is an element. Ends up being the same as the vanilla Haskell answer.
Reflection
This is a very simple task so there's not a lot to be said but:
- I'm not sure why
ewas given the shorter name thanfe.feis almost certainly the more useful of the two and probably they should be swapped. - Since this is such a simple task, hgl should probably follow the lead of the golfing langs and make this a builtin.
- There are a bunch of builtins that are similar to this task like
nx, but the descriptions were not the clearest.
CJam, 10 bytes
Loosely inspired by this answer to another challenge.
l~:A;{A&}/
Input is a line containing the two strings separated by a space. If a string contains special characters it needs to be defined explicitly as an array of chars.
Try it online! Or verify all test cases.
How it works
l~ e# Read line and evaluate: pushes the two strings onto the stack
:A; e# Copy the second string into variable A, then pop
{ }/ e# For each character in the first string, do the following
e# Implicitly push current character of the first string
A e# Push the second string
& e# Set intersection. This gives the current char or an empty string
e# Implicitly display stack contents
JavaScript (Node.js), 44 bytes
s=>a=>[...s].filter(c=>a.includes(c)).join``
Unfortunately, using .filter(a.includes) for 38 (wow!) throws String.prototype.includes called on null or undefined
MATLAB, 25 bytes
f=@(a,b)a(ismember(a,b))
Technically, only the call of a(ismember(a,b)) is required to fulfill the task, but to make it a callable function a function handle is created. Also, the inputs have to be of type char, not string, as a char is an array whereas a string is more like a complete unit in MATLAB.
JavaScript (Node.js), 41 bytes
Presently invalid as does not handle alphabets containing - or ]. (as pointed out by Deadcode)
s=>a=>s.replace(RegExp(`[^${a}]`,'g'),'')
Rust, 20 bytes
str::matches::<&[_]>
This mixes up three I/O methods for strings: the first parameter is a plain string slice &str, the second is a slice of chars &[char], and the output is an iterator yielding single-char string slices impl Iterator<Item=&str>.
Doc for str::matches. It can take several kinds of patterns (i.e. anything that implements Pattern) for non-overlapping substring search:
- single
char: matches that char - a
&stror equivalent: matches that exact string - a slice of chars
&[char]or equivalent: matches any char out of the ones listed - (and any 3rd party type that implements
Pattern, e.g.Regex)
We use the third variety in this challenge, which is indicated by the ::<&[_]> part. _ is a kind of wildcard type, and it resolves to char by the compiler because &[char] is the only type matching &[_] that implements Pattern.
Wolfram Language (Mathematica), 16 bytes
Cases[#|##&@@#]&
Input and output two lists of characters [alphabet][string].
Brachylog, 4 bytes
dᵗ∋ᵛ
Takes a list [s, a], and generates a list constituting the projection.
dᵗ Deduplicate a,
∋ᵛ then yield some c from a pair of elements [c, c] from s and a.
Deduplicating a is necessary in order to not generate multiple pairs from the same element of s.
R, 15 bytes
\(s,a)s[s%in%a]
Takes input and outputs through vectors of character codes (as in linked test suite) or vectors of characters.
Rust, 70 bytes
|a:&str,b:&[u8]|a.bytes().filter(|d|b.contains(d)).collect::<Vec<_>>()
Haskell, 20 bytes
a#b=filter(`elem`b)a
J, 5 4 bytes
e.#[
-1 byte thanks to seeing the word "filter" in Jonathan's Jelly answer
Filter by # element of e..
Jelly, 1 byte
f
This is exactly what Jelly's "filter-keep" dyadic atom does - takes a list on the left and a list on the right and keeps those in the left that appear in the right.
