7
\$\begingroup\$

Description

In this challenge, you need to write a function that takes in a list of strings and returns the smallest string based on their ASCII value. You should assume that the input list contains only lowercase alphabetical strings.

Test Cases

["a", "b", "c"] => "a"
["hello", "world", "code"] => "code"
["aaa", "aa", ""] => ""
["cat", "bat", "rat"] => "bat"
["zab", "xyz", "abcd"] => "zab"

Write the function in as few bytes as possible. The code itself can be a function, process or anything provided that it gives the desired output. Use of other ASCII characters like big or small letters, with space function must be supported.

\$\endgroup\$
11
  • 2
    \$\begingroup\$ "Smallest string based on ASCII value" as in the string with the smallest sum of ASCII values? \$\endgroup\$
    – Seggan
    Commented Mar 3, 2023 at 16:27
  • \$\begingroup\$ @Seggan precisely correct, the individual ASCII values are added \$\endgroup\$ Commented Mar 3, 2023 at 16:28
  • 5
    \$\begingroup\$ I suggest you clarify that in the post \$\endgroup\$
    – Seggan
    Commented Mar 3, 2023 at 16:31
  • \$\begingroup\$ Suggested test case: ["zab", "xyz", "abcd"] => "zab" \$\endgroup\$
    – The Thonnu
    Commented Mar 3, 2023 at 17:52
  • 1
    \$\begingroup\$ I suggest you remove the requirement of supporting extended ASCII. With standard ASCII the logic of the algorithm is probably the same, and it allows more languages to participate \$\endgroup\$
    – Luis Mendo
    Commented Mar 3, 2023 at 18:03

29 Answers 29

3
\$\begingroup\$

05AB1E, 5 bytes

ΣÇO}н

Try it online!

Explanation

ΣÇO}н # Implicit input
Σ  }  # Sort by:
 Ç    #  ASCII values
  O   #  Sum
    н # First item
      # Implicit output
\$\endgroup\$
3
\$\begingroup\$

Factor, 22 bytes

[ [ sum ] infimum-by ]

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Java (JDK), 57 bytes

l->l.stream().min((a,b)->a.chars().sum()-b.chars().sum())

Try it online!

Takes input as a List<String> and returns an Optional<String>.

\$\endgroup\$
3
\$\begingroup\$

BQN, 18 16 bytes

-2 from Dominic van Essen for replacing '0' with @.

{𝕩⊑˜⊑⍒(+´@⊸-)¨𝕩}

Try it online!

Explanation

{𝕩⊑˜⊑⍒(+´@⊸-)¨𝕩}  
{              ¨𝕩} 1. For each string in the (monadic) input 𝕩
{     (  @⊸-)  } 2a. convert the string to (negative) its unicode representation...
{     (+´     )  } 2b. and perform a sum reduction.
{    ⍒(       )  } 3. return descending-sorted indices.
{   ⊑            } 4. take the first.
{𝕩⊑˜             } 5. take this index into the input 𝕩 where ˜ "flips" the next function.
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Save 2 bytes by changing '0' to @... \$\endgroup\$ Commented Mar 18, 2023 at 9:41
  • \$\begingroup\$ Cheers, I didn't know about @ :s \$\endgroup\$ Commented Mar 19, 2023 at 16:47
2
\$\begingroup\$

Vyxal, 5 4 bytes

‡C∑P

Try it Online!

-1 thanks to @mathcat

Explanation

‡C∑P  # Implicit input
‡  P  # Minimum by:
 C    #  ASCII values
  ∑   #  Sum
      # Implicit output

Old:

C∑)ṡh # Implicit input
  )ṡ  # Sort by:
C     #  ASCII values
 ∑    #  Sum
    h # First item
      # Implicit output 
\$\endgroup\$
2
  • \$\begingroup\$ 4 bytes \$\endgroup\$
    – math scat
    Commented Mar 3, 2023 at 17:17
  • \$\begingroup\$ @mathcat thanks, updated \$\endgroup\$
    – The Thonnu
    Commented Mar 3, 2023 at 17:32
2
\$\begingroup\$

C (gcc), 92 bytes

f(s,t,u,i,c)char**s,*t,*u;{for(i=~0,u=0;t=*s;c<i+0U?u=*s,i=c:0,s++)for(c=0;*t;c+=*t++);s=u;}

Try it online!

Ungolfed:

f(s,t,u,i,c)char**s,*t,*u;{
  for(i=~0, // initialize minimum string sum to largest possible
      u=0; // initialize smallest string (in case of empty list)
      t=*s; // scan list
      c<i+0U?u=*s,i=c:0, // reset minimum string sum and pointer if smaller
      s++)
    for(c=0;*t;c+=*t++); // get string sum
  s=u; // return smallest string
}
\$\endgroup\$
2
\$\begingroup\$

Raku, 17 bytes

*.min(*.ords.sum)

Try it online!

*.ords.sum is an anonymous function that calculates the sum of the ordinal values of its string argument. That function is passed as the argument to *.min, which returns the element of the input list with the smallest value computed by the first function.

\$\endgroup\$
2
  • \$\begingroup\$ Your explanation seems to break off at a \$\endgroup\$ Commented Mar 18, 2023 at 14:50
  • \$\begingroup\$ Huh! Fixed. Dunno how that happened. \$\endgroup\$
    – Sean
    Commented Mar 18, 2023 at 17:38
2
\$\begingroup\$

Ruby, 19 bytes

->x{x.min_by &:sum}

Try it online!

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

Swift, 64  69 bytes

Now with fewer compiler crashes!

{$0.map{($0.reduce(0){$0+Int($1.asciiValue!)},$0)}.min{$0.0<$1.0}!.1}

SwiftFiddle link

\$\endgroup\$
1
  • \$\begingroup\$ The original version only worked for short strings; after more than a couple characters, it would overflow the limit for UInt8. However, when you hardcode the input, constant-folding causes this overflow to happen at compile-time, an the compiler crashes. \$\endgroup\$
    – Bbrk24
    Commented Mar 3, 2023 at 16:49
1
\$\begingroup\$

Python, 44 bytes

lambda l:min(l,key=lambda x:sum(map(ord,x)))

Attempt This Online!

Commented

lambda l:                                     # Anonymous function taking l, a list of strings
         min(l,                            )  # Return the minimum of l...
               key=                           # ...using the following function:
                   lambda x:                  #  Function taking x, a string
                            sum(          )   #  Sum the following:
                                map(ord,x)    #  Convert all characters to ASCII values
\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 59 bytes

a=>a.sort(g=(x,y)=>x>=x&&~~eval(Buffer(x).join`+`)-g(y))[0]

Try it online!

Commented

a =>            // a[] = input array
a.sort(g =      // g is a recursive callback function
  (x, y) =>     // for each pair (x, y) to be tested:
    x >= x &&   //   stop if x is undefined
    ~~eval(     //   otherwise, evaluate as JS code:
      Buffer(x) //     the ASCII codes of x
      .join`+`  //     joined with '+'
    )           //   end of eval()
    - g(y)      //   subtract the result of a recursive call with x = y
)               // end of sort()
[0]             // keep the first entry
\$\endgroup\$
1
\$\begingroup\$

Japt -g, 4 bytes

Takes input as an array of character arrays.

ñÈxc

Try it

ñÈxc     :Implicit input of 2D array
ñ        :Sort by
 È       :Function
  x      :  Sum of
   c     :    Codepoints
         :Implicit output of first element
\$\endgroup\$
1
\$\begingroup\$

Excel, 78 bytes

=LET(x,A1#,y,ROW(A:A),@SORTBY(x,MMULT(TOROW(y^0),IFERROR(CODE(MID(x,y,1)),))))

where A1# is a horizontal spilled range containing the strings.

\$\endgroup\$
1
  • \$\begingroup\$ In theory I thought =@SORTBY(A1#,MAP(A1#,LAMBDA(x,SUM(IFERROR(CODE(MID(x,ROW(A:A),1)),)+1)))) for 73 bytes would work. Using the implicit intersection operator should return the top-left cell. However, it's either bugged or not working as I expected. \$\endgroup\$
    – JvdV
    Commented Mar 6, 2023 at 14:37
1
\$\begingroup\$

Zsh +old utils, 47 55 103 bytes

Using the filesystem and the old System V sum* command:

for i;echo $i>$[++n];set `sum -s *|sort -n`;<$3

Try it online!   55 bytes

* On MacOS, cksum -o2 is equivalent to GNU sum -s. According to Wikipedia, the BSD checksum algorithm is "useless from a security perspective" 😛


103 bytes, using arrays and builtins only:

for x;{w=;for a (${(s::)${x:?}})((w+=#a));k+=($w)}
for i ({1..$#})((k[i]==$(printf ${(n)k})))&&<<<$@[i]

Try it online!
Explanation of code is in earlier revisions of this answer

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

Burlesque, 9 bytes

{)**++}<m

Try it online!

{
 )** # Map to ord
 ++  # sum
}<m  # Minimum by
\$\endgroup\$
1
\$\begingroup\$

Jelly, 5 bytes

OS$ÞḢ

Try it online!

Explanation

OS$ÞḢ  # Main link
  $    # Last two links as a monad:
O      #  Ordinals
 S     #  Sum
   Þ   # Sort the input by this monad
    Ḣ  # First item (minimum)
\$\endgroup\$
1
\$\begingroup\$

Stax, 9 5 bytes

And pure ASCII!

{|+}e

Run and debug it (with test cases)

Explanation

{  }e # minimum by
 |+   # sum
\$\endgroup\$
1
\$\begingroup\$

janet, 51 bytes

(fn[l](((sort-by first(map(fn[x][(sum x)x])l))0)1))

in janet, you can save bytes by not using spaces between brackets, which i personally think is very ugly for a lisp-like language, so here's an de-uglified version and an example

(fn [l] (((sort-by first (map (fn [x] [(sum x) x]) l)) 0) 1))
$ janet
Janet 1.29.1-20230709 openbsd/x64/clang - '(doc)' for help
repl:1:> (def F (fn[l](((sort-by first(map(fn[x][(sum x)x])l))0)1)))
<function 0x028B13B5F580>
repl:2:> (F ["zab" "xyz" "abcd"])
"zab"
\$\endgroup\$
1
\$\begingroup\$

Pip, 12 10 bytes

@Y$+A*_SKg

Attempt This Online!

-2 thanks to @DLosc

Explanation

@Y$+A*_SKg  ; Input on command line
         g  ; Input list
       SK   ; Sorted by:
  $+        ;  Sum of
    A*      ;  ASCII values of
      _     ;  The string
@Y          ; First item (minimum)
            ; Implicit output
\$\endgroup\$
1
  • \$\begingroup\$ Just noticing this answer a year later... you can save two bytes on the function by using a lambda expression $+A*_. \$\endgroup\$
    – DLosc
    Commented Mar 6 at 7:29
1
\$\begingroup\$

R, 50 47 bytes

  • -3 bytes by pajonk
which.min(Map(\(x)sum(utf8ToInt(x)),scan(,"")))

Attempt This Online!

This outputs a named vector with the smallest value string as the name and the value is the string's position in the input list. If this is against the rules, then the following code for 7 bytes more will provide the clean output: names(which.min(Map(\(x)sum(utf8ToInt(x)),scan(,""))))

\$\endgroup\$
1
  • 1
    \$\begingroup\$ -3 bytes using Map (apparently which.min works also for lists...) \$\endgroup\$
    – pajonk
    Commented May 7 at 17:59
0
\$\begingroup\$

Arturo, 42 bytes

$=>[minimum&=>[∑to[:integer]to[:char]&]]

Try it

\$\endgroup\$
0
\$\begingroup\$

Retina 0.8.2, 74 bytes

.
$&$&96$*~
0T1`l`L`\w\w
{`[J-Z]
9$&
}T`_L`dL
\d
$*~
+`(\w)~
~$1
O`
1G`
~

Try it online! Only accepts strings of lowercase letters. Explanation:

.
$&$&96$*~

Duplicate each letter and suffix 96 ~s to each pair.

0T1`l`L`\w\w

Uppercase alternate letters.

{`[J-Z]
9$&
}T`_L`dL

Map uppercase letters into digits that sum to their index i.e. A=1 to Z=998.

\d
$*~

Expand the digits into that many ~s.

+`(\w)~
~$1

Move all of the ~s to the beginning of the string.

O`

Sort the strings into order. Since ~ sorts after z, this means that the string with the fewest ~s will sort first.

1G`

Keep only the first string.

~

Delete the ~s.

\$\endgroup\$
0
\$\begingroup\$

Charcoal, 15 bytes

UMθ⟦↨Eι℅λ¹ι⟧⊟⌊θ

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

UMθ⟦↨Eι℅λ¹ι⟧

Calculate the sum of ASCII values for each string.

⊟⌊θ

Output the string with the smallest sum.

\$\endgroup\$
0
\$\begingroup\$

PowerShell Core, 55 bytes

($args|Sort-Object{"$($_|% t*y|%{'+',+$_[0]})"|iex})[0]

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Pyth, 6 bytes

.msCMb

Try it online!

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

Husk, 2 bytes

◄Σ

Try it online!

◄     # minlon: Element that minimizes function result
 Σ    # chrsum: Sum of code points
\$\endgroup\$
0
\$\begingroup\$

BQN, 15 14 bytes

⊑∘⍋∘(+´¨-⟜@)⊑⊢

Try it at BQN REPL

⊑∘⍋∘(+´¨-⟜@)⊑⊢
    (  ¨    )       # for each element of input
        -⟜@         #   subtract the null character from each letter
                    #   (thereby getting codepoint values)
     +´             #   and sum by fold-addition
⊑∘                  # now get the first element of 
  ⍋∘                # the indices of sorted elements
             ⊑      # and use this to select from
              ⊢     # the elements of the input
\$\endgroup\$
0
\$\begingroup\$

Perl 5 + -pl, 49 bytes

($_)=sort{unpack($x="%32A*",$a)-unpack$x,$b}$_,<>

Try it online!

Explanation

sorts a list of the current input ($_) and the remaining lines of input (<>) based on the value of unpacking the string using "exotic templates", having the first index of the result re-assigned to $_ to be implicitly -printed.

\$\endgroup\$
0
\$\begingroup\$

Scala 3, 34 bytes

 _.minByOption(_.map(_.toInt).sum)

Attempt This Online!

\$\endgroup\$

Your Answer

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

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