A pure word (or perfect word), as defined by me, is a word where the sum of the position in the alphabet of each letter in the word is perfectly divisible by the total length of the word. For example, abcb is a perfect word because 1 + 2 + 3 + 2 = 8, and 8 / 4 = 2.

Your task

Given a word as input, output whether or not it is a perfect word. The word may always be assumed to be lowercase.


This is code-golf, so shortest program in bytes wins.


abcb: truthy
ccc: truthy
aaa: truthy
pure: truthy
word: truthy
bed: falsy
code: falsy
bode: falsy
  • \$\begingroup\$ What type of outputs are allowed? For example, 0 for truthy and a non-consistent nonzero number for falsy? Any two values? Truthy and falsy swapped? @All: you may want to vote here \$\endgroup\$
    – Luis Mendo
    Jan 15, 2022 at 11:21
  • \$\begingroup\$ @LuisMendo check the related meta post \$\endgroup\$
    – Ginger
    Jan 15, 2022 at 17:18
  • 3
    \$\begingroup\$ I know what "truthy" and "falsy" mean. I'm asking if the outputs can be non-consistent values (i.e. more than two values), or for example two distinct truthy values. You need to specify the output options allowed by the challenge. Voting to close as unclear until resolved \$\endgroup\$
    – Luis Mendo
    Jan 15, 2022 at 17:33
  • \$\begingroup\$ I'm pretty sure our consensus is that there is no default for decision problem output. E.g., is false for a perfect number and true for a non-perfect one allowed? What about 1 for a perfect number and any other number otherwise, or positive for perfect and negative for non-perfect? \$\endgroup\$ Jan 15, 2022 at 18:00
  • 7
    \$\begingroup\$ @taRadvylfsriksushilani The consensus appears not to be. However I would really like it if something as basic as output specifications were put in the challenge itself instead of hidden away somewhere on meta. It's not very beginner friendly seeing as experienced users don't seem to always recall the exact state of the meta. \$\endgroup\$
    – Wheat Wizard
    Jan 15, 2022 at 20:23

48 Answers 48


Zsh, 31 bytes


Try it online!

In Zsh, ##x in arithmetic mode returns the codepoint of 'x'.

        ${(s::) 1}    # split $1 into characters
   +\#\#${(s::)^1}    # append `+##` to each element
a=(+\#\#${(s::)^1})   # save as $a
(((a)%$#1))           # join $a on spaces, evaluate (+##a +##b ...) % $#1
                      # arithmetically

Python, 125 bytes

Wow I feel like an idiot after reading all these other amazing answers.

j=[ord(k)-96 for k in str(input(""))]
while len(j)>1:j[0]+=j[1];del j[1]
print("%sy"%("truth"if j[0]%l<1else"fals"))

I think how this works is pretty trivial.


Pyth, 7 bytes


Test suite

!%sCMQl  | Full code
!%sCMQlQ | with implicit variables filled
   CMQ   | Replace each character in the input with its codepoint
  s      | Sum the resulting list
 %    lQ | Mod the sum with the length of the input
!        | Boolean negate (i.e. 0 -> True, other -> False)

MathGolf, 5 bytes


Input as a list of characters. Could be 1 byte less by taking the input as a list of codepoints.

Try it online.


$     # Map each character in the (implicit) input-list to a codepoint integer
 Σ    # Sum this list
  \   # Swap so the (implicit) input-list is at the top again
   £  # Pop and push its length
    ÷ # Check if the earlier sum is divisible by this length
      # (after which the entire stack is output implicitly as result)

Whitespace, 113 bytes

[S S S N
_Push_0][S N
S _Duplicate_0][S N
S _Duplicate_0][N
_Create_Label_LOOP][S N
S _Duplicate][S N
S _Duplicate][T N
T   S _Read_STDIN_as_char][T    T   T   _Retrieve_input][S N
S _Duplicate][S S S T   S T S N
_Push_10][T S S T   _Subtract][N
T   S S N
_If_0_jump_to_Label_PRINT_RESULT][T S S S _Add][S N
T   _Swap_top_two][S S S T  N
_Push_1][T  S S S _Add][S N
T   _Swap_top_two][N
_Create_Label_PRINT_RESULT][S N
_Discard_top][S N
T   _Swap_top_two][T    S T T   _Modulo][N
T   S T N
_If_0_Jump_to_Label_TRUTHY][S S T   T   N
S S T   N
_Create_Label_TRUTHY][S S S T   N
_Push_1][T  S S S _Add][T   N
S T _Print_as_integer]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Since Whitespace can only read input one character at a time, the input must contain a trailing newline so we'll know when we're done reading characters.
Whitespace also lacks truthy/falsey values, so this program will output 1 for truthy and 0 for falsey (could be 28 bytes less with 0 as truthy and a positive integer as falsey).

Try it online (with raw spaces, tabs and new-lines only).

Explanation in pseudo-code:

Integer length = 0
Integer sum = 0
Start LOOP:
  Integer input = STDIN as character
  If(input == '\n'):
    Jump to PRINT_RESULT
  sum = sum + input
  length = length + 1
  Go to next iteration of LOOP

  Integer result = 0
  Integer mod = sum modulo length
  If(mod == 0):
    Skip to TRUTHY
    result = -1
  result = result + 1
  Print result as integer to STDOUT

C (clang), 49 bytes


Try it online!

Takes input as a wide string; returns 1 for pure words and 0 for others.


Fig, \$4\log_{256}(96)\approx\$ 3.292 bytes


Try it online!

Port of K answer. Prints 0 for truthy and a positive number for falsey.

   S # Sum of charcodes
%    # Modulo
 Lx  # Length of input

K (ngn/k), 11 10 bytes


Try it online!

Saves a byte by not using the Not operator (~)

Quick and simple. Return 0 for true and any other value for false.


{(#x)!+/x}    Main function. Takes x as input
      +/x     Sum of all charcodes in x
     !        Modulo
 (#x)         Length of x

Python 3, 55 bytes

lambda s:(sum(ord(c)-95for c in s)/len(s)).is_integer()

Try it online!

  • 2
    \$\begingroup\$ By the looks of it the code divides by 2. Shouldn't it divide by len(s), or am I overlooking something? \$\endgroup\$ Jan 14, 2022 at 23:19
  • \$\begingroup\$ @dingledooper woops, will fix \$\endgroup\$
    – Alan Bagel
    Jan 14, 2022 at 23:21
  • \$\begingroup\$ You can get 53 bytes with the walrus operator lambda s:int(b:=(sum(ord(c)-95for c in s)/len(s)))==b (though tio.run doesn't recognize it) \$\endgroup\$ Jan 20, 2022 at 3:30

Kotlin, 85 bytes

fun i(s:String):Int{var a=0;for(i in s)a+=i.code-96;return if(a%s.length==0)1 else 0}

Try it online!

Ungolfed version:

fun isPure(s: String) : Int
    var acc = 0
    for(i in s) acc+= i.code-96
    return if(acc%s.length==0) 1 else 0

1 stands for Truthy and 0 stands for falsy, derived from this post Interpretation of Truthy/Falsey


C#, 101 83 bytes

bool P(string w){int i=0;foreach(var c in w){i+=(int)c%32;};return i%w.Length==0;};

Try it online

  • 1
    \$\begingroup\$ Welcome to Code Golf, and nice first answer! Be sure to check out our Tips for golfing in C# page for ways you can golf your program. We allow anonymous functions here, so you should be able to remove the static Func<string,bool> P =, as well as the spaces around the = and => \$\endgroup\$ Jan 28, 2022 at 12:33
  • \$\begingroup\$ @caird thanks for the welcome and the tips, that helped knock a significant chunk off \$\endgroup\$
    – B-Slam
    Jan 28, 2022 at 14:46
  • 1
    \$\begingroup\$ Suggest return i%w.Length<1 instead of return i%w.Length==0 and removing the innermost curly braces. \$\endgroup\$
    – ceilingcat
    Feb 1, 2022 at 10:29

Vyxal, 7 bytes


Try it Online!

  • \$\begingroup\$ Nice! You don't need the space. \$\endgroup\$
    – emanresu A
    Mar 7, 2022 at 3:12
  • \$\begingroup\$ Try it Online! for 7 bytes. \$\endgroup\$
    – lyxal
    Mar 7, 2022 at 3:31

Nim, 52 bytes

import sequtils,sugar

Try it online!


Swift, 42 bytes


Try it online!

This uses the same algorithm as the current top answers for Python, Excel, Java, and Scala, and probably others. As for why I use .utf8, see my explanation here. As with that answer, the input type here can be String or Substring, and the output type is Bool.

It still surprises me that Swift has .reduce(0, +) rather than .sum() for collections of numbers.


APOL, 32 bytes

v(0 i);!(%(⊕(ƒ(⁰ ⌕(ⓛ ∋))) l(⁰)))


v(            Set memory cell
  i           to input
!(            Not
  %(          Modulo
    ⊕(       Sum
      ƒ(      List-builder for
        ⁰     Memory cell 0
        ⌕(    Find
          ⓛ  All ASCII lowercase characters
          ∋   Loop item
    l(        Length of
      ⁰       Memory cell 0

Thunno, \$ 7\log_{256}(96)\approx \$ 5.76 bytes


Attempt This Online!


OSz0L%!  # Implicit input
 S       # the sum of
O        # the ords of the input
     %!  # is divisible by
    L    # the length of
  z0     # the input?
         # Implicit output

PHP, 67 bytes


Try it online!


fn($w) => !(array_sum(
    array_map('ord', str_split($w))
  ) % 96 % strlen($w));

D, 67 bytes

import std;int p(string w){return !(w.fold!"a+=b-96"(0)%w.length);}


import std;
int p(string w) {
    return !(w.fold!"a+=b-96"(0)%w.length);
// not much more readable, lol

takes a string w, and then performs a fold on it. The fold adds each char, minus 96, to the accumulator. 96 being the ascii value of the backtick character, one behind a (since this challenge specifies that the characters are 1-indexed). this effectively adds up all characters in the string. Then we perform a modulo for a divisibility check, and since we want 0 to be the true case, we invert it. Note how we return int from this function so that it takes up one less byte. ints can be implicitly cast to bool so it's fine.

Try it online!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.