Swap program halves to test divisors
JavaScript (ES6), 46 + 55 + 6 + 36 = 282 274 ... 158 143 bytes

A:

n=&gt;(r=0,D=x=&gt;x&amp;&amp;D(x-1,n%x||(r++?q-=x:q=n)))(n)


B:

n=&gt;(q=(g=D=x=&gt;x&amp;&amp;!(n%x||(g|=m&gt;2*(m=x),0))+D(x-1))(m=n))


C:

?!g:!q


D:

?(P=k=&gt;--k?D(n=k)&lt;q&amp;P(k):1)(n):n%r&lt;1


The result is 4 anonymous functions which give truthy/falsy values for their respective inputs (AC, AD, and BC give true/false, BD gives 1/0).

Test snippet



let AC =
n=&gt;(r=0,D=x=&gt;x&amp;&amp;D(x-1,n%x||(r++?q-=x:q=n)))(n)
?!g:!q

let AD =
n=&gt;(r=0,D=x=&gt;x&amp;&amp;D(x-1,n%x||(r++?q-=x:q=n)))(n)
?(P=k=&gt;--k?D(n=k)&lt;q&amp;P(k):1)(n):n%r&lt;1

let BC =
n=&gt;(q=(g=D=x=&gt;x&amp;&amp;!(n%x||(g|=m&gt;2*(m=x),0))+D(x-1))(m=n))
?!g:!q

let BD =
n=&gt;(q=(g=D=x=&gt;x&amp;&amp;!(n%x||(g|=m&gt;2*(m=x),0))+D(x-1))(m=n))
?(P=k=&gt;--k?D(n=k)&lt;q&amp;P(k):1)(n):n%r&lt;1

let update = n =&gt; O.innerText = [
  'perfect: ' + AC(n),
  'refactorable: ' + AD(n),
  'practical: ' + BC(n),
  'highly composite: ' + BD(n)
].join("\n")
&lt;input type=number value=1 min=1 oninput=update(this.value)&gt;
&lt;pre id=O&gt;&lt;/pre&gt;