JSFiddle - React, Tailwind, and code Playground

HTML

<textarea id='input'>This is some sample text! ###</textarea>
<pre id='report'></pre>

JavaScript

var r = document.getElementById('report'),
    t = document.getElementById('input');

(t.onkeyup = function(e) {
    r.innerHTML = getReport(t.value);
})();

function repeatedCharsByRegexp(s, r) {
    var charsFound = {}, repeatedChars = '';
    for (var i = 0; i < s.length; i++) {
        if (r.test(s.charAt(i))) {
            if (charsFound[s.charAt(i)]) repeatedChars += s.charAt(i);
            else charsFound[s.charAt(i)] = true;
        }
    }
    return repeatedChars;
}
function repeatedAlnum(s) { return repeatedCharsByRegexp(s, /[A-Za-z0-9]/          ); }
function repeatedPunct(s) { return repeatedCharsByRegexp(s, /[\(\[!?.\-,":';\]\)]/ ); }
function repeatedOther(s) { return repeatedCharsByRegexp(s, /[{`~@#$%^&*_+=|\/><}]/); }
function repeatedSpace(s) { return repeatedCharsByRegexp(s, /\s/                   ); }

function item(txt) { return '- ' + txt + '\n'; }
function getReport(s) {
    var score = s.length,
        alnum = repeatedAlnum(s),
        punct = repeatedPunct(s),
        other = repeatedOther(s),
        space = repeatedSpace(s);
    return (
        item(score + ' characters long') +
        item('repeated alnum:       -' + (score -= alnum.length*3, alnum.length*3) + ' (' + alnum + ')') +
        item('repeated punctuation: -' + (score -= punct.length*2, punct.length*2) + ' (' + punct + ')') +
        item('repeated other:       -' + (score -= other.length*4, other.length*4) + ' (' + other + ')') +
        item('repeated whitespace:  -' + (score -= space.length*1, space.length*1) + ' (' + space + ')') +
        '\nTotal score: ' + score
    );
}