'Agregar' las letras en una palabra


17

Mi padre es un maestro retirado, y solía dar exámenes combinados de ortografía y matemáticas, donde el alumno deletreaba una palabra y luego 'puntuaba' la palabra sumando las letras, donde a = 1, b = 2, etc. (p. ej. cat = 3 + 1 + 20 = 24). Esto facilitó la calificación de los cuestionarios, ya que solo tendría que verificar las 'puntuaciones' incorrectas en lugar de las palabras mal escritas, y tuvo el beneficio adicional de probar 2 habilidades a la vez.

Contrató a un amigo mío para que escribiera un programa que calificara palabras para él, de modo que pudiera generar largas respuestas sin errores. Este problema está inspirado en ese programa.

Requisitos:

  1. Acepta cualquier palabra con letras mayúsculas y minúsculas
  2. Devuelve un error para cualquier carácter especial, es decir, espacios, guiones, @ ^% # etc.
  3. a = 1, b = 2, ... y A = 1, B = 2, ...
  4. Imprime el puntaje de la palabra
  5. (Opcional) verifique que la palabra esté en un diccionario después de la puntuación e imprima una advertencia si no lo está.
  6. No importa un diccionario externo de letras-> números. Debes generarlo tú mismo.

Cualquier idioma es aceptable. Esto es similar a la ' batalla raíz digital ', pero mucho más simple.


2
¿Se supone que esto es un código de golf?
Peter Taylor

2
@Zach Usando la code-golfetiqueta.
Lowjacker

2
¿Tu padre incluso se molestó en enseñar la regla "I antes de E excepto después de C"?
Nathan Merrill

2
Sí, solo revisando puntajes? Deletrearía gato como aaaaaaaaaaaaaaaaaaaaaaaa. Papá: ¿El puntaje es 24? ¡Así es!
ericw31415

3
@ ericw31415 Cada función de hashing tiene colisiones ;-). Hasta ahora ninguno de sus estudiantes ha intentado ese vector de ataque
Zach

Respuestas:


8

Golfscript - 23 caracteres

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

Asegúrese de que no haya nuevas líneas finales en la entrada (por ejemplo, uso echo -n).


¡Tenemos un nuevo ganador!
Zach

En general, se supone que el filtrado externo se incluye de alguna manera en el recuento de caracteres (Ctrl-f filtrado externo), aunque supongo que solo quedan 2 caracteres adicionales.
Jesse Millikan

2
@Jesse: echo -nrealmente no cuenta como filtrado externo; de hecho, la respuesta que vinculó lo sugiere como un formulario válido para la entrada.
Nabb

10

Brainf *** (100)

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

Sin embargo, debo admitir que esto no cumple con todos los requisitos. Primero, solo acepta letras mayúsculas, y la palabra debe terminar con una pestaña. Tiene un comportamiento indefinido para caracteres no válidos y no arroja un error. Muestra la suma de las letras como un carácter ASCII. Por ejemplo, si la palabra es "HOLA", (8 + 5 + 12 + 12 + 15 = 52) mostrará el carácter "4", que es el carácter ASCII para 52. Esto también significa que el programa se asusta cuando la suma es más de 255.

Pero aparte de eso , funciona bien. Dame un respiro, mi cerebro solo puede manejar pequeñas dosis de ... bueno, ya sabes.


¿Por qué terminar la palabra con una pestaña en lugar de una nueva línea?
Lowjacker

@Lowjacker Porque asumí que TAB es más simple que preocuparse por \no \r\no \n\r. Y si usara nueva línea, no tendría un buen número redondo como 100 como el recuento de caracteres.
Peter Olson el

¿Qué pasaría si recibiera una dosis grande?
Mateen Ulhaq

8

Pitón ( 65 64)

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

Esto genera un error si la palabra contiene caracteres que no son letras, pero no es útil o informativo. (Editar: punta del sombrero para evitar el truco de indexación).


1
print sum(['',ord(i)-64]['@'<i<'[']for i in raw_input().upper())afeitado un par de caracteres.
st0le

Solo un personaje en realidad. : - \
st0le

Guardar 4 caracteres mediante el uso input; obliga al usuario a poner comillas alrededor de las cadenas de entrada, pero "fácil de usar" y "no peligroso" no están en la especificación.
jscs

Bueno, ¡solo cámbialo a Python 3! raw_inputinput
Oleh Prypin

print sum([i,ord(i)-64]['@'<i<'[']for i in raw_input().upper()) otro byte afeitado
Alexander Nigl

8

Ruby, 43 caracteres

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

Sin embargo, el mensaje de error que esto genera no es exactamente útil. Ambas soluciones publicadas aquí suponen que la entrada no tiene salto de línea final, así que para probarlas, use echo -n.

Ruby, 76 caracteres con verificación de diccionario

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

El mensaje de advertencia consta del carácter único "W". La ruta al diccionario se debe proporcionar a través de ARGV. Ejemplo 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

2
Puede cortar 9 caracteres en la versión de verificación del diccionario haciendo que el mensaje de error sea un signo de exclamación.
Peter Olson el

Obtienes un premio de consolación por la entrada más corta con un cheque de diccionario. ¡Camino a seguir!
Zach

¿Por qué se propuso la verificación del diccionario si no le da ninguna ventaja real (por el contrario, solo hinchó el código)?
Método auxiliar

5

Python 2.6 (72 caracteres) Sin verificación de diccionario

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

Python 2.6 (178 caracteres *) con verificación de diccionario

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

* Se puede bajar a 156 con un mensaje de error menos útil. :-)

Gracias a todos los comentaristas por ayudar a mejorar esto.


Es posible que desee considerar usar el sumbuiltin con una expresión generadora, en lugar de un forbucle. Le permitiría recortar algunos caracteres (~ 17).

@jloy: Gracias por señalarlo.
John

los paréntesis en la impresión se pueden eliminar
st0le

parece que estás usando asolo una vez, así que usa el literal en sí mismo ... "0abc....z".index(i)funcionará de manera equivalente.
st0le

La 0matriz de puntuación es inteligente, pero también significa que cat0se acepta sin error, lo cual no es correcto, creo. Lo cual es una lástima, ya que le permitiría pasar map(a.index,w)en su sumlugar (sustituyendo el literal por acomo sugiere st0le).

4

Perl (52) (48)

golf aún más gracias a Timwi

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


Te estás perdiendo la -ebandera allí.
Lowjacker

1
Al menos debe incluir las banderas pe lintérprete en su recuento de caracteres. Ver esta discusión en meta.
Ventero el

syntax error at -e line 1, near "(=" Execution of -e aborted due to compilation errors.¿Qué estoy haciendo mal?
usuario desconocido el

si está ejecutando en Unix, cambie las comillas dobles a simples
chino perl goth

@Timwi: 'Aceptar cualquier palabra con mayúsculas y minúsculas' fue al hilo equivocado, lo siento. Lo eliminé ahora. @chinese: Sí, gracias, con comillas simples está bien. Mientras me limite a la entrada ascii. :)
usuario desconocido

4

Pitón (80)

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

Python v2 (65 pero char `será aceptado)

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

v3 (60 caracteres, @ serán aceptados pero no contados, gracias jloy)

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

SUGERENCIA: HAY UNA FORMA DE ELIMINAR UN CARÁCULO MÁS DE SUS SOLUCIONES. :)

2
@jloy Qué 'sugerencia' útil. ;)
Mateen Ulhaq

4

Scala: 59 caracteres, 7 de ellos carga útil, sin dict:

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

No hay diccionario hasta ahora. Resultado negativo significa: ¡Negativo!

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

Maneja el Umlaute alemán con gracia, por cierto:

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

Wow, menos caracteres que la versión de Perl (y aún más legible).
Método auxiliar

Probé SHiNKiROU y la solución de chinesis-Perl, pero no funcionaron para mí. Los guardé como alpha.ply los comencé perl alpha.pl. ¿Solo manejan Ascii? Bueno, en Perl es una bestia tan vieja ... :)
usuario desconocido

Perl y Unicode es un gran desastre. Probablemente tengas que ejecutarlos como perl -M5.010 alpha.plo algo así.
Peter Taylor

Escuché que necesito comillas simples en lugar de comillas dobles en Linux, y esto funcionó, gracias.
usuario desconocido

4

Bibliotecas Java + Google Guava, 347 caracteres, con verificación de diccionario

Versión de 1 cadena larga ilegible :-)

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

Versión legible para humanos (tipo de :-))

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

La ruta del diccionario ahora se pasa a través de a[1], para que las aserciones funcionen, debe usar la -eabandera (+3 caracteres más). En cuanto al diccionario, /usr/share/dict/wordsse ha utilizado el dict (debería estar disponible en la mayoría de los sistemas * nix).


Hasta ahora eres el único con un chequeo de diccionario, entonces +1
Zach

¿una línea? esto no es particularmente legible de esta manera, aunque supongo que ahorra caracteres
Nate Koppenhaver

Agregaré una solución más legible (y también una más corta usando Google Guava para reducir el código repetitivo).
Método auxiliar

¿Solo permite ascii, pero usa Charset.UTF-8?
usuario desconocido

1
Porque el String UTF-8es más corto que los otros conjuntos de caracteres :-).
Método auxiliar

4

Python 3, 95 caracteres con diccionario

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

El diccionario tiene que estar en un archivo llamado d.

Python 3, 61 sin diccionario, pero idea robada

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

3

Perl (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))


Editar: Con validación es:

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. En ese caso:

C #, 118

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

1
Esto no valida la entrada.
Lowjacker

¡Uy! Espera un segundo ...
Ry-

3
Creo que deberías proporcionar programas completos. Su solución C # no se compila; debe colocarlo en un método Main dentro de una declaración de clase y contar todos los caracteres.
Timwi

1
No, porque ese código no hace nada, y no es justo perjudicar a los usuarios de lenguajes orientados a objetos. Esto es válido C # / VB.NET de todos modos.
Ry-

3

Mejorando ligeramente la respuesta de John: Python (90)

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

2
añadiendo el carbón maniquí en el comienzo cadena es menor ... paréntesis se puede quitar
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-$`).

3

Golfscript - 39 caracteres

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

El error que arroja no es exactamente el mejor, pero bueno, aborta la ejecución.


No sé nada sobre golfscript, ¡así que voy a asumir que cumple con los requisitos y declararle ganador!
Zach

¡Vaya, has sido vencido! ¿Supongo que 2 días no son suficientes para esperar una pregunta de código de golf?
Zach

3

PYTHON 62 68 * Personajes

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

Requiere que el usuario ingrese cadenas usando comillas, y no es seguro ( inputejecuta el código), pero, como dije en un comentario en otra publicación, "no es fácil de usar" y "no es un riesgo de seguridad" no está en la especificación.


* Me olvidé print, maldita sea.


La respuesta de jloy es aún más corta, en realidad, debido a la diferencia input/ raw_input.
jscs

2

Ruby 1.9, 69

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

Solo maneja caracteres ascii. ¿Pensé que Ruby es de nuestro siglo? :)
usuario desconocido

@user unknown: la especificación no dice que tenga que hacerlo. Hacerlo sería bastante complicado ...
Lowjacker

2

GolfScript, 50 (53)

Da un error en los caracteres incorrectos, pero no uno muy bueno (50 caracteres):

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

Da "E" en caso de error (53 caracteres):

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

El fragmento generador de alfabeto 123,97>+es robado de Ventero.


2

J (55)

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

Esto satisface todas las condiciones excepto la del diccionario. Como condición de error, devuelve "infinito" (el símbolo de subrayado en J) para palabras que contienen cualquier cosa menos letras.


2

Haskell (127)

(genera un error en caracteres extraños)
(también: el espacio entre toUpper.y \xes necesario, de lo contrario lo analiza 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)

(no genera un error, pero es un 45% más corto)

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

La "configuración" / etc:

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

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

Comportamiento "indefinido" (es más 'mala práctica' que 'indefinido', pero bueno):

  • void main() Eso lo dice todo.
  • Estoy usando newsin delete.

1

JavaScript 1.8, 80 caracteres

Sorprendentemente legible!

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

Para su uso en Chrome tuve que convertirlo en un poco de: alert(prompt().toLowerCase().split("").reduce(function(a,b){return a+b.charCodeAt(0)-96},0)). Todavía me gustan las soluciones de JavaScript :)
pimvdb

¿No devuelve un error cuando haces un carácter no válido?
ericw31415

1

APL (34)

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

Da la puntuación o un VALUE ERRORsi hay caracteres no alfabéticos en la entrada.

Explicación:

  • : lee una línea de entrada
  • {... }: función aplicada a cada carácter de entrada
  • A←⎕UCS⍵: almacena el valor ASCII del carácter actual en A
  • A-32×96<A: hace que el carácter sea mayúscula: de Ase resta 32 si 96<A(entonces, si es mayúscula), de lo contrario 0
  • 64-⍨: resta 64 de esto, dando A = 1, B = 2 ...
  • ¨: aplica esta función a cada personaje:
  • ⍵∊⍳26: si el personaje tiene entre 1 y 26 ...
  • :⍵: luego devuelve ⍵ (y dado que no hay otra cláusula, habrá un VALUE ERRORsi no está entre 1 y 26)
  • +/: suma todos los valores juntos (y este valor se genera automáticamente porque es el resultado final).

1

JavaScript, 60 bytes

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

Si el programa debe devolver un error en entradas no válidas, entonces 80 bytes:

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

Si una entrada no es válida, la consola dirá que _no está definida (no debe haber una variable definida llamada _).


1

Pitón 3, 58 55

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

sin diccionario o idea robada pero todavía error inútil;)

thx @ Eᴀsᴛᴇʀʟʏ

Prueba aquí .


Creo que puede guardar un byte cambiando a python 2 y haciendo print<SPACE>sum(ord(......., eliminando los 2 paréntesis alrededor de la expresión.
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ eso es correcto, pero la entrada debe estar entre paréntesis y no quiero promover python 2;)
Alexander Nigl

¡PYTHON 2 ES VIDA! y también, ¿no creo que eso requiera que la entrada esté entre paréntesis?
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ sry quise decir citado. input()en python3 está raw_input()en python2
Alexander Nigl

Oh, lo olvidé. 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 # (sin validación) 79 57 caracteres

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

1

C # con validación: 108 caracteres (con 12 para mensaje de error):

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

C # sin validación: 60 53 caracteres:

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

1
En el segundo sin validación, puede reducir los caracteres aún más eliminando la declaración de variable s y utilizando Console.ReadLine () en línea.
hermiod

1

Perl (42 31)

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

Espero contar F, p, a y l como 1 carácter fue correcto.


1

JavaScript, 68 bytes

Esto casi seguro se puede jugar más al golf

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

Con comprobación de diccionario (Node.js y descendientes de Unix únicamente) 195 bytes

Usos /usr/share/dict/words, y definitivamente se puede acortar (ver el mensaje de advertencia)

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

Para un mensaje de error, lo hace console.error(), no console.warn().
ericw31415

Pero el desafío decía advertir (5. (Opcional) verifique que la palabra esté en un diccionario después de anotar, e imprima una advertencia si no es así.) No significa ser pedante, pero el desafío especificó una advertencia
MayorMonty

@SpeedyNinja Creo que todavía cuenta, ese no es realmente el punto del desafío ...
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ es 1 carácter más corto;)
MayorMonty

@SpeedyNinja Tienes razón, leí mal.
ericw31415
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.