«Ajoutez» les lettres dans un mot


17

Mon père est un enseignant à la retraite, et il donnait des tests d'orthographe et de mathématiques combinés, où l'élève épelait un mot, puis `` notait '' le mot en additionnant les lettres, où a = 1, b = 2, etc. (par exemple chat = 3 + 1 + 20 = 24). Cela rendait la notation des questionnaires plus facile, car il aurait juste à vérifier les «scores» incorrects plutôt que les mots mal orthographiés, et avait l'avantage supplémentaire de tester 2 compétences à la fois.

Il a engagé un de mes amis pour écrire un programme qui marquerait des mots pour lui, afin qu'il puisse générer de longues réponses sans erreur. Ce problème est inspiré par ce programme.

Exigences:

  1. Acceptez n'importe quel mot avec des lettres majuscules et minuscules
  2. Renvoie une erreur pour tous les caractères spéciaux, c'est-à-dire les espaces, les tirets, @ ^% # etc.
  3. a = 1, b = 2, ... et A = 1, B = 2, ...
  4. Imprimer la partition du mot
  5. (Facultatif) vérifiez que le mot figure dans un dictionnaire après la notation et imprimez un avertissement s'il ne l'est pas.
  6. Pas d'importation d'un dictionnaire externe de lettres-> chiffres. Vous devez le générer vous-même.

N'importe quelle langue est acceptable. Ceci est similaire à la « bataille racine numérique », mais beaucoup plus simple.


2
Est-ce censé être un golf de code?
Peter Taylor

2
@Zach Utilisation de la code-golfbalise.
Lowjacker

2
Votre père a-t-il même pris la peine d'enseigner la règle "I avant E sauf après C"?
Nathan Merrill

2
Ouais, seulement vérifier les scores? J'épelerais chat comme aaaaaaaaaaaaaaaaaaaaaaaa. Papa: Le score est de 24? C'est vrai!
ericw31415

3
@ ericw31415 Chaque fonction de hachage a des collisions ;-). Jusqu'à présent, aucun de ses élèves n'a essayé ce vecteur d'attaque
Zach

Réponses:


8

Golfscript - 23 caractères

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

Assurez-vous qu'il n'y a pas de retour à la ligne en entrée (par exemple, utilisation echo -n).


Nous avons un nouveau gagnant!
Zach

En règle générale, le filtrage externe est censé être inclus dans le nombre de caractères (filtrage externe Ctrl-f), bien que je suppose qu'il ne reste que 2 caractères supplémentaires.
Jesse Millikan

2
@Jesse: echo -nne compte vraiment pas comme un filtrage externe - en fait, la réponse que vous avez liée le suggère comme un formulaire valide pour la saisie.
Nabb

10

Brainf *** (100)

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

Je dois cependant admettre que cela ne répond pas tout à fait à toutes les exigences. Tout d'abord, il n'accepte que les majuscules et le mot doit se terminer par un onglet. Il a un comportement indéfini pour les caractères non valides et ne génère pas d'erreur. Il affiche la somme des lettres sous forme de caractère ASCII. Par exemple, si le mot est "BONJOUR", (8 + 5 + 12 + 12 + 15 = 52), il affichera le caractère "4", qui est le caractère ASCII pour 52. Cela signifie également que le programme panique lorsque la somme est supérieure à 255.

Mais à part ça , ça marche très bien. Donnez-moi une pause, mon cerveau ne peut gérer que de petites doses de ... enfin, vous savez.


Pourquoi terminer le mot avec un onglet au lieu d'une nouvelle ligne?
Lowjacker

@Lowjacker Parce que je suppose que TAB est plus simple que de se soucier de \nou \r\nou \n\r. Et si j'utilisais la nouvelle ligne, je n'aurais pas un joli chiffre rond comme 100 comme nombre de caractères.
Peter Olson

Que se passerait-il si vous receviez une dose importante?
Mateen Ulhaq

8

Python ( 65 64)

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

Cela soulève une erreur si le mot contient des caractères autres que des lettres, mais pas un caractère utile ou informatif. (Edit: pointe du chapeau à st0le pour l'astuce d'indexation.)


1
print sum(['',ord(i)-64]['@'<i<'[']for i in raw_input().upper())rasé quelques caractères.
st0le

Un seul personnage en fait. : - \
st0le

Enregistrez 4 caractères en utilisant input; oblige l'utilisateur à mettre des guillemets autour des chaînes d'entrée, mais "convivial" et "pas dangereux" ne sont pas dans la spécification!
jscs

Eh bien, changez-le simplement en Python 3! raw_inputinput
Oleh Prypin

print sum([i,ord(i)-64]['@'<i<'[']for i in raw_input().upper()) un autre octet rasé
Alexander Nigl

8

Ruby, 43 caractères

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

Le message d'erreur que cela génère n'est cependant pas vraiment utile. Les deux solutions publiées ici supposent que l'entrée n'a pas de saut de ligne de fin, donc pour les tester, utilisez echo -n.

Ruby, 76 caractères avec vérification du dictionnaire

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

Le message d'avertissement se compose du seul caractère "W". Le chemin d'accès au dictionnaire doit être fourni via ARGV. Exemple d'utilisation:

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

2
Vous pouvez couper 9 caractères dans la version de vérification du dictionnaire en faisant du message d'erreur un point d'exclamation.
Peter Olson

Vous obtenez un prix de consolation pour l'entrée la plus courte avec une vérification du dictionnaire. Marche à suivre!
Zach

Pourquoi la vérification du dictionnaire a-t-elle été proposée si elle ne vous donne aucun avantage réel (au contraire, elle a simplement gonflé le code)?
Méthode d'assistance le

5

Python 2.6 (72 caractères) sans vérification du dictionnaire

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

Python 2.6 (178 caractères *) avec vérification du dictionnaire

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

* Peut être abaissé à 156 avec un message d'erreur moins utile. :-)

Merci à tous les commentateurs d'avoir aidé à améliorer cela.


Vous voudrez peut-être envisager d'utiliser la fonction sumintégrée avec une expression de générateur, plutôt qu'une forboucle. Cela vous permettrait de couper quelques caractères (~ 17).

@jloy: Merci de l'avoir signalé.
John

les parenthèses imprimées peuvent être éliminées
st0le

il semble que vous n'utilisiez aqu'une seule fois, alors utilisez le littéral lui-même ... "0abc....z".index(i)fonctionnera de manière équivalente.
st0le

Le 0dans votre tableau de score est intelligent, mais cela signifie également que cela cat0est accepté sans erreur, ce qui n'est pas correct, je pense. Ce qui est dommage, car cela vous permettrait de passer map(a.index,w)à la sumplace (en substituant le littéral à acomme le suggère St0le).

4

Perl (52) (48)

golf encore plus grâce à Timwi

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


Vous manquez le -edrapeau là-bas.
Lowjacker

1
Vous devez au moins inclure les indicateurs pet linterprète dans votre nombre de caractères. Voir cette discussion sur les méta.
Ventero

syntax error at -e line 1, near "(=" Execution of -e aborted due to compilation errors.Qu'est-ce que je fais mal?
utilisateur inconnu

si vous utilisez unix, changez les guillemets doubles en simples
chinese perl goth

@Timwi: 'Accepter n'importe quel mot avec des lettres majuscules et minuscules' est allé dans le mauvais fil, désolé. Je l'ai supprimé maintenant. @chinese: Oui, merci, avec des guillemets simples, ça va. Tant que je me limite à la saisie ascii. :)
utilisateur inconnu

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 mais le caractère `sera accepté)

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

v3 (60 caractères, @ seront acceptés mais non comptés, merci jloy)

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

CONSEIL: IL EXISTE UN MOYEN D'ENLEVER UN CHAR DE PLUS DE VOS SOLUTIONS. :)

2
@jloy Quel «indice» utile. ;)
Mateen Ulhaq

4

Scala: 59 caractères, dont 7 de charge utile, pas de dict:

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

Pas de dictionnaire pour l'instant. Un résultat négatif signifie: Négatif!

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

Manipule le tréma allemand avec grâce, soit dit en passant:

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

Wow, moins de caractères que la version Perl (et toujours plus lisible).
Méthode d'assistance le

J'ai essayé SHiNKiROUs et chinesis-Perl-solution, mais ils n'ont pas fonctionné pour moi. Les a enregistrés sous alpha.plet les a démarrés par perl alpha.pl. Manient-ils simplement Ascii? Eh bien - à Perl est une telle vieille bête ... :)
utilisateur inconnu

Perl et Unicode est un gros gâchis. Vous devrez probablement les exécuter en tant que perl -M5.010 alpha.plou quelque chose comme ça.
Peter Taylor

J'ai entendu dire que j'avais besoin de guillemets simples au lieu de guillemets doubles sous Linux, et cela a fonctionné, merci.
utilisateur inconnu

4

Bibliothèques Java + Google Guava, 347 caractères, avec vérification du dictionnaire

Version illisible à 1 chaîne longue :-)

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

Version lisible par l'homme (sorte 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);
    }
}

Le chemin du dictionnaire est maintenant transmis via a[1], pour que les assertions fonctionnent, vous devez utiliser l' -eaindicateur (+3 caractères supplémentaires). Quant au dictionnaire, le dict /usr/share/dict/words(qui devrait être disponible sur la plupart des systèmes * nix) a été utilisé.


Jusqu'à présent, vous êtes le seul à avoir vérifié le dictionnaire, alors +1
Zach

une ligne? ce n'est pas particulièrement lisible de cette façon, bien que je suppose que cela sauve les caractères
Nate Koppenhaver

J'ajouterai une solution plus lisible (et aussi une plus courte en utilisant Google Guava pour réduire le code passe-partout).
Méthode d'assistance le

Vous autorisez simplement ascii, mais utilisez Charset.UTF-8?
utilisateur inconnu

1
Parce que la chaîne UTF-8est plus courte que les autres jeux de caractères :-).
Méthode d'assistance le

4

Python 3, 95 caractères avec dictionnaire

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

Le dictionnaire doit être dans un fichier appelé d.

Python 3, 61 sans dictionnaire, mais idée volée

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


Modifier: Avec validation est:

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

129 caractères. Dans quel cas:

C #, 118

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

1
Cela ne valide pas l'entrée.
Lowjacker

Oups! Attendez une seconde ...
Ry-

3
Je pense que vous devriez fournir des programmes complets. Votre solution C # ne compile pas; vous devez le placer dans une méthode Main dans une déclaration de classe et compter tous les caractères.
Timwi

1
Non, car ce code ne fait rien et il n'est pas juste de désavantager les utilisateurs de langages orientés objet. C'est de toute façon C # / VB.NET valide.
Ry-

3

Améliorant légèrement la réponse de John: Python (90)

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

2
l'ajout du caractère factice au début de la chaîne est plus court ... les parenthèses peuvent être supprimées
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 caractères

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

L'erreur qu'elle lance n'est pas exactement la meilleure, mais bon, elle interrompt l'exécution.


Je ne sais rien de golfscript, donc je vais supposer que cela répond aux exigences et vous déclarer vainqueur!
Zach

Oups, vous avez été battu! Je suppose que 2 jours ne suffisent pas pour attendre une question de code de golf?
Zach

3

PYTHON 62 68 * Caractères

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

Nécessite que l'utilisateur entre des chaînes à l'aide de guillemets et n'est pas sûr ( inputexécute le code), mais, comme je l'ai dit dans un commentaire à un autre article, "convivial" et "pas un risque pour la sécurité" n'est pas dans la spécification!


* J'ai oublié print, bon sang.


La réponse de jloy est encore plus courte, en fait, à cause de la différence input/ raw_input.
jscs

2

Rubis 1.9, 69

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

Ne gère que les caractères ascii. Je pensais que Ruby est de notre siècle? :)
utilisateur inconnu

@user unknown: La spécification ne dit pas que c'est nécessaire. Le faire serait plutôt compliqué ...
Lowjacker

2

GolfScript, 50 (53)

Donne une erreur sur les mauvais caractères, mais pas très bonne (50 caractères):

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

Donne plutôt "E" en cas d'erreur (53 caractères):

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

L'extrait de génération d'alphabet 123,97>+est volé à Ventero.


2

J (55)

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

Cela satisfait toutes les conditions sauf celle du dictionnaire. En tant que condition d'erreur, il renvoie "infini" (le symbole de soulignement en J) pour les mots qui contiennent autre chose que des lettres.


2

Haskell (127)

(soulève une erreur sur les caractères étranges)
(aussi: l'espace entre toUpper.et \xest nécessaire sinon il le traite comme (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)

(ne génère pas d'erreur, mais 45% plus court)

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

Le "set up" / etc:

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

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

Comportement "non défini" (c'est plus une "mauvaise pratique" qu'un "non défini", mais bon):

  • void main() Cela dit tout.
  • J'utilise newsans delete.

1

JavaScript 1.8, 80 caractères

Étonnamment lisible!

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

Pour une utilisation dans Chrome je devais convertir un peu: alert(prompt().toLowerCase().split("").reduce(function(a,b){return a+b.charCodeAt(0)-96},0)). J'aime toujours plus les solutions JavaScript :)
pimvdb

Il ne retourne pas d'erreur lorsque vous faites un caractère invalide ???
ericw31415

1

APL (34)

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

Donne soit le score, soit un VALUE ERRORs'il y a des caractères non alphabétiques dans l'entrée.

Explication:

  • : lire une ligne d'entrée
  • {... }: fonction appliquée à chaque caractère d'entrée
  • A←⎕UCS⍵: stocke la valeur ASCII du caractère courant dans A
  • A-32×96<A: rendre le caractère majuscule: de Aest soustrait 32 si 96<A(donc, s'il est en majuscule), sinon 0
  • 64-⍨: soustrayez 64 de ceci, donnant A = 1, B = 2 ...
  • ¨: appliquez cette fonction à chaque personnage:
  • ⍵∊⍳26: si le personnage est compris entre 1 et 26 ...
  • :⍵: alors retourne ⍵ (et puisqu'il n'y a pas de clause else, il y aura un VALUE ERRORsi ce n'est pas entre 1 et 26)
  • +/: somme toutes les valeurs ensemble (et cette valeur est automatiquement sortie car c'est le résultat final).

1

JavaScript, 60 octets

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

Si le programme doit renvoyer une erreur sur des entrées invalides, alors 80 octets:

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

Si une entrée n'est pas valide, la console dira qu'elle _n'est pas définie (il ne doit pas déjà y avoir de variable définie appelée _).


1

Python 3, 58 55

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

sans dictionnaire ou idée volée mais erreur toujours inutile;)

thx @ Eᴀsᴛᴇʀʟʏ

Testez ici .


Je pense que vous pouvez enregistrer un octet en passant à python 2 et en faisant print<SPACE>sum(ord(......., en supprimant les 2 parenthèses autour de l'expression.
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ c'est vrai mais que l'entrée doit être entre parenthèses et je ne veux pas promouvoir python 2;)
Alexander Nigl

PYTHON 2 EST LA VIE !! et aussi, je ne pense pas que cela nécessiterait une entrée entre parenthèses?
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ sry je voulais dire cité. input()en python3 est raw_input()en python2
Alexander Nigl

Oh j'ai oublié. Hm.
Rɪᴋᴇʀ

1

C, 98 octets

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

1

F # (pas de validation) 79 57 caractères

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

1

C # avec validation: 108 caractères (dont 12 pour le message d'erreur):

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

C # sans validation: 60 53 caractères:

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

1
Dans le second sans validation, vous pouvez réduire encore plus les caractères en supprimant la déclaration de variable s et en utilisant Console.ReadLine () en ligne.
hermiod

1

Perl (42 31)

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

J'espère que compter F, p, a et l comme 1 caractère était correct.


1

JavaScript, 68 octets

Cela peut certainement être joué plus

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

Avec vérification du dictionnaire (Node.js et descendants Unix uniquement) 195 octets

Utilise /usr/share/dict/wordset peut certainement être raccourci (voir le message d'avertissement)

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

Pour un message d'erreur console.error(), non console.warn().
ericw31415

Mais le défi dit d'avertir (5. (Facultatif) vérifiez que le mot est dans un dictionnaire après avoir marqué et imprimez un avertissement s'il ne l'est pas.) Ne voulez pas être pédant, mais le défi spécifiait un avertissement
MayorMonty

@SpeedyNinja Je pense que ça compte toujours, ce n'est pas vraiment le but du défi ...
Rɪᴋᴇʀ

@ EᴀsᴛᴇʀʟʏIʀᴋ c'est 1 caractère plus court;)
MayorMonty

@SpeedyNinja Vous avez raison, j'ai mal lu.
ericw31415
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.