将单词中的字母“相加”


17

我父亲是一位退休的老师,他经常提供拼写和数学测验的组合,学生可以在其中拼写一个单词,然后通过将字母加起来(其中a = 1,b = 2等)来“打分”该单词。 (例如cat = 3 + 1 + 20 = 24)。这使对测验进行评分变得更加容易,因为他只需要检查“分数”而不是拼写错误的单词即可,并且具有一次测试2个技能的额外好处。

他雇用了我的一个朋友来编写一个程序,该程序可以为他打分,因此他可以生成冗长的答案键而不会出错。该问题是受该程序启发的。

要求:

  1. 接受任何带有大写和小写字母的单词
  2. 返回任何特殊字符的错误,例如空格,连字符,@ ^%#等。
  3. a = 1,b = 2,...和A = 1,B = 2,...
  4. 打印单词的分数
  5. (可选)在计分后检查单词是否在字典中,如果不是,则打印警告。
  6. 无需导入外部字母->数字字典。您必须自己生成它。

任何语言都是可以接受的。这类似于“ 数字根战 ”,但要简单得多。


2
这应该是打码高尔夫吗?
彼得·泰勒

2
@Zach使用code-golf标签。
Lowjacker 2011年

2
您父亲有没有教过“我在E之前的我,除了C之后的”规则?
弥敦道·美林

2
是的,只检查分数?我把猫拼成aaaaaaaaaaaaaaaaaaaaaaaa。爸爸:分数是24?那就对了!
ericw31415

3
@ ericw31415每个哈希函数都有冲突;-)。到目前为止,他的任何学生都没有尝试过这种攻击媒介
扎克

Answers:



10

Brainf ***(100)

>+[>,---------]<[<]>>
[--------------------
---------------------
-------------->]<[[[<
]>+[>]<->]<<]>-.

我必须承认,这并不完全符合所有要求。首先,它仅接受大写字母,并且该单词必须以制表符结尾。对于无效字符,它具有未定义的行为,并且不会引发错误。它将字母的总和显示为ASCII字符。例如,如果单词是“ HELLO”,(8 + 5 + 12 + 12 + 15 = 52),它将显示字符“ 4”,它是52的ASCII字符。这也意味着程序在总和超过255。

但是除此之外,它还可以。休息一下,我的大脑只能承受小剂量的...嗯,你知道的。


为什么用制表符而不是换行符结尾单词?
Lowjacker 2011年

@Lowjacker因为我以为TAB是不是担心更简单\n\r\n\n\r。而且,如果我使用换行符,我将没有一个很好的整数,例如100作为字符数。
彼得·奥尔森

如果服用大剂量会怎样?
Mateen Ulhaq,2011年

8

巨蟒(65 64)

print sum(['',ord(i)-64]['@'<i<'[']for i in raw_input().upper())

如果单词包含非字母字符,但没有帮助或提示性的字符,则会引发错误。(编辑:将帽子的尖端固定在索引技巧上。)


1
print sum(['',ord(i)-64]['@'<i<'[']for i in raw_input().upper())刮了几个字符。
st0le 2011年

实际上只有一个字符。:-\
st0le 2011年

使用保存4个字符input;强制用户在输入字符串周围加上引号,但是“用户友好”和“不危险”不在规范中!
jscs 2011年

好吧,只需将其更改为Python 3!raw_inputinput
Oleh Prypin

print sum([i,ord(i)-64]['@'<i<'[']for i in raw_input().upper()) 另一个字节被剃掉了
亚历山大·尼格

8

Ruby,43个字符

$_=gets.upcase;p~/[^A-Z]/?_: $_.sum-64*~/$/

但是,生成的错误消息并不是完全有用。此处发布的两个解决方案均假设输入没有尾随换行符,因此,请使用测试它们echo -n

Ruby,76个字符,带字典检查

l=STDIN.gets;$_=l.upcase;p~/[^A-Z]/?_: $_.sum-64*~/$/;[*$<].index(l)||$><<?W

警告消息由单个字符“ W”组成。字典的路径必须通过ARGV提供。用法示例:

$ echo -n asd | ruby addletters.rb /usr/share/dict/words
24
W
$ echo -n cat | ruby addletters.rb /usr/share/dict/words
24

2
通过使错误消息成为感叹号,您可以在字典检查版本中砍掉9个字符。
彼得·奥尔森

您可以通过字典检查获得最短入场的安慰奖。要走的路!
Zach

为什么没有提出字典检查,如果它没有给您真正的优势(相反,它只会使代码blo肿)?
助手方法

5

Python 2.6(72个字符),无字典检查

print sum(map(" abcdefghijklmnopqrstuvwxyz".index, raw_input().lower()))

带有字典检查功能的Python 2.6(178个字符*)

w=raw_input().lower()
print sum(map(" abcdefghijklmnopqrstuvwxyz".index, w))
if w not in open('/usr/share/dict/american-english').read().split():
 print('Word not in dictionary')

*可以将其降低到156,并显示一条不太有用的错误消息。:-)

感谢所有评论者帮助改善此问题。


您可能要考虑将sum内建函数与生成器表达式一起使用,而不是与for循环一起使用。这样可以减少一些字符(〜17)。

@jloy:感谢您指出这一点。
约翰

可以消除打印上的括号
st0le 2011年

似乎您a只使用了一次,所以使用文字本身... "0abc....z".index(i)将等效地工作。
st0le 2011年

0你的得分数组是聪明的,但它也意味着cat0没有错误,这是不正确的接受,我想。太糟糕了,因为它将允许您传递map(a.index,w)sum(以ast0le表示的文字替换)。

4

Perl (52)(48)

多亏了Timwi才打高尔夫球

perl -lpe "($w=uc)=~/[^A-Z]/&&die;$w=~s/./$_-=64-ord$&/ge"


您在-e那儿错过了国旗。
Lowjacker 2011年

1
您至少应在字符数中包含pl解释器标志。请参阅有关meta的讨论
Ventero 2011年

syntax error at -e line 1, near "(=" Execution of -e aborted due to compilation errors.我究竟做错了什么?
用户未知

如果您在Unix上运行,请将双引号更改为单引号
chinese perl goth

@Timwi:'接受任何包含大写和小写字母的单词'进入了错误的线程,对不起。我现在删除了。@chinese:是的,谢谢,单引号没关系。只要我限制自己输入ascii。:)
未知用户

4

巨蟒(80)

w=raw_input().lower()
s=0
for l in w:s+=range(97,123).index(ord(l))+1
print s

Python v2(65,但char`将被接受)

print sum(map(range(96,123).index,map(ord,raw_input().lower())))

v3(60个字符,@将被接受,但不计算在内,谢谢jloy)

print sum(map(range(64,91).index,map(ord,input().upper())))

提示:有一种方法可以从您的解决方案中删除更多的字符。:)

2
@jloy多么有用的“提示”。;)
Mateen Ulhaq

4

Scala:59个字符,其中7个有效载荷,无字典:

(0/:"Payload".map(c=>if(c.isLetter)(c-'A')%32 else-999))(_+_)
67

到目前为止没有字典。负结果表示:负!

(0/:"Pay!wall?".map(c=>if(c.isLetter)(c-'A')%32 else-999))(_+_)   
-1915

顺便优雅地处理德国Umlaute:

(0/:"Müllrößchen".map(c=>if(c.isLetter)(c-'A')%32 else-999))(_+_)
155

哇,字符数少于Perl版本(而且可读性更高)。
Helper Method

我尝试了SHiNKiROUs和chinesis-Perl解决方案,但它们对我没有用。将它们另存为,alpha.pl并以开始perl alpha.pl。他们只是处理Ascii吗?好吧-在Perl就是这么古老的野兽... :)
用户不知道

Perl和Unicode非常混乱。您可能必须以perl -M5.010 alpha.pl类似方式运行它们。
Peter Taylor

听说在Linux上我需要单引号而不是双引号,这很有效,谢谢。
用户未知

4

Java + Google Guava库,347个字符,带有字典检查

无法读取的1个长字符串版本:-)

import java.io.*;import com.google.common.base.*;import com.google.common.io.*;class C{public static void main(String[]a)throws Exception{int s=0;for(int c:a[0].toUpperCase().toCharArray()){assert(c>64&&c<91);s+=c-64;}String d=Files.toString(new File(a[1]),Charsets.UTF_8);if(StringUtils.containsIgnoreCase(d,a[0]))System.out.println("w");System.out.println(s);}}

易于阅读的版本(:-)

import java.io.*;

import com.google.common.base.*;
import com.google.common.io.*;

class C {
    public static void main(String[] a) throws Exception {
        int s=0;

        for(int c : a[0].toUpperCase().toCharArray()) {
            System.out.println(c);
            assert(c > 64 && c < 91);
            s += c - 64;
        }

        String d = Files.toString(new File(a[1]), Charsets.UTF_8);

        if (d.contains(a[0])) System.out.println("w");

        System.out.println(s);
    }
}

现在,通过传递了字典路径a[1],为了使断言起作用,您必须使用-ea标志(+3个以上的字符)。至于字典,已使用字典/usr/share/dict/words(在大多数* nix系统上应该可用)。


到目前为止,您是唯一接受字典检查的人,因此+1
Zach

一条线?这种方式不是特别可读,尽管我猜它可以节省字符
Nate Koppenhaver

我将添加一个更具可读性的解决方案(以及使用Google Guava减少样板代码的简短解决方案)。
Helper Method

您只允许使用ascii,但使用Charset.UTF-8?
用户未知

1
因为String UTF-8比其他字符集短:-)。
辅助方法

4

Python 3,95个字符,带字典

d=input().lower()
print(d in open("d").read()and sum(['',ord(c)-96]['`'<c<'{']for c in d)or'f')

字典必须在名为d的文件中。

Python 3,61,没有字典,但主意被盗

print(sum(['',ord(c)-96]['`'<c<'{']for c in input().lower()))

3

佩尔(71)

($a)=lc<>;$a=~/[^a-z]/i&&die;$x+=ord$_ for split//,$a;die$x-96*length$a;

3

VB.NET,84 82 73 71

Console.Write(Console.ReadLine.Sum(Function(c)Asc(Char.ToUpper(c))-64))


编辑:验证为:

Dim r=Console.ReadLine
Console.Write(If(r.All(AddressOf Char.IsLetter),r.Sum(Function(c)Asc(Char.ToUpper(c))-64),"Invalid input."))

129个字符。在这种情况下:

C#,118

var r=Console.ReadLine();Console.Write(r.All(char.IsLetter)?r.Sum(c=>char.ToUpper(c)-64).ToString():"Invalid input.");

1
这不会验证输入。
Lowjacker 2011年

糟糕!稍等...
Ry- 2011年

3
我认为您应该提供完整的程序。您的C#解决方案无法编译;您需要将其放在类声明内的Main方法中,并计算所有字符。
Timwi

1
不,因为该代码无法执行任何操作,并且对弱于使用面向对象语言的用户不公平。无论如何,这是有效的C#/ VB.NET。
Ry- 2011年

3

略微提高了约翰的答案:Python(90)

s=0
for i in raw_input().lower():
 s+=("abcdefghijklmnopqrstuvwxyz".index(i)+1)
print(s)

2
在字符串开头添加虚拟字符的时间较短...可以删除括号
st0le 2011年

3

Erlang,104岁

a()->
a(string:to_lower(io:get_line([])),0).
a([_|[]],S)->
S;
a([C|R],S) when C<${, C>=$`->
a(R,S+C-$`).

3

Golfscript - 39 chars

n%~{.96>{96}{64}if-..26>\0<|{0/}*}%{+}*

The error it throws is not exactly the best, but hey, it aborts execution.


I don't know anything about golfscript, so I'm going to assume this meets the requirements and declare you the winner!
Zach

Whoops, you've been beat! I guess 2 days isn't long enough to wait on a code golf question?
Zach

3

PYTHON 62 68* Characters

print sum(map(chr,range(65,91)).index(c)+1 for c in input().upper())

Requires user to input strings using quotes, and is not safe (input executes code), but, as I said in a comment to another post, "user-friendly" and "not a security risk" ain't in the spec!


* I forgot about print, dammit.


jloy's answer is still shorter, actually, because of the input/raw_input difference.
jscs

2

Ruby 1.9, 69

w=gets.chop.upcase
w[/[^A-Z]/]&&fail
p w.bytes.inject(0){|s,b|s+b-64}

Does only handle ascii characters. I thought Ruby is from our century? :)
user unknown

@user unknown: The spec doesn't say it has to. Doing it would be rather complicated...
Lowjacker

2

GolfScript, 50(53)

Gives an error on bad characters, but not a very good one (50 characters):

);[{""123,97>+91,65>+?}/].-1?0<{{26%1+}%{+}*}{@}if

Gives "E" on error instead (53 characters):

);[{""123,97>+91,65>+?}/].-1?0<{{26%1+}%{+}*}{;"E"}if

The alphabet-generating snippet 123,97>+ is stolen from Ventero .


2

J (55)

+/64-~-&32`]@.(<&97)`_:@.(<&65)`_:@.(>&122)"0,I.a.&e."0

This satisfies all the conditions except the dictionary one. As an error condition, it returns "infinity" (the underscore symbol in J) for words that contain anything but letters.


2

Haskell (127)

(raises an error on weird characters)
(also: the space between toUpper. and \x is needed otherwise it parses it as(toUpper) .\ (x))

import Char
main=getLine>>=putStrLn.show.sum.(map$(-65+).ord.toUpper. \x->if x`elem`['A'..'Z']++['a'..'z']then x else error"")

Haskell (70)

(does not raise an error, but 45% shorter)

import Char
main=getLine>>=putStrLn.show.sum.(map$(-65+).ord.toUpper)

2

C++ (111 107)

void main(){int a=0;s8*b=new s8[99];for(cin>>b;*b;)if(isalpha(*b))a+=tolower(*b++)-96;else return;cout<<a;}

The "set up"/etc:

#include <iostream>
#include <cstdio>
#include <cctype>

#ifdef _MSC_VER
    typedef __int8 s8;
#else
    typedef signed char s8;
#endif

"Undefined" behavior (It's more 'bad practice' than 'undefined', but oh well):

  • void main() That says it all.
  • I'm using new without delete.

1

JavaScript 1.8, 80 chars

Surprisingly readable!

alert(Array.reduce(prompt().toLowerCase(),function(a,b)a+b.charCodeAt(0)-96,0))

For use in Chrome I had to convert it a little: alert(prompt().toLowerCase().split("").reduce(function(a,b){return a+b.charCodeAt(0)-96},0)). I still like JavaScript solutions most :)
pimvdb

It doesn't return an error when you do invalid character???
ericw31415

1

APL (34)

+/{⍵∊⍳26:⍵}¨{64-⍨A-32×96<A←⎕UCS⍵}⍞

Gives either the score, or a VALUE ERROR if there are non-alphabetic characters in the input.

Explanation:

  • : read a line of input
  • {...}: function applied to every character of input
  • A←⎕UCS⍵: store the ASCII value of the current character in A
  • A-32×96<A: make character uppercase: from A is subtracted 32 if 96<A (so, if it's uppercase), otherwise 0
  • 64-⍨: subtract 64 from this, giving A=1, B=2 ...
  • ¨: apply this function to every character:
  • ⍵∊⍳26: if the character is between 1 and 26...
  • :⍵: then return ⍵ (and since there's no else clause there will be a VALUE ERROR if it's not between 1 and 26)
  • +/: sum all the values together (and this value is automatically outputted because it's the final result).

1

JavaScript, 60 bytes

s=>[...s.toUpperCase()].reduce((a,b)=>a+b.charCodeAt()-64,0)

If the program must return an error on invalid inputs, then 80 bytes:

s=>/[^a-z]/i.test(s)?_:[...s.toUpperCase()].reduce((a,b)=>a+b.charCodeAt()-64,0)

If an input is invalid, then the console will say that _ is not defined (there must not already be a variable defined called _).


1

Python 3, 58 55

print(sum(ord(x)%32for x in input()if x.isalpha()or z))

without dictionary or stolen idea but still unhelpful error ;)

thx @Eᴀsᴛᴇʀʟʏ

Test here.


I think you can save a byte by switching to python 2 and doing print<SPACE>sum(ord(......., removing the 2 parentheses around the expression.
Rɪᴋᴇʀ

@EᴀsᴛᴇʀʟʏIʀᴋ that is right but than the input has to be in parenthesis and I don't want to promote python 2 ;)
Alexander Nigl

PYTHON 2 IS LIFE!! and also, I don't think that would require the input to be parenthesized?
Rɪᴋᴇʀ

@EᴀsᴛᴇʀʟʏIʀᴋ sry i meant quoted. input() in python3 is raw_input() in python2
Alexander Nigl

oh, I forgot. Hm.
Rɪᴋᴇʀ

1

C, 98 bytes

 int a(char *s){int b=0;while(*s){if(!isalpha(*s))throw 1;b+=(toupper(*(s++))-64);}printf("%d",b);}

1

F# (no validation) 79 57 chars

let a w=w|>Seq.fold(fun a b->a+(int b)-65)0|>printfn"%i"

1

C# with validation: 108 chars (with 12 for error message):

var s=Console.ReadLine();Console.Write(s.All(Char.IsLetter)?s.Sum(x=>x&'_'-'@').ToString():"Invalid input");

C# without validation: 60 53 chars:

Console.Write(Console.ReadLine().Sum(x=>x&'_'-'@'));

1
In the second one without validation, you can reduce the characters even more by removing the s variable declaration and using Console.ReadLine() inline.
hermiod

1

Perl (42 31)

perl -F -pale '$c+=ord(uc$_)-64for@F;$_=$c'

I hope counting F, p, a and l as 1 character was correct.


1

JavaScript, 68 Bytes

This can almost certainly be golfed more

w=>[...w.toLowerCase()].map(v=>v.charCodeAt()-96).reduce((a,b)=>a+b)

With dictionary check (Node.js & Unix Descendants only) 195 Bytes

Uses /usr/share/dict/words, and can definitely be shortened (see the warn message)

w=>(require("fs").readFile("/usr/share/dict/words",(e,t)=>!(t+"").split`
`.includes(w=w.toLowerCase())&&console.warn(w+" not found in dict")),[...w].map(v=>v.charCodeAt()-96).reduce((a,b)=>a+b))

For an error message, you do console.error(), not console.warn().
ericw31415

But the challenge said to warn (5. (Optional) check that the word is in a dictionary after scoring, and print a warning if it is not.) Don't mean to be pedantic, but the challenge specified a warning
MayorMonty

@SpeedyNinja I think it still counts, that isn't really the point of the challenge...
Rɪᴋᴇʀ

@EᴀsᴛᴇʀʟʏIʀᴋ it is 1 character shorter ;)
MayorMonty

@SpeedyNinja You're right, I misread.
ericw31415
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.