26
\$\begingroup\$

I recently decided to download some dictation software, in order to help with my writing. However, it doesn't work very well when I'm coding, since I have to change from saying words to symbols and back again. It's even worse when I'm coding in an esoteric language which is all symbols.

In order to make my use of the dictation program more consistent, I decided to switch it over to character mode, where I just say the name of each character instead. Problem solved! Though this does delay my novel's release date a little bit...

So, assuming that the longer the name of a character, the longer it takes to say, how long will it take me to spell out some of my programs/sentences?

Specifications

Given a string consisting of only printable ASCII, return the sum of each character's unicode name. For example, / is called SOLIDUS with 7 characters, and A is LATIN CAPITAL LETTER A with 22 characters.

But remember, I have to say your programs out loud to execute them, so their score will be based on how long it takes me to say them, i.e. as the sum of the lengths of each character's unicode name.

Test Cases:

In format input => output with no trailing/leading spaces in input.

A      => 22
/      => 7
Once upon a time...           => 304
slurp.uninames>>.comb.sum.say => 530
JoKing => 124
!" #$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~        =>  1591
Double-check your \s on the last test case ;)   => 755
<say "<$_>~~.EVAL">~~.EVAL     => 388
,[.,]  => 58
19     => 19

Rules:

  • Input to your program will only consist of printable ASCII characters, that is, the codepoints 32 (space) to 126 (tilde).
    • For convenience sake, here is the list of lengths of the characters you have to handle: [5,16,14,11,11,12,9,10,16,17,8,9,5,12,9,7,10,9,9,11,10,10,9,11,11,10,5,9,14,11,17,13,13,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,19,15,20,17,8,12,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,18,13,19,5]
  • Here is a reference program you can use to score your program.
    • Peter Taylor has pointed out that the reference program normalises some unicode characters. It should still work for most solutions, but feel free to correct it if you need
  • Since you're saying what the characters actually look like, your solution will be scored by the characters that are displayed, not the bytes involved. This is directed at languages with custom encodings.
    • You can assume that I've memorised the entire Unicode library and can say whatever strange characters you use.
  • Sorry Rogem, but answers have to be composed of displayable characters. Unprintables are fine, I just have to be able to read the characters out loud.
  • Whatever you do, do not use in your program.
\$\endgroup\$
  • 8
    \$\begingroup\$ ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM this will be the full name of my child \$\endgroup\$ – Quintec Feb 16 at 2:08
  • 1
    \$\begingroup\$ This program scores 6 in word mode: Try it online! \$\endgroup\$ – Neil Feb 16 at 15:21
  • 2
    \$\begingroup\$ The reference program is buggy. Consider [this test] (tio.run/##dY5PC4JAEMXvfYphYcNsWcrSi@Ahrx3rlB223FTSXdk/…) where \x[2126] is counted as \x[3a9]. \$\endgroup\$ – Peter Taylor Feb 20 at 18:34

11 Answers 11

13
\$\begingroup\$

Java 8, score 846 838 822 816

ௐ->ௐ.map(ˇ->Character.getName(ˇ).length()).sum()

-8 score thanks to @tsh replacing the _1 with .
-22 score thanks to @ASCII-only replacing the with ˇ and $ with .

Try it online.

Explanation:

The and ˇ are used instead of the s and c I would normally use, because lowercase letters are all 20 (i.e. LATIN SMALL LETTER S), but (TAMIL OM) is 8 and ˇ (CARON) is 5.

ௐ->                         // Method with IntStream parameter and integer return-type
  ௐ.map(ˇ->                 //  Map each character to:
      Character.getName(ˇ)  //   Get the name of the character
               .length())   //   Get the length of that name
   .sum()                   //  And after the map: sum all lengths together,
                            //  and return it as result
\$\endgroup\$
  • 1
    \$\begingroup\$ I like how this Java stuff beats the 05AB1E answer both in terms of bytes and it terms of score... \$\endgroup\$ – Erik the Outgolfer Feb 16 at 13:13
  • \$\begingroup\$ @EriktheOutgolfer Ikr. Builtins ftw I guess. ;) \$\endgroup\$ – Kevin Cruijssen Feb 16 at 15:09
  • \$\begingroup\$ @KevinCruijssen It does save a couple bytes that you don't have to push compressed integer 87235805968599116032550323044578484972930006625267106917841 :P \$\endgroup\$ – Quintec Feb 17 at 17:29
  • 1
    \$\begingroup\$ Use instead of _1 would save some points. \$\endgroup\$ – tsh Feb 20 at 8:20
  • 1
    \$\begingroup\$ @KevinCruijssen Peter Taylor's (OHM SIGN) is 8 characters long. Also haha I wasn't aware it was not valid, just assumed since it's valid in C# and Peter used _1 too (program to find short variable names, the box character can't be used) \$\endgroup\$ – ASCII-only Feb 21 at 11:04
11
\$\begingroup\$

Perl 6, score 337

+*.uninames.&[~].ords

Try it online!

\$\endgroup\$
  • \$\begingroup\$ That .&[~] instead of .join is a neat trick. I can never remember what reduction operators can be applied through that method \$\endgroup\$ – Jo King Feb 18 at 1:11
7
\$\begingroup\$

Japt v2.0a1 -x, Score 926 908 875 865 829 791 789

Takes input as an array of characters.

®cg`061742//0.450./..//.2/5117385`c+51 r\A_p26}  n# 

Try it or run all test cases on TIO

(APOSTROPHE is omitted from the 6th test case on TIO as Japt can't handle both single and double quotes in the same input string)


Explanation

®cg`...`c+51 r\A_p26}  n#      :Implicit input of character array
®                              :Map
 c                             :  Character code
  g                            :  Index into (0-based, with wrapping)
   `...`                       :    The string described below
        c+51                   :    Increment the codepoint of each by 51 (="8cKidj55gebbc9agh895c97a99baa9bba59ebhddMjfkh")
                               :    (Space closes the above method)
             r                 :    Replace
              \A               :      RegEx /[A-Z]/g
                _              :      Pass each match through a function
                 p26           :        Repeat 26 times
                    }          :      End function
                               :    (Space closes the replace method)
                               :  (Space closes the indexing method)
                       n       :  Convert to integer
                        #      :    From base 32 (note the trailing space)
                               :Implicitly reduce by addition and output

Building The String

(Scores include the steps and extra characters needed to reverse each modification)

  1. The array gave a baseline score of 2161.
  2. Converting each to a single character in a base >=23 and joining to a string scored 1832.
  3. Replacing both runs of m and k with a single, uppercase character scored 963.
  4. There were still too many expensive letters so next I tried to get rid of them by reducing the codepoints of all characters. 5 was the character with the lowest codepoint (53) so I started with 52, which scored 756
  5. After trying all numbers that would leave no letters in the string, 51 gave the best score of 738
  6. Finally, replacing the quotation marks with slightly cheaper backticks gave a score of 734. Backticks in Japt are usually used to enclose and decompress a compressed string but, luckily, none of the characters in this string are contained in Shoco's library

The final string, so, contains the characters at the following codepoints:

[5,48,24,54,49,55,2,2,52,50,47,47,48,6,46,52,53,5,6,2,48,6,4,46,6,6,47,46,46,6,47,47,46,2,6,50,47,53,49,49,26,55,51,56,53]
\$\endgroup\$
4
\$\begingroup\$

05AB1E, score 963

Îv•Fδà‚<0?9½mΣ@×ƶC₁vc-™uΔ_ε'•21вεD3‹i22α₂и}}˜yÇ32-è+

Try it online or verify all test cases.

Explanation:

Î               # Push 0 and the input-string
 v              # Loop `y` over the characters of this input-string:
  •Fδà‚<0?9½mΣ@×ƶC₁vc-™uΔ_ε'•
               '#  Push compressed integer 87235805968599116032550323044578484972930006625267106917841
   21в          #  Converted to Base-21 as list: [5,16,14,11,11,12,9,10,16,17,8,9,5,12,9,7,10,9,9,11,10,10,9,11,11,10,5,9,14,11,17,13,13,0,19,15,20,17,8,12,2,18,13,19,5]
    ε           #  Map over this list:
     D3‹i       #   If the value is smaller than 3:
         22α    #    Take the absolute difference of this value with 22
            ₂и  #    Repeat it 26 times as list
    }}          #  Close the if-statement and map
      ˜         #  Flatten the list
       yÇ       #  Get the unicode value of the current character
         32-    #  Subtract 32
            è   #  Index it into the list of integers
             +  #  And add it to the sum
                # (and output the sum implicitly as result after the loop)

See this 05AB1E tip of mine (sections How to compress large integers? and How to compress integer lists?) to understand why •Fδà‚<0?9½mΣ@×ƶC₁vc-™uΔ_ε'•21в is [5,16,14,11,11,12,9,10,16,17,8,9,5,12,9,7,10,9,9,11,10,10,9,11,11,10,5,9,14,11,17,13,13,0,19,15,20,17,8,12,2,18,13,19,5].

\$\endgroup\$
4
\$\begingroup\$

C# (Visual C# Interactive Compiler) (score 1627 1116 1096 1037 1019 902)

Ω=>Ω.Sum(ˇ=>(31&-ˇ)>5&ˇ>62?22-ˇ/91*2:"♁♌♊♇♇♈♅♆♌♍♄♅♁♈♅♃♆♅♅♇♆♆♅♇♇♆♁♅♊♇♍♉♉♏♋♐♍♄♈♎♉♏♁"[ˇ-6-ˇ/33*26]-9788)

This uses no built-in database: just some special-casing for letters and a lookup table.

Online test suite.

It can't score itself, because most of the characters are not in range, including the variables CARON and OHM SIGN and the zodiac symbols used to encode the lookup table.

Thanks to ASCII-only for many suggestions.

\$\endgroup\$
  • \$\begingroup\$ What scoring program did you use \$\endgroup\$ – ASCII-only Feb 20 at 13:52
  • \$\begingroup\$ tio.run/##NZDrdpNAFIX/z1OMY0wgwhCg0NAEanpT22jVaquGiAQnYbgMhIHWGJO36gv0xSJrBf@cdS57r72@E3A54HR3UbFgyMuCsoVEWenM7d3To@08PeKbKhU82xG2suDJdgd2xLauikPNbLc9R9eONU32FFPtakeI5CyOExrly5CShC4iSuMoonEcEcriZZryrFyGSZFygiZebdP1rmZOZcsUdwMwzwriB6Fw7xfQh5RBRh4m0zVAIyRBRYGaBpCybw8BumYBgVWesVpb0pRgjPc3vXcAEE@qIscVo8xPCXccHGTpDPMqxdxf7XWG3gPoMruqifcLVauNz1wEn7detDuC2H0pyVjpqZp@YJiHfetoMLSd41ejk9Oz84vXb95eXo3fvb/@8PHTzecvt3dfv32fuO70h/fTnwW/yHwR0ihOUpbly4KX1f3D79Wf9d/NtskyLBWgs6yaJUQOQhLEcJVVBXRdDmukMiQw8XkJS1KXwOcEDsQG3TAAGtYU0EXDludst/j8djR20f@u@UK/D5A0wdK0oa1H1WrCLbARwV1BSzKmjAgttPYly9hAaDsQrueCL26QONj9Aw \$\endgroup\$ – ASCII-only Feb 20 at 13:56
  • 2
    \$\begingroup\$ @ASCII-only, I used the Python answer below; the Java answer also gives 1627. The problem seems to be that the reference solution is buggy: Ω is U+2126, OHM SIGN, not GREEK CAPITAL LETTER OMEGA. \$\endgroup\$ – Peter Taylor Feb 20 at 14:18
  • 1
    \$\begingroup\$ Score 5 name: ˇ, no other names shorter than 8 that C# accepts, also not verified with Java program \$\endgroup\$ – ASCII-only Feb 20 at 15:34
  • 1
    \$\begingroup\$ @Kevin, as per my earlier comment the reference implementation is buggy. I think it's applying normalisation to turn the source character OHM SIGN into GREEK CAPITAL LETTER OMEGA. \$\endgroup\$ – Peter Taylor Feb 20 at 18:27
4
\$\begingroup\$

R; Score: 3330 1586 1443

Also challenging in R due to lack of built-ins.

Well the code is now mostly @Giuseppe's but that's alright. I was able to make a small edit to golf further by replacing the * with the ~, and the s with the dot.

Thanks to @Nick Kennedy for getting this down to 1443 by using arcane magic "a UTF8 encoded version of the number sequence"

function(.)sum((c(+",752230178/0,30.1002110221,052844",61~26,+":6;8/3",59~26,+"94:,")-39)[+.-31]);`+`=utf8ToInt;`~`=rep

Try it online

\$\endgroup\$
  • \$\begingroup\$ 1769 points -- makes a minimal attempt to compress the values... \$\endgroup\$ – Giuseppe Feb 20 at 1:37
  • 2
    \$\begingroup\$ also, utf8ToInt is a super helpful command for golfing :-) I haven't been on PPCG for a month or so, so it's nice to see new people golfing in R! \$\endgroup\$ – Giuseppe Feb 20 at 1:38
  • \$\begingroup\$ Ah, I had a way to compress it, but was not aware of utf8ToInt. I'll have to work on this later tonight/tomorrow. \$\endgroup\$ – CT Hall Feb 20 at 1:49
  • 1
    \$\begingroup\$ It's just more lines of code under the program/snippet that doesn't affect bytecount - useful to do some tests in \$\endgroup\$ – ASCII-only Feb 20 at 14:58
  • 1
    \$\begingroup\$ Down to 1443: tio.run/##xc09DoIwFADgu3ShTR/… Using a UTF8 encoded version of the number sequence. \$\endgroup\$ – Nick Kennedy Feb 23 at 20:54
3
\$\begingroup\$

Python 3, Score of 993

lambda _:len(''.join(map(__import__('unicodedata').name,_)))

Try it online!

Below 1000 now, any tips still appreciated.

-16 thanks to Kirill L.

\$\endgroup\$
  • 2
    \$\begingroup\$ 993 \$\endgroup\$ – Kirill L. Feb 16 at 12:21
  • \$\begingroup\$ You can replace _ by ˇ for 987. \$\endgroup\$ – Lynn Feb 21 at 21:40
3
\$\begingroup\$

C (gcc), 467 + 95 * Invalid Character

<< NON-COMPETING >>

This answer is not valid as it is, since answers must consist of named characters.

_1(char*_){_=*_?-"�����������������������������������������������������������������������������������������������"[*_-32]+_1(1+_):0;}

Try it online!

Defines a recursive function _1() that takes the string as its only argument. Replace the s with the below bytes using a hex editor.

fb f0 f2 f5 f5 f4 f7 f6
f0 ef f8 f7 fb f4 f7 f9
f6 f7 f7 f5 f6 f6 f7 f5
f5 f6 fb f7 f2 f5 ef f3
f3 ea ea ea ea ea ea ea
ea ea ea ea ea ea ea ea
ea ea ea ea ea ea ea ea
ea ea ea ed f1 ec ef f8
f4 ec ec ec ec ec ec ec
ec ec ec ec ec ec ec ec
ec ec ec ec ec ec ec ec
ec ec ec ee f3 ed fb

Degolf

The function is semantically equivalent to:

int foo(char *str){return *str?-""[*str-32]+foo(str + 1):0;}

where the string constant is a look-up table of the lengths of each printable ASCII character, stored as a negative integer.

\$\endgroup\$
  • \$\begingroup\$ I think it's very clever, but unfortunately I'm going to have to rule undisplayable bytes as invalid. Even if I didn't explicitly ban them, the premise of the challenge (reading the code out loud) would be impossible with this submission. \$\endgroup\$ – Jo King Feb 22 at 0:44
  • \$\begingroup\$ @JoKing I've marked the answer as non-competing for now. \$\endgroup\$ – user77406 Feb 22 at 6:45
  • \$\begingroup\$ @Rogem Check the C# answer for a valid lookup-based answer that's close to minimal score \$\endgroup\$ – ASCII-only Feb 22 at 10:10
  • \$\begingroup\$ @ASCII-only I'd rather not copy. Makes for very boring golfs. \$\endgroup\$ – user77406 Feb 22 at 10:13
  • \$\begingroup\$ @Rogem well... not like the lookup-based ones are that different anyway... the end result will be the same either way \$\endgroup\$ – ASCII-only Feb 22 at 10:14
2
\$\begingroup\$

Perl 5 -pl, score 723

s,\N{OX}*.,_charnames'viacode ord$&,ge,$_=y,,,c

Try it online!

Explanation

s,        ,                        ,ge  # Replace globally
  \N{OX}*   # zero or more OX characters 🐂, loads the
            # _charnames module as side effect,
         .  # any character
           _charnames'viacode ord$&  # with its Unicode character name
                                     # (using old package delimiter).
                                      ,$_=y,,,c  # Set $_ to its length
\$\endgroup\$
2
\$\begingroup\$

Attache, 1934

Sum@{ToBase[FromBase[Ords@"!ZByru=#9fBYb$a3Si0^pU,ZP#3$cd'(c-_lhu]h(]5;!W|?M4:<_^sU;N&XFN`t:u"-32,95],23][Ords@_-32]}

Try it online!

Simple compression and indexing.

\$\endgroup\$
  • \$\begingroup\$ :P looks like using a smarter lookup (see C# answer) would help with score. Or even just using a charset that doesn't contain letters to compress \$\endgroup\$ – ASCII-only Feb 22 at 10:13
1
\$\begingroup\$

C# (Visual C# Interactive Compiler), Score: 4007 3988 3759 3551 2551

ˇ=>ˇ.Sum(_=>new[]{5,16,14,11,11,12,9,10,16,17,8,9,5,12,9,7,10,9,9,11,10,10,9,11,11,10,5,9,14,11,17,13,13,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,19,15,20,17,8,12,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,18,13,19,5}[_-32])

I feel crushed by Peter Taylor's solution up above. Thanks to Peter Taylor for pointing out a simple lookup table was better than my previous dictionary solution.

Try it online!

\$\endgroup\$
  • \$\begingroup\$ This is considerably worse than a direct lookup table: _1=>_1.Select(_2=>new int[]{5,16,14,11,11,12,9,10,16,17,8,9,5,12,9,7,10,9,9,11,10,10,9,11,11,10,5,9,14,11,17,13,13,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,19,15,20,17,8,12,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,18,13,19,5}[_2-32]).Sum() scores 2786. \$\endgroup\$ – Peter Taylor Feb 20 at 12:06

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.