15
\$\begingroup\$

Supreme Sum String

Given an input string, return the word with the highest sum of each of its unicode characters.

Rules

  • The input should be seperated by whitespace
  • The value of each word is based on the sum of each character in the word's UTF-16 code
  • The output should be the first word with the highest value (in case of duplicate sums)

Examples

Input: "a b c d e"
Output: "e"

Input: "hello world"
Output: "world"

Input: "this is a test"
Output: "test"

Input: "àà as a test"
Output: "àà"

Input "α ää"
Output: "α"

Input: "🍬 隣隣隣"
Output: "隣隣隣"

Input: "💀 👻 🤡 🦇 🕷️ 🍬 🎃"
Output: "🕷️"

This is code golf, so the shortest answer wins! Good luck :)

\$\endgroup\$
  • \$\begingroup\$ Will there always be at least one space (at least 2 words)? \$\endgroup\$ – Emigna Oct 5 '18 at 16:13
  • 2
    \$\begingroup\$ This would have been more interesting with ASCII instead of Unicode, because more languages could have participated. Requiring Unicode support doesn't seem to add anything to the challenge \$\endgroup\$ – Luis Mendo Oct 5 '18 at 17:05
  • 1
    \$\begingroup\$ I mostly used Unicode because it has emojis lol \$\endgroup\$ – GammaGames Oct 5 '18 at 17:45
  • 2
    \$\begingroup\$ Since many of the current answers seem to use the sum of UTF-8 or UTF-32 code units, you should add some additional test cases. For example "α ää" yields different results with UTF-8 (383 < 718) and UTF-16 (945 > 456). \$\endgroup\$ – nwellnhof Oct 5 '18 at 18:04
  • 1
    \$\begingroup\$ Yeah, newlines area allowed. Tabs too! \$\endgroup\$ – GammaGames Oct 5 '18 at 22:37

16 Answers 16

3
\$\begingroup\$

Jelly, 7 bytes

ḲOS$ÐṀḢ

Try it online!

ḲOS$ÐṀḢ
Ḳ        Split input on spaces
    ÐṀ   Give words that have maximum of:
   $       Monad:
 O           ord(each character)
  S          sum
      Ḣ  First word that gives the max ord-sum.
\$\endgroup\$
  • \$\begingroup\$ If the spec is relaxed to input being allowed as a list of words then O§MḢị \$\endgroup\$ – Jonathan Allan Oct 5 '18 at 18:44
  • \$\begingroup\$ @JonathanAllan Where did OP say that was allowed? \$\endgroup\$ – dylnan Oct 5 '18 at 19:05
  • \$\begingroup\$ didn't just if... \$\endgroup\$ – Jonathan Allan Oct 5 '18 at 19:20
  • \$\begingroup\$ @JonathanAllan Ah, gotcha. \$\endgroup\$ – dylnan Oct 5 '18 at 19:39
  • 1
    \$\begingroup\$ @GammaGames It would help if I could take a list of strings, e.g. ["abc", "def"]. But at this point there are a lot of answers so I don't recommend adding new methods of input \$\endgroup\$ – dylnan Oct 5 '18 at 23:45
7
\$\begingroup\$

Perl 6, 34 bytes

*.words.max(*.encode('utf16').sum)

Try it online!

\$\endgroup\$
6
\$\begingroup\$

R, 77 69 59 58 56 44 bytes

A group effort now.

'^'=mapply
sort(-sum^utf8ToInt^scan(,""))[1]

Try it online!

Convert to code points, sum each word, negate, (stably) sort, return first element.

Technically the return value is a "named vector" whose value is the sum and name is the winning word, but this seems to follow the rules. If you want to return the winning word as a string, you'd have to spend 7 more bytes and wrap the above in names().

\$\endgroup\$
  • \$\begingroup\$ Is there a reason there's spaces in front of the word? When I run it on"💀 👻 🤡 🦇 🕷️ 🍬 🎃" it prints out " 🕷️ " (with a bunch of spaces in front of it) \$\endgroup\$ – GammaGames Oct 5 '18 at 17:43
  • 2
    \$\begingroup\$ @GammaGames the output is what is called a "named vector" in R. In this case the value is the sum of the code points of the winning word, and the name is printed along with it, which in this case is the winning word itself. The name is right-aligned to the number below it. \$\endgroup\$ – ngm Oct 5 '18 at 17:46
  • \$\begingroup\$ Oh, neat! It looks like it does follow the rules, so I'll allow it. Cool entry! \$\endgroup\$ – GammaGames Oct 5 '18 at 17:56
  • \$\begingroup\$ sort(-sapply(...)) is shorter by 3 bytes. \$\endgroup\$ – Giuseppe Oct 5 '18 at 18:05
  • 3
    \$\begingroup\$ @JayCe mapply does the unlist for free. \$\endgroup\$ – ngm Oct 5 '18 at 18:29
5
\$\begingroup\$

05AB1E, 8 bytes

ð¡RΣÇO}θ

Try it online!

Explanation

ð¡          # split input on spaces
  R         # reverse the resulting list
   Σ  }     # sort by
    ÇO      # sum of character codes
       θ    # take the last
\$\endgroup\$
  • \$\begingroup\$ Wow, I'm always amazed by the answers made in dedicated golfing languages! \$\endgroup\$ – GammaGames Oct 5 '18 at 16:49
  • \$\begingroup\$ Why do you need to reverse the resulting list? It's gonna get sorted anyways right? Or does the R actually reverse the list after it's sorted? \$\endgroup\$ – FireCubez Oct 6 '18 at 15:53
  • \$\begingroup\$ @FireCubez For test case àà as a test the àà and test have the same largest unicode sum. So without the reverse test would be output instead of àà. Btw, Emigna, use # to save a byte. ;) EDIT: Never mind. I see it doesn't wrap the input in a list for single word inputs.. That's unfortunate. \$\endgroup\$ – Kevin Cruijssen Oct 6 '18 at 20:31
4
\$\begingroup\$

JavaScript (ES6), 81 bytes

s=>s.split` `.map(m=s=>m=[...s].map(c=>t+=c.charCodeAt(),t=0)&&t<=m?m:(r=s,t))&&r

Try it online!

\$\endgroup\$
  • \$\begingroup\$ That's way better than the code I came up with when I was writing the challenge, mine was ~200 chars long! \$\endgroup\$ – GammaGames Oct 5 '18 at 16:46
  • \$\begingroup\$ 72 bytes \$\endgroup\$ – guest271314 Oct 5 '18 at 23:14
  • \$\begingroup\$ @guest271314 doesn't work for the second last test case and some extreme cases like f("😂 龘龘龘龘龘") \$\endgroup\$ – Shieru Asakoto Oct 6 '18 at 0:25
  • \$\begingroup\$ @ShieruAsakoto Appears to return correct result here tio.run/##y0osSyxOLsosKNHNy09J/… ? What is expected result for "😂 龘龘龘龘龘"? \$\endgroup\$ – guest271314 Oct 6 '18 at 1:25
  • \$\begingroup\$ Oh nvm 隣(\uf9f1) was the one in CJK Compatibility Ideograph block instead lol. Thought it was 隣(\u96a3), the one in CJK Unified Ideograph block. \$\endgroup\$ – Shieru Asakoto Oct 6 '18 at 1:36
4
\$\begingroup\$

jq, 61 43 57 37 characters

(57 39 53 33 characters code + 4 characters command line options)

./" "|reverse|max_by(explode|add)

Sample run:

bash-4.4$ jq -Rr './" "|reverse|max_by(explode|add)' <<< 'àà as a test'
àà

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Indeed. Missed that case. ☹ Thanks, @nimi. \$\endgroup\$ – manatwork Oct 5 '18 at 17:00
4
\$\begingroup\$

Pyth, 8 bytes

h.MsCMZc

Test suite

I know there's already a Pyth answer but I feel like this uses a pretty different approach and also it's waaaay shorter

Explanation:
h.MsCMZc  | Full code
h.MsCMZcQ | with implicit variables added
----------+------------------------------------
h         | The first element of
       cQ | the input chopped at whitespace
 .M       | with the maximal value for
   s      | the sum of
    CMZ   | the Unicode value of each character
\$\endgroup\$
  • \$\begingroup\$ Wow, that's really precise! Thanks for the explanation! \$\endgroup\$ – GammaGames Oct 6 '18 at 3:03
4
\$\begingroup\$

PowerShell, 74 52 bytes

(-split$args|sort{$r=0;$_|% t*y|%{$r+=$_};$r}-u)[-1]

Try it online!

Thanks to mazzy for a whopping -22 bytes.

-splits the input $args on whitespace, pipes that into sort with a particular sorting mechanism {...} and the -unique flag.

Here we're taking the current word $_, changing it toCharArray, then for each letter we're adding it into our $result. That turns the string into a number based on its UTF-16 representation.

For once, PowerShell having all strings be UTF-16 in the background is a life-saver!

We then encapsulate those results in (...) to transform them into an array and take the last [-1] one, i.e., the largest result that's the closest to the start of the sentence. This works because of the -unique flag, i.e., if there's a later element that has the same value, it's discarded. That word is left on the pipeline and output is implicit.

\$\endgroup\$
  • \$\begingroup\$ it's smart. Thanks. 2 moments: why not sort -u instead a reverse? can be enough + to convert in the number? (-split$args|sort{($_|% t*y|%{+$_})-join"+"|iex} -u)[-1] \$\endgroup\$ – mazzy Oct 6 '18 at 7:00
  • \$\begingroup\$ more golf: (-split$args|sort{$r=0;$_|% t*y|%{$r+=$_};$r}-u)[-1] :) \$\endgroup\$ – mazzy Oct 6 '18 at 7:12
  • \$\begingroup\$ @mazzy Yes, thanks! \$\endgroup\$ – AdmBorkBork Oct 8 '18 at 13:50
3
\$\begingroup\$

Python 3, 55 52 bytes

lambda s:max(s.split(),key=lambda w:sum(map(ord,w)))

Try it online!

  • -3 bytes thanks to Gigaflop for pointing out that no argument is needed in the split method.
\$\endgroup\$
  • \$\begingroup\$ You can save 3 bytes by passing no args to split(), as it splits on any group of whitespace. \$\endgroup\$ – Gigaflop Oct 5 '18 at 18:17
2
\$\begingroup\$

MATLAB, 57 bytes

s=strsplit(input('','s'));[Y I]=max(cellfun(@sum,s));s(I)

In my MATLAB R2016a all tests arepassed, except that emojis are not rendered properly. But characters are returned correctly

\$\endgroup\$
2
\$\begingroup\$

Japt -h, 8 bytes

@Enigma approach

¸w ñ_¬xc

Try it online!


Another Approach

Japt -g, 8 bytes

¸ñ@-X¬xc

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Identical to what I was about to post. The need for the reversal annoys me; would've preferred if we could output any of the words in the case of a tie. \$\endgroup\$ – Shaggy Oct 5 '18 at 18:24
  • \$\begingroup\$ @Shaggy if that was possible, I have a 6 bytes answer for it \$\endgroup\$ – Luis felipe De jesus Munoz Oct 5 '18 at 18:27
  • \$\begingroup\$ Same 6-byter I started with before spotting that requirement in the spec. \$\endgroup\$ – Shaggy Oct 5 '18 at 18:28
  • \$\begingroup\$ I'm sorry! Originally when I sandboxed the challenge I figured it could output any of the answers, but I changed it after a little feedback so it was more consistent \$\endgroup\$ – GammaGames Oct 5 '18 at 22:43
2
\$\begingroup\$

Java (JDK), 117 97 84 bytes

-13 bytes thanks @Nevay. Apparently I didn't know I can also use var in Java.

s->{var b="";for(var a:s.split(" "))b=a.chars().sum()>b.chars().sum()?a:b;return b;}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ -13 bytes: s->{var b="";for(var a:s.split(" "))b=a.chars().sum()>b.chars().sum()?a:b;return b;} \$\endgroup\$ – Nevay Oct 6 '18 at 18:39
1
\$\begingroup\$

Ruby, 45 characters

->s{s.split.max_by{|w|w.codepoints.reduce:+}}

Sample run:

irb(main):001:0> ->s{s.split.max_by{|w|w.codepoints.reduce:+}}['àà as a test']
=> "àà"

Try it online!

Ruby 2.4, 40 characters

->s{s.split.max_by{|w|w.codepoints.sum}}

(Untested.)

\$\endgroup\$
1
\$\begingroup\$

Pyth, 33 bytes

FHmCdmcd)Kczd aYu+GHmCdH0)@KxYeSY

Try it online!

There is almost certainly a better way to do this, but I spent too much on it so this will do.

FH  #For every array of letters in 
  mCd   #the array of arrays of letters [['w', 'o', 'r', 'l', 'd'], ['h', 'e', 'l', 'l', 'o']]
     mcd)   #wrap that in another array [[hello"], ["world"]]
         Kczd   #split input(z) on spaces ["hello", "world"] and assign it to K for later
              aY     #append to list Y... " " silences the prints from the for loop.
                u+GH    #reduce the list of numbers by summing them    
                    mCdH    #convert each letter in the array to its int counterpart
                        0)    #the zero for the accumulator and close for loop
                          @K    #get by index the word from K
                            xY   #find the index in Y of that number
                              eSY   #sort Y, get the last (largest) number

I would have passed a reduce into another map instead of using the for loop, but I couldn't get that to work.

\$\endgroup\$
  • \$\begingroup\$ Oh boy, a pyth answer! Thanks for the explanation, nice entry! \$\endgroup\$ – GammaGames Oct 5 '18 at 22:41
1
\$\begingroup\$

Charcoal, 20 bytes

≔⪪S θ≔EθΣEι℅λη§θ⌕η⌈η

Try it online! Link is to verbose version of code. Explanation:

≔⪪S θ

Split the input string on spaces and assign to q.

≔EθΣEι℅λη

Calculate the sum of the ordinals of the characters in each word and assign to h.

§θ⌕η⌈η

Find the index of the highest sum and print the word at that index.

\$\endgroup\$
1
\$\begingroup\$

Powershell, 66 bytes

Straightforward. See AdmBorkBork's answer to found a smart using of Powershell.

-split$args|%{$s=0
$_|% t*y|%{$s+=$_}
if($s-gt$x){$w=$_;$x=$s}}
$w

Note! To correct work with unicode, save your script file with UTF-16 or UTF8 with BOM encoding.

Test script:

$f = {

-split$args|%{$s=0         # split argument strings by whitespaces, for each word
$_|% t*y|%{$s+=$_}         # let $s is sum of unicode char code
if($s-gt$x){$w=$_;$x=$s}}  # if $s greater then previous one, store word and sum to variables
$w                         # return word from stored variable

}

@(
    ,("a b c d e", "e")

    ,("hello world", "world")

    ,("this is a test", "test")

    ,("àà as a test", "àà")

    ,("α ää", "α")

    ,("🍬 隣隣隣", "隣隣隣")

    ,("💀 👻 🤡 🦇 🕷️ 🍬 🎃", "🕷️")
) | % {
    $s,$e=$_
    $r=&$f $s
    "$($r-eq$e): $r"
}

Output:

True: e
True: world
True: test
True: àà
True: α
True: 隣隣隣
True: 🕷️
\$\endgroup\$

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.