9
\$\begingroup\$

A port of my other question: Double Prime Words

Consider a word/string of n alphanumeric characters with sum of the characters, s, using their numeric position in the alphabet (a=1, B=2, c=3, etc.) or numeric value (0,1, 2, 3 - 9). Numeric characters should be taken at individual value. (66 is two 6 characters for a sum of 12)

A word is a Length-Sum Multiple if and only if s is a multiple of n, specifically s/n is a positive integer {1,2,3,4...}. In the case of s=0, and n={0,00,000,...}, 0 is a multiple of any n but it does not yield a positive integer. Hence an input of {0,00,000,...} is False.

Input can be any combination of numbers and upper or lower case alphabetic characters, as there is no numeric difference between a or A. Handling empty input, n=s=0, is not required.

Output is any appropriate logical format related to your language. i.e. True or False, T or F, 1 or 0, positive for truthy and 0 for falsy, etc. Specifying what format your output will appear is highly appreciated, but not required. (Output need not include n or s, but I include them below as demonstration and example)

Winning condition: In as few bytes as possible, write a function that is able to determine if a string is a Length-Sum Multiple.

Examples

Input -> Output (n,s) 
hello -> False (5, 52) 
MuLtIpLe -> False (8, 108)
Junct10n -> False (8, 83)
Order66 -> False (7, 72)
CodeGolf -> False (8, 67)
SUM -> False (3, 53)
ID -> False (2, 13)
25 -> False (2, 7)
0 -> False (1, 0) 0/1 = 0 which is not a positive integer
10 -> False (2, 1) 
hello2 -> True (6, 54)
5um -> True (3, 39)
length -> True (6, 66)
Order64 -> True (7, 70)
Covid19 -> True (7, 63)
Word -> True (4, 60)
APPLE -> True (5, 50)
lawYER -> True (6, 84)
abc123 -> True (6, 12)
is -> True (2, 28)
television -> True (10, 130)
19 -> True (2, 10)
234 -> True (3, 9)
a -> True (1, 1)
b -> True (1, 2)
C -> True (1, 3)
Z -> True (1, 26)
1 -> True (1, 1)
9 -> True (1, 9)
asked Sep 21, 2020 at 15:19
\$\endgroup\$
17
  • 2
    \$\begingroup\$ Sorry I missed this in the sandbox. Overall, a very good challenge! One thing though - I would consider allowing answerers to specify if they want input as whatever, all uppercase, or all lowercase - for most submissions, requiring both will just make them put a ".lower()" at the beginning which doesn't add much interesting to solutions. Up to you though - I think there could definitely be some interesting approaches this way too! \$\endgroup\$ Commented Sep 21, 2020 at 15:30
  • 3
    \$\begingroup\$ For whatever one opinion is worth, I don't agree with the idea to allow only upper & only lower. \$\endgroup\$ Commented Sep 21, 2020 at 15:35
  • 6
    \$\begingroup\$ Why is 0 falsey? 0 IS divisible by 1.. \$\endgroup\$ Commented Sep 21, 2020 at 15:40
  • 2
    \$\begingroup\$ "if and only if s is a multiple of n, or more strictly \$s \equiv 0 \mod n\,ドル or even \$s\div n\$ is a positive integer \${1,2,3,4...}\$" These three contradict each other for \$s = 0\$ \$\endgroup\$ Commented Sep 21, 2020 at 15:46
  • 2
    \$\begingroup\$ @Sumner18 The contradiction is in "s is a multiple of n" and "more strictly s mod n == 0" compared with "s/n is a positive integer". The first two are true for \$s=0\$ and the third isn't. I'd recommend removing the first two and just use the third, which is rigorous enough to work by itself \$\endgroup\$ Commented Sep 21, 2020 at 16:06

21 Answers 21

4
\$\begingroup\$

05AB1E, (削除) 16 (削除ここまで) 15 bytes

þIáÇ32%«ODXgÖ*Ā

Input as a list of characters.

-1 byte implicitly thanks to @ovs.

Try it online or verify all test cases.

Explanation:

þ # Only leave the digits of the (implicit) input-list
 Iá # Push the input-list again, and only leave its letters
 Ç # Convert each letter to its codepoint integer
 32% # Take modulo-32 on each codepoint
 « # Merge it to the list of digits
 O # Sum this list
 D # Duplicate this sum
 Ig # Push the input-list again, and pop and push its length
 Ö # Check if the sum is divisible by this length
 * # Multiply it by the duplicated sum
 Ā # And check that this is NOT 0
 # (after which the result is output implicitly)

3 bytes (D*Ā) are used for edge-cases 0/00/000/etc.

answered Sep 21, 2020 at 15:42
\$\endgroup\$
3
  • 1
    \$\begingroup\$ I had þSDŠKÇžw%«ODIgÖ*Ā - only one byte longer :). \$\endgroup\$ Commented Sep 21, 2020 at 16:04
  • \$\begingroup\$ @ovs Nice. I was actually just looking for some alternatives and found another 16-byter: Asálk>®þ«OD®gÖ*Ā. No 15-byter yet, although I have the feeling it's possible. \$\endgroup\$ Commented Sep 21, 2020 at 16:07
  • \$\begingroup\$ @ovs Actually, I think your approach opens up a 15-byter like this: þIáÇžw%«ODIgÖ*Ā, so thanks. :) \$\endgroup\$ Commented Sep 21, 2020 at 16:09
4
\$\begingroup\$

Jelly, (削除) 12 (削除ここまで) 11 bytes

ŒlO%48Sȯ.%L

A monadic Link accepting a list of characters which yields zero (falsey) if the string is a length-sum-multiple or a non-zero number (truthy) if not.

Try it online! Or see the test-suite.

How?

ŒlO%48Sȯ.%L - Link: list of characters, w e.g. "ID" "10" "19" "0...0"
Œl - lower-case (w) "id" "10" "19" "0...0"
 O - ordinals [105,100] [49,48] [49,57] [48,...,48]
 48 - forty-eight 48 48 48 48
 % - modulo [9,4] [1,0] [1,9] [0,...,0]
 S - sum 13 1 10 0
 . - a half 0.5 0.5 0.5 0.5
 ȯ - logical OR 13 1 10 0.5
 L - length (w) 2 2 2 length(w)
 % - modulo 1 1 0 0.5
 (nope nope yep! nope)
answered Sep 21, 2020 at 17:44
\$\endgroup\$
4
\$\begingroup\$

C (gcc), (削除) 73 (削除ここまで) \$\cdots\$ (削除) 63 (削除ここまで) 61 bytes

Saved (削除) a (削除ここまで) 3 bytes thanks to ceilingcat!!!

n;u;f(char*s){for(n=u=0;*s;++n)u+=*s&15+*s++/64*16;u*=u%n<1;}

Try it online!

Inputs a string and returns a truthy if it's a Length-Sum Multiple or a falsey otherwise.

answered Sep 21, 2020 at 16:22
\$\endgroup\$
0
4
\$\begingroup\$

J, 29 24 bytes

#(|=0=])1#.48|64|96|3&u:

Try it online!

-5 bytes thanks to xash

Inspired by Neil's answer -- be sure to upvote him.

  • 3&u: turns the string into ascii codes
  • 96| mods the lowercase letters into the range 1-26
  • 64| mods the uppercase letters into the range 1-26
  • 48| mods the digits into the range 0-9
  • 1#. sum of all those converted digits
  • # (on the far left) length of string
  • (|=0=]) First we check if the sum is zero 0=] -- this will return 1 when it is and 0 otherwise. Then we check if sum mod the length | is equal to that. Thus for the entire phrase to return true it must be the case that the sum is both evenly divisible its length and nonzero.

Why can't you just use a single 32 mod instead of doing a 96 followed by a 64?

With 32, you'd be affecting the values 0-9 as well. With 96/64, you fix the letters without touching the digits, and now, since the letters are all 26 and under, when you fix the digits the already-fixed letters are unaffected.

answered Sep 21, 2020 at 18:40
\$\endgroup\$
7
  • 2
    \$\begingroup\$ 24 bytes \$\endgroup\$ Commented Sep 21, 2020 at 21:25
  • 2
    \$\begingroup\$ Excellent. That added enough cleverness to be worthy of explanation :) \$\endgroup\$ Commented Sep 21, 2020 at 21:40
  • \$\begingroup\$ Based on the explanation, I would have guessed that one could replace both 64| and 96| with 32|, but that doesn't seem to be the case when I try... \$\endgroup\$ Commented Sep 22, 2020 at 13:32
  • 1
    \$\begingroup\$ Got it! It's right-to-left mods of the same number, right? Sorry for not having any clue about J syntax... \$\endgroup\$ Commented Sep 22, 2020 at 13:40
  • 1
    \$\begingroup\$ I love it! ...and, I've immediately stolen that trick to save 1 byte in my R answer. Thankyou very much! \$\endgroup\$ Commented Sep 22, 2020 at 13:43
3
\$\begingroup\$

Python 3, 54 bytes

lambda s:(sum(ord(c)%48for c in s.lower())or.5)%len(s)

An unnamed function accepting a string which returns zero (falsey) if the string is a length-sum-multiple or a non-zero number (truthy) if not.

Try it online! Or see the test-suite.

answered Sep 21, 2020 at 18:30
\$\endgroup\$
3
\$\begingroup\$

R, (削除) 63 (削除ここまで) (削除) 62 (削除ここまで) (削除) 57 (削除ここまで) 56 bytes

Edit: saved 1 byte thanks to Jonah

function(s)!sum(i<-utf8ToInt(s)%%96%%64%%48)%%nchar(s)&i

Try it online!

Output is Truthy list of one-or-more TRUEs, or Falsy list of one-or-more FALSEs.

answered Sep 21, 2020 at 15:48
\$\endgroup\$
3
\$\begingroup\$

Scala, (削除) 71 (削除ここまで) (削除) 62 (削除ここまで) 46 bytes

s=>{val x=(0/:s)(_+_%96%64%48);x>0&x%s.size<1}

Try it online

32 bytes if zero weren't falsey

s=>(0/:s)(_+_%96%64%48)%s.size<1

Try it online

answered Sep 21, 2020 at 17:10
\$\endgroup\$
5
  • \$\begingroup\$ As far as I can tell yours fails on the "0" test case \$\endgroup\$ Commented Sep 21, 2020 at 20:23
  • \$\begingroup\$ @MrRedstoner Fixed it for 71 bytes :( \$\endgroup\$ Commented Sep 22, 2020 at 12:50
  • \$\begingroup\$ 67 bytes: s=>{val x=s.map{x=>if(x.isDigit)x%48 else x%32}.sum;x>0&x%s.size<1} \$\endgroup\$ Commented Sep 22, 2020 at 13:27
  • \$\begingroup\$ If you 'steal' the amazingly-cunning trick from xash's tip for Jonah's answer, you could even get 50 bytes: s=>{val x=s.map{x=>x%96%64%48}.sum;x>0&x%s.size<1}... (at which point you'll be beating me...). \$\endgroup\$ Commented Sep 23, 2020 at 7:50
  • \$\begingroup\$ @DominicvanEssen Wow, that's really clever \$\endgroup\$ Commented Sep 23, 2020 at 13:31
3
\$\begingroup\$

Java (削除) 79 (削除ここまで) (削除) 77 (削除ここまで) (削除) 68 (削除ここまで) (削除) 66 (削除ここまで) 64 bytes

s->{int u=0;for(int c:s)u+=c%96%64%48;return u>0&u%s.length<1;};

Try it here!

My first ever answer! The "0" test case messed me up, without it I could have had 51, (I wanted to try challenge the C answer, from which I've borrowed the char-to-number conversion). Now pretty much a port of the C answer.

s->s.chars().map(c->c%96%64%48).sum()%s.length()<1;

Still fairly proud of beating out some of current answers in languages like Python and JavaScript using the 'oh so verbose' Java.

Thanks to @user for a few extra bytes saved

@ceilingcat for a few more

@dominic-van-essen for 2 more using @xash's idea

answered Sep 21, 2020 at 18:18
\$\endgroup\$
4
  • 1
    \$\begingroup\$ @user thanks, I really should have taken a better look at that C submission and realized that myself. \$\endgroup\$ Commented Sep 21, 2020 at 18:40
  • \$\begingroup\$ 68 bytes if you use an array \$\endgroup\$ Commented Sep 21, 2020 at 18:46
  • \$\begingroup\$ A shame about loosing Stream and making it pretty much a port of the C answer, but at least the fails-on-"0" is staying a Stream because I can't find a way to apply the same improvement without making it worse. \$\endgroup\$ Commented Sep 21, 2020 at 18:56
  • 1
    \$\begingroup\$ Very nice answer! 64 bytes if you steal xash's MOD tip for Jonah's answer. \$\endgroup\$ Commented Sep 24, 2020 at 6:40
2
\$\begingroup\$

Python 3.8, 59 bytes

lambda d:1>(x:=sum(int(c,36)-9*(c>'9')for c in d))%len(d)<x

Try it online!

answered Sep 21, 2020 at 15:42
\$\endgroup\$
3
  • \$\begingroup\$ is this "x:=" an assignment inside an expression? That's rather new isn't it? \$\endgroup\$ Commented Sep 21, 2020 at 16:00
  • 1
    \$\begingroup\$ @Teck-freak yes it was introduced in version 3.8 and is called assignment expression. The walrus operator is quite handy for golfing. \$\endgroup\$ Commented Sep 21, 2020 at 16:07
  • \$\begingroup\$ yes, I even played around a bit when it was introduced. I completely forgot about it, as I'm mainly doing addons in 2.7 and 3.4 and maybe 3.7 Nice idea going with a base36 int by the way. \$\endgroup\$ Commented Sep 21, 2020 at 16:12
2
\$\begingroup\$

Charcoal, 18 bytes

≔ΣE↧θ%c/oι48η∧η¬%ηLθ

Try it online! Link is to verbose version of code. Output is a Charcoal boolean, i.e. - for a multiple, nothing if not. Explanation:

≔ΣE↧θ%c/oι48η

Convert the string to lower case, take the code points of all the characters, reduce them modulo 48, then take the sum.

∧η¬%ηLθ

Check that the sum is a non-zero multiple of the length of the string.

answered Sep 21, 2020 at 17:55
\$\endgroup\$
2
\$\begingroup\$

Perl 5 + -plF, 32 bytes

-7 bytes thanks to @Nahuel Fouilleul!

$s+=ord(lc)%48for@F;$_&&=1>$s%@F

Try it online!

answered Sep 21, 2020 at 18:47
\$\endgroup\$
3
  • 1
    \$\begingroup\$ 38 bytes without using sum Try it online! \$\endgroup\$ Commented Sep 22, 2020 at 9:44
  • \$\begingroup\$ @NahuelFouilleul Nice! Much cleaner, thank you! I wasn't happy with it last night, but I didn't have time to go back to it :) \$\endgroup\$ Commented Sep 22, 2020 at 10:52
  • \$\begingroup\$ nice trick to switch to lowercase so that 96%48 is also 0 \$\endgroup\$ Commented Sep 22, 2020 at 17:47
1
\$\begingroup\$

Python 3, (削除) 101 (削除ここまで) 96 bytes

def f(s):x=sum([i-[48,96][i>96]for i in map(ord,s.lower())]);return not(x%len(s))and x//len(s)>0

Try it online!

answered Sep 21, 2020 at 15:51
\$\endgroup\$
2
  • \$\begingroup\$ You can replace your ternery construct "-96if i>96else i-48" with "-[48,96][i>96]" which saves you 5 bytes (boolean as index). \$\endgroup\$ Commented Sep 21, 2020 at 16:20
  • \$\begingroup\$ You can return "not x%len(s)" The brackets fall away (operation-order) and the "and"-part isn't needed as the only case where it is 0 is for empty strings, or if we have rest. empty strings need not be checked and rests are already indicating a False => saves 16 Bytes \$\endgroup\$ Commented Sep 21, 2020 at 16:26
1
\$\begingroup\$

Jelly, 23 bytes

ØWiⱮ_3e€ØD¤%26Sμ;ọ3L¤$Ȧ

Try it online!

Golfed 1 byte and also made the program actually work (third time's a charm? it was still broken)

Explanation

ØWiⱮ_3e€ØD¤%26Sμ;ọ3L¤$Ȧ Main Link
 Ɱ For each character in the input
 i find its index in
ØW "ABC...XYZabc...xyz0123456789_"
 _ and subtract from each element
 3e€ØD¤ the corresponding value, which is
 3 if the original character
 e€ is a member of
 ØD the digits (this is to fix the one-off offset of the digits)
 (the above nilad gets a list of 0 and 1 for if each character is a digit, and since Jelly's subtraction `_` is vectorized, this works as subtracting the corresponding element)
 %26 modulo 26
 Sμ take the sum; begin a new link with this value
 ; $ append
 ọ the number of times the sum is divisible by (just plain "divisible by?" has the arguments in the opposite order which would take 1 extra byte to flip)
 3L¤ the length of the input
 Ȧ any and all - are both values truthy; that is, is the sum divisible and non-zero?
answered Sep 21, 2020 at 16:16
\$\endgroup\$
4
  • 1
    \$\begingroup\$ This fails for 0, an irritating corner case \$\endgroup\$ Commented Sep 21, 2020 at 16:16
  • \$\begingroup\$ @cairdcoinheringaahing i thought i fixed that lol??? well, thanks for pointing that out, i managed to golf 0 bytes with a different approach but it did fix the problem! \$\endgroup\$ Commented Sep 21, 2020 at 16:22
  • \$\begingroup\$ Well, it's a better answer than mine (yours actually works :P), very nice :D. Interesting that you used ØW (my original approach used ØB) \$\endgroup\$ Commented Sep 21, 2020 at 16:23
  • 1
    \$\begingroup\$ @cairdcoinheringaahing yeah my first try used that and I think I just ended up copy-pasting a different one when I retried with this approach lol \$\endgroup\$ Commented Sep 21, 2020 at 16:24
1
\$\begingroup\$

Japt, (削除) 22 (削除ここまで) (削除) 17 (削除ここまで) 15 bytes

Input is an array of characters.

Or 13 bytes, without having to special-case 0.

xÈv c u48
©vNÎl

Try it

;x@ÒBbXu)aX\n©vNÎl :Implicit input of character array U
 x :Reduce by addition
 @ :After passing each X through the following function
 Ò : Negate the bitwise NOT of
; B : Uppercase alphabet
 b : 0-based index of
 Xu : Uppercase X
 ) : End indexing
 aX : Logical OR with X, which gets coerced to an integer
 \n :Reassign to U
 © :Logical AND with
 v : Is divisible by
 N : Array of all inputs
 Î : First element (i.e., the original U)
 l : Length
answered Sep 21, 2020 at 15:48
\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), (削除) 54 (削除ここまで) 53 bytes

Returns 0 or 1.

s=>Buffer(s).map(c=>t+=++k&&c%96%64%48,k=t=0)|t%k<!!t

Try it online!

answered Sep 21, 2020 at 16:17
\$\endgroup\$
0
\$\begingroup\$

Python 2 & Python 3 -- 69 Bytes

lambda a:0==sum(ord(s.upper())-[64,48][s.isdigit()]for s in a)%len(a)

Assuming the input as string on variable a, one can get down to 60 Bytes

0==sum(ord(s.upper())-[64,48][s.isdigit()]for s in a)%len(a)
answered Sep 21, 2020 at 15:53
\$\endgroup\$
2
  • 3
    \$\begingroup\$ Hello, based on site consensus, input cannot be taken as a variable. You could wrap your program into a function/lambda and it would be valid. Also, your program has to either output the value or return it from a function, it cannot be a single expression that evaluates to the answer. \$\endgroup\$ Commented Sep 21, 2020 at 16:00
  • \$\begingroup\$ Hello @HyperNeutrino I fail to see how a single expression is not applicable, but yes, I'll modify it into a lambda. (it is my fift golf and the first in over 2 years.) \$\endgroup\$ Commented Sep 21, 2020 at 16:08
0
\$\begingroup\$

JavaScript, 107 bytes

a=>(b=a.toLowerCase().split('').reduce((c,d)=>c+(+(isNaN(d)?d.charCodeAt(0)-96:d)),0)/a.length,!(b?b%1:!b))

Try it online!

answered Sep 21, 2020 at 16:53
\$\endgroup\$
0
\$\begingroup\$

Retina 0.8.2, 63 bytes

^
$.'$*1;
T`L`l
[j-z]
55$&
[t-z]
55$&
T`_l`ddd
\d
$*
^(1+);1円+$

Try it online! Link includes test cases. Explanation:

^
$.'$*1;

Prefix the input with a unary copy of itself.

T`L`l

Convert it to lower case.

[j-z]
55$&
[t-z]
55$&
T`_l`ddd

Convert the letters to digits with the same digital sum.

\d
$*

Take the digital sum.

^(1+);1円+$

Check that it is a non-zero multiple of the length.

answered Sep 21, 2020 at 18:09
\$\endgroup\$
0
\$\begingroup\$

MAWP, 78 bytes

%|0/[!843WWP843WWWA/]~[!88WP88WWA/]~[!86WP86WWA/]_1A![1A~M~]%!~!~/P\WA{0:.}?1:

Try it!

Waiting for answer in 1+...

Uses the modulus method from Jonah's J answer.

answered Sep 22, 2020 at 4:30
\$\endgroup\$
0
\$\begingroup\$

MATL, (削除) 12 (削除ここまで) 11 bytes

k48\stGn\~*

Output is 0 if the input is length-sum multiple, or a positive number otherwise.

Try it online! Or verify all test cases.

How it works

k % Implicit input. Convert to lowercase
48 % Push 48
\ % Modulus. Each character is first converted to its code-point
s % Sum. This gives "s"
t % Duplicate (*)
G % Push input again
n % Number of elements. This gives "n"
\ % Modulus
~ % Negate. This gives true if s mod n equals 0, or false otherwise (**)
* % Multiply (*) and (**)
 % Implicit display. True and false are displayed as 1 and 0 respectively
answered Sep 21, 2020 at 17:04
\$\endgroup\$
0
\$\begingroup\$

Wolfram Language (Mathematica), 54 bytes

Tr[a=FromDigits/@#/.a_/;a>9:>a-9]~Mod~Tr[1^#]==0<Tr@a&

Try it online! Pure function. Takes a list of characters as input and returns True or False as output. The bulk of the work is done by FromDigits, which converts the characters 0-9, A-Z to the numbers 0-35.

answered Sep 25, 2020 at 10:52
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.