'Adicione' as letras em uma palavra

17

Meu pai é um professor aposentado e costumava fazer testes combinados de ortografia e matemática, nos quais o aluno escrevia uma palavra e depois 'pontuava' a palavra somando as letras, onde a = 1, b = 2, etc. (por exemplo, gato = 3 + 1 + 20 = 24). Isso facilitou a classificação dos questionários, pois ele precisaria apenas verificar "pontuações" incorretas em vez de palavras escritas incorretamente, além de ter o benefício adicional de testar duas habilidades de uma só vez.

Ele contratou um amigo meu para escrever um programa que classificasse palavras para ele, para que ele pudesse gerar chaves de resposta longas sem erros. Esse problema é inspirado nesse programa.

Requisitos:

  1. Aceite qualquer palavra com letras maiúsculas e minúsculas
  2. Retorna um erro para qualquer caractere especial, como espaços, hífens, @ ^% # etc.
  3. a = 1, b = 2, ... e A = 1, B = 2, ...
  4. Imprima a pontuação da palavra
  5. (Opcional) verifique se a palavra está em um dicionário após a pontuação e imprima um aviso, se não estiver.
  6. Não é possível importar um dicionário externo de letras-> números. Você deve gerá-lo você mesmo.

Qualquer idioma é aceitável. Isso é semelhante à ' batalha raiz digital ', mas muito mais simples.

Zach
fonte
2
Isso deveria ser um código de golfe?
Peter Taylor
2
@Zach Usando a code-golftag.
Lowjacker
2
Seu pai se deu ao trabalho de ensinar a regra "eu antes de E, exceto depois de C"?
Nathan Merrill
2
Sim, apenas verificando pontuações? Eu soletraria gato como aaaaaaaaaaaaaaaaaaaaaaaa. Pai: A pontuação é 24? Está certo!
Ericw31415
3
@ ericw31415 Toda função de hash tem colisões ;-). Até agora nenhum dos seus alunos têm tentado que vetor de ataque
Zach

Respostas:

8

Golfscript - 23 caracteres

0\{.31&.(.26%=@64///+}/

Verifique se não há novas linhas à direita na entrada (por exemplo, uso echo -n).

Nabb
fonte
Temos um novo vencedor!
Zach
Geralmente, a filtragem externa deve ser incluída na contagem de caracteres de alguma forma (filtragem externa Ctrl-f.), Embora eu assuma que sejam apenas dois caracteres extras para ficar sem.
precisa
2
@ Jessie: echo -nrealmente não conta como filtro externo - na verdade, a resposta que você vinculou sugere que é um formulário válido para entrada.
Nabb 27/04
10

Brainf *** (100)

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

Eu tenho que admitir, porém, isso não está de acordo com todos os requisitos. Primeiro, ele aceita apenas letras maiúsculas e a palavra deve ser finalizada com uma guia. Tem um comportamento indefinido para caracteres inválidos e não gera um erro. Ele exibe a soma das letras como um caractere ASCII. Por exemplo, se a palavra for "HELLO", (8 + 5 + 12 + 12 + 15 = 52), ele exibirá o caractere "4", que é o caractere ASCII para 52. Isso também significa que o programa enlouquece quando a soma é superior a 255.

Mas, fora isso , funciona muito bem. Dá um tempo, meu cérebro só aguenta pequenas doses de ... bem, você sabe.

Peter Olson
fonte
Por que terminar a palavra com uma guia em vez de uma nova linha?
precisa saber é o seguinte
@ Lowjacker Porque eu assumi TAB é mais simples do que se preocupar com \nou \r\nou \n\r. E se eu usasse a nova linha, não teria um número redondo agradável como 100 como a contagem de caracteres.
31811 Peter Olson
O que aconteceria se você recebesse uma dose grande?
Mateen Ulhaq
8

Python ( 65 64)

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

Isso gera um erro se a palavra contiver caracteres que não sejam da letra, mas não útil ou informativa. (Edit: ponta do chapéu para st0le para o truque de indexação.)


fonte
11
print sum(['',ord(i)-64]['@'<i<'[']for i in raw_input().upper())raspou um par de caracteres.
st0le
Apenas um char na verdade. : - \
st0le
Salve 4 caracteres usando input; força o usuário a colocar aspas nas seqüências de caracteres de entrada, mas "fácil de usar" e "não perigoso" não estão na especificação!
JSCs
Bem, basta alterá-lo para Python 3! raw_inputinput
Oleh Prypin
print sum([i,ord(i)-64]['@'<i<'[']for i in raw_input().upper()) outro byte raspada
Alexander Nigl
8

Ruby, 43 caracteres

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

A mensagem de erro que isso gera não é exatamente útil, no entanto. As duas soluções postadas aqui assumem que a entrada não possui quebra de linha à direita; portanto, para testá-las, use echo -n.

Ruby, 76 caracteres com verificação de dicionário

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

A mensagem de aviso consiste no caractere único "W". O caminho para o dicionário deve ser fornecido via ARGV. Exemplo de uso:

$ echo -n asd | ruby addletters.rb /usr/share/dict/words
24
W
$ echo -n cat | ruby addletters.rb /usr/share/dict/words
24
Ventero
fonte
2
Você pode cortar 9 caracteres na versão de verificação do dicionário, transformando a mensagem de erro em um ponto de exclamação.
27611 Peter Olson
Você recebe um prêmio de consolação pela entrada mais curta com uma verificação no dicionário. Caminho a percorrer!
Zach
Por que a verificação do dicionário foi proposta se não lhe deu nenhuma vantagem real (pelo contrário, apenas inchado o código)?
método auxiliar
5

Python 2.6 (72 caracteres) Sem verificação de dicionário

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

Python 2.6 (178 caracteres *) Com verificação de dicionário

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')

* Pode ser reduzido para 156 com uma mensagem de erro menos útil. :-)

Obrigado a todos os comentaristas por ajudarem a melhorar isso.

John
fonte
Você pode considerar o uso do sumbuilt-in com uma expressão de gerador, em vez de um forloop. Isso permitiria que você aparasse alguns caracteres (~ 17).
@ jloy: Obrigado por apontar isso.
John
os parênteses na impressão pode ser eliminado
st0le
parece que você está usando aapenas uma vez, então use o literal em si ... "0abc....z".index(i)funcionará de forma equivalente.
st0le
O 0em sua matriz de pontuação é inteligente, mas também significa que cat0é aceito sem erros, o que não está certo, eu acho. O que é muito ruim, pois permitiria passar map(a.index,w)para sumele (substituindo o literal por ast0le).
4

Perl (52) (48)

jogou ainda mais graças a Timwi

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

gótico chinês do perl
fonte
Você está perdendo a -ebandeira lá.
Lowjacker
11
Você deve incluir pelo menos os sinalizadores pe lintérprete na sua contagem de caracteres. Veja esta discussão no meta.
Ventero
syntax error at -e line 1, near "(=" Execution of -e aborted due to compilation errors.O que estou fazendo de errado?
usuário desconhecido
se você estiver executando no UNIX, mudança duplo aspas para os solteiros
perl chineses goth
@ Timwi: 'Aceite qualquer palavra com letras maiúsculas e minúsculas' foi para o tópico errado, desculpe. Eu o apaguei agora. @chinese: Sim, obrigado, com aspas simples tudo bem. Contanto que eu me restrinja à entrada ascii. :)
usuário desconhecido
4

Python (80)

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

Python v2 (65, mas char `será aceito)

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

v3 (60 caracteres, @ serão aceitos, mas não contados, obrigado jloy)

print sum(map(range(64,91).index,map(ord,input().upper())))
OneOfOne
fonte
DICA: HÁ UMA MANEIRA DE REMOVER MAIS UM CARRO DE SUAS SOLUÇÕES. :)
2
@jloy Que 'dica' útil. ;)
Mateen Ulhaq
4

Scala: 59 caracteres, 7 deles carga útil, sem ditado:

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

Nenhum dicionário até agora. Resultado negativo significa: Negativo!

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

Manipula alemão Umlaute graciosamente, a propósito:

(0/:"Müllrößchen".map(c=>if(c.isLetter)(c-'A')%32 else-999))(_+_)
155
Usuário desconhecido
fonte
Uau, menos caracteres que a versão Perl (e ainda mais legível).
Helper Method
Tentei SHiNKiROUs e chinês-Perl-solution, mas eles não funcionaram para mim. Salvei-os como alpha.ple iniciei-os por perl alpha.pl. Eles apenas lidam com Ascii? Bem - no Perl é um animal tão antigo ... :)
user unknown
Perl e Unicode é uma grande bagunça. Você provavelmente tem que executá-los como perl -M5.010 alpha.plou algo assim.
22411 Peter
Ouvi dizer que preciso de aspas simples em vez de aspas duplas no Linux, e isso funcionou, obrigado.
usuário desconhecido
4

Bibliotecas Java + Google Guava, 347 caracteres, com verificação de dicionário

Versão ilegível de 1 string longa :-)

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);}}

Versão legível por humanos (mais ou menos :-))

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);
    }
}

O caminho do dicionário agora é transmitido via a[1], para que as afirmações funcionem, você precisa usar a -eabandeira (mais 3 caracteres). Quanto ao dicionário, o dict /usr/share/dict/words(deve estar disponível na maioria dos sistemas * nix) foi usado.

Método auxiliar
fonte
Até agora, você é o único com uma verificação de dicionário. +1
Zach
uma linha? isso não é particularily legível desta forma, embora eu acho que ele salva caracteres
Nate Koppenhaver
Vou adicionar uma solução mais legível (e também uma mais curta, usando o Google Guava para reduzir o código padrão).
Método ajudante
Você apenas permite ascii, mas usa Charset.UTF-8?
usuário desconhecido
11
Porque a String UTF-8é mais curta que os outros charsets :-).
Helper Method
4

Python 3, 95 caracteres com dicionário

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

O dicionário deve estar em um arquivo chamado d.

Python 3, 61 sem dicionário, mas ideia roubada

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

Perl (71)

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

VB.NET, 84 82 73 71

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


Edit: Com a validação é:

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

129 caracteres. Nesse caso:

C #, 118

var r=Console.ReadLine();Console.Write(r.All(char.IsLetter)?r.Sum(c=>char.ToUpper(c)-64).ToString():"Invalid input.");
Ry-
fonte
11
Isso não valida a entrada.
Lowjacker
Opa! Espere um segundo ...
Ry-
3
Eu acho que você deve fornecer programas completos. Sua solução C # não compila; você precisa colocá-lo em um método Main dentro de uma declaração de classe e contar todos os caracteres.
Timwi
11
Não, porque esse código não faz nada e não é justo prejudicar os usuários de linguagens orientadas a objetos. Isso é válido em C # / VB.NET de qualquer maneira.
Ry-
3

Melhorando um pouco a resposta de John: Python (90)

s=0
for i in raw_input().lower():
 s+=("abcdefghijklmnopqrstuvwxyz".index(i)+1)
print(s)
Zach
fonte
2
adicionando o caractere manequim no início string é mais curtas ... parênteses pode ser removido
st0le
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-$`).
xymostech
fonte
3

Golfscript - 39 caracteres

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

O erro que ele lança não é exatamente o melhor, mas interrompe a execução.

Juan
fonte
Eu não sei nada sobre golfscript, então vou assumir que isso atende aos requisitos e declarar o vencedor!
Zach
Opa, você foi derrotado! Eu acho que 2 dias não é o suficiente para esperar uma pergunta sobre código de golfe?
Zach
3

PYTHON 62 68 * Personagens

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

Requer que o usuário insira seqüências de caracteres usando aspas e não é seguro ( inputexecuta o código), mas, como eu disse em um comentário em outro post, "amigável" e "sem risco de segurança" não estão na especificação!


* Eu esqueci print, caramba.

jscs
fonte
A resposta de jloy é ainda mais curta, na verdade, devido à diferença input/ raw_input.
JSCs
2

Rubi 1.9, 69

w=gets.chop.upcase
w[/[^A-Z]/]&&fail
p w.bytes.inject(0){|s,b|s+b-64}
Lowjacker
fonte
Lida apenas com caracteres ascii. Eu pensei que Ruby é do nosso século? :)
usuário desconhecido
@ usuário desconhecido: a especificação não diz que precisa. Fazê-lo seria bastante complicado ...
Lowjacker
2

GolfScript, 50 (53)

Dá um erro em caracteres ruins, mas não muito bom (50 caracteres):

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

Dá "E" por erro (53 caracteres):

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

O snippet gerador de alfabeto 123,97>+é roubado do Ventero.

Jesse Millikan
fonte
2

J (55)

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

Isso satisfaz todas as condições, exceto a do dicionário. Como condição de erro, ele retorna "infinito" (o símbolo de sublinhado em J) para palavras que contenham apenas letras.

Gregory Higley
fonte
2

Haskell (127)

(gera um erro em caracteres estranhos)
(também: o espaço entre toUpper.e \xé necessário, caso contrário, ele será analisado como (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)

(não gera um erro, mas 45% menor)

import Char
main=getLine>>=putStrLn.show.sum.(map$(-65+).ord.toUpper)
marinus
fonte
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;}

O "configurar" / etc:

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

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

Comportamento "indefinido" (é mais 'má prática' do que 'indefinido', mas tudo bem):

  • void main() Isso já diz tudo.
  • Estou usando newsem delete.
Mateen Ulhaq
fonte
1

JavaScript 1.8, 80 caracteres

Surpreendentemente legível!

alert(Array.reduce(prompt().toLowerCase(),function(a,b)a+b.charCodeAt(0)-96,0))
Casey Chu
fonte
Para uso no Chrome eu tinha para convertê-lo um pouco: alert(prompt().toLowerCase().split("").reduce(function(a,b){return a+b.charCodeAt(0)-96},0)). Eu ainda gosto soluções JavaScript mais :)
pimvdb
Não retorna um erro quando você faz caractere inválido ???
Ericw31415
1

APL (34)

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

Dá a pontuação ou a VALUE ERRORse houver caracteres não alfabéticos na entrada.

Explicação:

  • : lê uma linha de entrada
  • {... }: função aplicada a todos os caracteres da entrada
  • A←⎕UCS⍵: armazene o valor ASCII do caractere atual em A
  • A-32×96<A: torna o caractere em maiúsculas: de Aé subtraído 32 se 96<A(então, se estiver em maiúsculas), caso contrário 0
  • 64-⍨: subtraia 64 disso, dando A = 1, B = 2 ...
  • ¨: aplique esta função a todos os caracteres:
  • ⍵∊⍳26: se o caractere estiver entre 1 e 26 ...
  • :⍵: então retorne ⍵ (e como não há mais cláusula, haverá um VALUE ERRORse não estiver entre 1 e 26)
  • +/: soma todos os valores (e esse valor é gerado automaticamente porque é o resultado final).
marinus
fonte
1

JavaScript, 60 bytes

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

Se o programa precisar retornar um erro em entradas inválidas, 80 bytes:

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

Se uma entrada for inválida, o console dirá que _não está definido (ainda não deve haver uma variável definida chamada _).

ericw31415
fonte
1

Python 3, 58 55

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

sem dicionário ou idéia roubada, mas ainda erro inútil;)

thx @ Eᴀsᴛᴇʀʟʏ

Teste aqui .

Alexander Nigl
fonte
Eu acho que você pode salvar um byte alternando para python 2 e fazendo print<SPACE>sum(ord(......., removendo os 2 parênteses em torno da expressão.
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ que é certo, mas que a entrada tem que ser entre parênteses e eu não quero promover python 2;)
Alexander Nigl
PYTHON 2 É VIDA !! e também, acho que não exigiria que a entrada fosse entre parênteses?
Rɪᴋᴇʀ
@ EᴀsᴛᴇʀʟʏIʀᴋ sry eu quis dizer citado. input()em python3 está raw_input()em python2
Alexander Nigl 8/16
Oh, eu esqueci. Hum.
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);}
Adam Spindler
fonte
1

F # (sem validação) 79 57 caracteres

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

C # com validação: 108 caracteres (com 12 para mensagem de erro):

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

C # sem validação: 60 53 caracteres:

Console.Write(Console.ReadLine().Sum(x=>x&'_'-'@'));
driis
fonte
11
No segundo sem validação, você pode reduzir ainda mais os caracteres removendo a declaração da variável s e usando o Console.ReadLine () em linha.
hermiod
1

Perl (42. 31)

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

Espero que contar F, p, a e l como 1 caractere esteja correto.

memowe
fonte
1

JavaScript, 68 bytes

Isso quase certamente pode ser jogado mais

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

Com verificação de dicionário (apenas Node.js e Descendentes Unix) 195 bytes

Usa /usr/share/dict/wordse pode ser definitivamente reduzido (veja a mensagem de aviso)

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))
MayorMonty
fonte
Para uma mensagem de erro, você faz console.error() , não console.warn().
Ericw31415
Mas o desafio dito para advertir (5. (Opcional) verifique se a palavra está em um dicionário após a pontuação e imprima uma aviso, se não estiver.) Não seja pedante, mas o desafio especificou um aviso
MayorMonty
@SpeedyNinja Acho que ainda conta, esse não é realmente o objetivo do desafio ...
305
@ EᴀsᴛᴇʀʟʏIʀᴋ é 1 caractere mais curto;)
MayorMonty 8/16
@SpeedyNinja Você está certo, eu interpretei errado.
Ericw31415