Highest or Lowest Occurrences?
Jelly, 31 bytes
ØṖḟØBṭØBUs26¤f€³Lİ⁴¡$ÐṀFf
¹⁶Ç?€
Try it online!
The boolean values are 2
and 1
(or any other positive even/odd pair), which represent True
and False
respectively. I will try to add an explanation after further golfing.
Thanks to caird coinheringaahing for saving 2 bytes, and to Lynn for saving 4 bytes! Thanks to one of Erik's tricks, which inspired me to save 4 bytes!
How it works
Note that this is the explanation for the 35-byte version. The new one does roughly the same (but tweaked a bit by Lynn), so I won't change it.
ØBUs26f€³µ³ḟØBW,µẎLİ⁴¡$ÐṀF - Niladic helper link.
ØB - String of base digits: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz'.
U - Reverse.
s26 - Chop into sublists of length 26, preserving shorter
trailing substrings.
f€³ - For each, keep the common characters with the input.
ØB - Base digits.
³ḟ - Get the signs in the input. Filter the characters of the
input that aren't alphanumeric.
W,µẎ - Concatenate (wrap, two element list, tighten).
ÐṀ - Keep the elements with maximal link value.
L - Length.
⁴¡ - Do N times, where N is the second input.
İ - Inverse. Computes 1 ÷ Length. 2 maps to the length itself,
because 1 ÷ (1 ÷ Length) = length; 1 yields
(1 ÷ Length), swapping the maximal numbers with minimal ones.
F - Flatten.
¹⁶e¢$?€ - Main link.
€ - For each character.
e¢? - If it is contained by the last link (called niladically), then:
¹ - Identity, the character itself, else:
⁶ - A space.
Python 2, 166 158 bytes
t=lambda c:('@'<c<'[','`'<c<'{','/'<c<':',1-c.isalnum())
def f(s,b):x=map(sum,zip(*map(t,s)));print''.join([' ',c][x[t(c).index(1)]==sorted(x)[-b]]for c in s)
Try it online!
R, 193 186 179 158 bytes
-7 bytes thanks to NofP and his suggestion of cbind
-6 bytes using outer
, -1 byte switching [^a-zA-Z0-9]
with [[:punct:]]
-21 bytes thanks to MickyT for pointing out a list of characters is allowed
function(S,B){y=outer(c("[a-z]","[A-Z]","\\d","[[:punct:]]"),S,Vectorize(grepl))
S[!colSums(y[(s=rowSums(y))=="if"(B,max,min)(s),,drop=F])]=" "
cat(S,sep='')}
Verify all test cases
Takes 1/T
as truthy (max
) and 0/F
as falsey (min
), and takes S
as a list of single characters.
Try it online!
In my original version (with NofP's suggestions), the matrix y
is constructed by evaluating grepl(regex, S)
for each regex
, then concatenating them together as columns of a matrix. This results in multiple calls to grepl
, but as S
is fixed, it seemed that something else needed to be done. As I noted:
There are potentially shorter approaches;
mapply
, for example:
y=mapply(grepl,c("[a-z]","[A-Z]","\\d","[^a-zA-Z0-9]"),list(S))
unfortunately, this will not simplify as a matrix in the 1-character example of
"A"
.
I used outer
rather than mapply
, which always returns an array (a matrix in this case), and was forced to Vectorize
grepl
, which is really just an mapply
wrapper around it.
I also discovered the predefined character group [:punct:]
which matches punctuation (non-space, non-alphanumeric) characters.