A better measure of “effort to write code” is the number of lexer tokens. So, identifiers count as one (regardless of length), operators count as one, each paren counts as one, and spaces count as zero. Code that has had more “blunt force” applied to it to get it working will end up with more lexer-token length. Code that has had most of its repetition factored away will have few (although, in turn, its cyclomatic complexity will go up, meaning that it might now be harder to
read, however much easier it is to maintain once grokked.)
You could also measure the compressed size of the code, since compression eliminates redundancies like long identifiers being repeated. But they’ll also sort of “cyclomatically optimize” your code as well—effectively re-rolling any hand-written unrolled loops, and shortening repetitions of a(b(x)) into the same result as a_b(x). You might say compression shows the optimal lexical size of the code. :)