# 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.