# Special Character Coding Challenge - Check string for validity (Lots of rules)

## Raku, 41 bytes

```
{?/^[\s*\!?\s*\d+\.?\d*\s*]+%<[%&#$!]>$/}
```

Try it online!

Checks if the input matches against a regex.

### Explanation:

```
{?/^ $/} # Check if the input is
[ ]+ # A series of
\!? # An optional ! followed by
\d+\.?\d* # A number
\s* \s* \s* # Interspersed with optional whitespace
% # Joined by
<[ ]> # Any of
%&#! # The special characters
```

## 05AB1E, ~~46~~ ~~45~~ ~~ 44 ~~ 43 bytes

^{Crossed out 44 is no longer 44 :)}

```
þ'.ªžQ7£`)5L.Þ:DÔƵKå≠s2K¤s¬4%s•8мZ_r•₄вå≠`P
```

-2 bytes thanks to *@ExpiredData*.

Outputs `1`

for truthy and `0`

or a positive integer for falsey (NOTE: only `1`

is truthy in 05AB1E, so this is completely fine with the truthy/falsey definition of the meta).

Try it online or verify all test cases.

**Explanation:**

Unfortunately 05AB1E doesn't have any regexes. So instead I'll:

Convert the input to something that's easier to work with:

```
þ # Only leave the digits of the (implicit) input-string
'.ª '# Convert the number to a list of digits, and append a "." to this list
žQ # Push a constant with all printable ASCII characters (range [32,126])
7£ # Only leave the first 7: ' !"#$%&'
` # Push them all separated to the stack
) # Wrap everything on the stack into a list
5L # Push a list [1,2,3,4,5]
.Þ # Extend the trailing item infinitely: [1,2,3,4,5,5,5,...]
: # Replace all characters in the (implicit) input-string with these
# We now have a number consisting only of the digits [1,2,3,5],
# where 1 is a digit or "."; 2 are spaces; 3 is "!"; and 4 is one of "%&#$"
# i.e. "5.4 $ 2.9 !3.4 &! 89.8213" → 1112521112311125321111111
```

After which it's easier to check whether it complies to all the rules:

Rule 5: check that there are no two numbers with spaces in between:

```
D # Duplicate the number
Ô # Connected uniquify them (i.e. 1112521112311125321111111 → 1252123125321)
ƵK # Push compressed integer 121
å≠ # And check that the number does NOT contains 121 as substring
```

Remove all spaces. And then rules 3 and 4: check that the input ends with a digit, and starts with a `"!"`

or digit:

```
s # Swap to get the number at the top again
2K # Remove all 2s (the spaces)
¤ # Push the last digit (without popping the number itself)
s # Swap again
¬ # And push the first digit (without popping the number itself)
4% # And take modulo 4, so 1 remains 1, and 5 becomes 1
```

Rules 1 and 2: check that it does not contain `"!S"`

/`"!!"`

/`"!!!"`

/`S!!`

(where `S`

is one of the special characters `"%&#$"`

):

```
s # Swap to get the number at the top again
•8мZ_r• # Push compressed integer 35055333533
₄в # Convert it to base-1000 as list: [35,55,333,533]
å≠ # Check for each that the number does NOT contain it as substring
` # And push all four checks separated to the stack
```

And finally check if all were truthy:

```
P # Then take the product of all values on the stack
# (after which this is output implicitly as result)
```

See this 05AB1E tip of mine (sections *How to compress large integers?* and *How to compress integer lists?*) to understand why `ƵK`

is `121`

; `•8мZ_r•`

is `35055333533`

; and `•8мZ_r•₄в`

is `[35,55,333,533]`

.

## Perl 5 `-p`

, 72 bytes

```
$_=!/^[%#&\$]|^!!|([%#&!\$]\s*){3}|[%#!&\$]\s*[%#&\$]|\d\s+\d|\D$/&&/\d/
```

Try it online!