„Dodaj” litery w słowie


17

Mój tata jest emerytowanym nauczycielem, a on zwykł przeprowadzać quizy pisowni i matematyki, w których uczeń pisał słowo, a następnie „punktował” słowo, dodając litery, gdzie a = 1, b = 2 itd. (np. cat = 3 + 1 + 20 = 24). Ułatwiło to ocenianie quizów, ponieważ musiał on po prostu sprawdzać, czy nie ma niepoprawnych „wyników”, a nie niepoprawnie pisanych słów, i miał dodatkową zaletę testowania 2 umiejętności jednocześnie.

Zatrudnił mojego przyjaciela, aby napisał program, który oceniałby słowa dla niego, aby mógł generować długie klucze odpowiedzi bez błędów. Ten problem jest inspirowany tym programem.

Wymagania:

  1. Zaakceptuj dowolne słowo z dużymi i małymi literami
  2. Zwraca błąd dla dowolnych znaków specjalnych, tj. Spacji, łączników, @ ^% # itd.
  3. a = 1, b = 2, ... i A = 1, B = 2, ...
  4. Wydrukuj wynik słowa
  5. (Opcjonalnie) sprawdź, czy słowo znajduje się w słowniku po ocenie, i wydrukuj ostrzeżenie, jeśli nie jest.
  6. Brak importowania zewnętrznego słownika liter-> liczb. Musisz sam go wygenerować.

Każdy język jest akceptowalny. Jest to podobne do „ cyfrowej bitwy o rootowanie ”, ale o wiele prostsze.


2
Czy to ma być golf golfowy?
Peter Taylor,

2
@Zach Korzystanie ze code-golfznacznika.
Lowjacker 23.04.11

2
Czy twój tata nawet zawracał sobie głowę nauczaniem zasady „ja przed E, z wyjątkiem reguły C”?
Nathan Merrill

2
Tak, tylko sprawdzasz wyniki? Przeliterowałbym kota jako aaaaaaaaaaaaaaaaaaaaaaaa. Tata: Wynik to 24? Zgadza się!
ericw31415

3
@ ericw31415 Każda funkcja mieszająca ma kolizje ;-). Do tej pory żaden z jego uczniów nie próbował tego wektora ataku
Zach

Odpowiedzi:


8

Golfscript - 23 znaki

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

Upewnij się, że na wejściu nie ma końcowych znaków nowej linii (np. Use echo -n).


Mamy nowego zwycięzcę!
Zach.

Ogólnie rzecz biorąc, zewnętrzne filtrowanie powinno być jakoś uwzględnione w liczeniu znaków (filtrowanie zewnętrzne Ctrl-f.), Choć zakładam, że są to tylko 2 dodatkowe znaki.
Jesse Millikan

2
@Jesse: echo -nnaprawdę nie liczy się jako zewnętrzne filtrowanie - w rzeczywistości odpowiedź, którą podłączyłeś, sugeruje, że jest to poprawna forma do wprowadzania danych.
Nabb

10

Brainf *** (100)

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

Muszę jednak przyznać, że to nie do końca spełnia wszystkie wymagania. Po pierwsze, akceptuje tylko wielkie litery, a słowo musi kończyć się tabulatorem. Niezdefiniowane zachowanie ma niezdefiniowane znaki i nie zgłasza błędu. Wyświetla sumę liter jako znak ASCII. Na przykład, jeśli słowo to „CZEŚĆ”, (8 + 5 + 12 + 12 + 15 = 52) wyświetli znak „4”, który jest znakiem ASCII dla 52. Oznacza to również, że program wariuje, gdy suma jest większa niż 255.

Ale poza tym działa dobrze. Daj mi spokój, mój mózg poradzi sobie tylko z niewielkimi dawkami ... no wiesz.


Po co kończyć słowo tabulatorem zamiast nowego wiersza?
Lowjacker 24.04.11

@ Lowowacker Ponieważ założyłem, że TAB jest prostsze niż martwienie się o \nlub \r\nlub \n\r. A gdybym użył nowej linii, nie miałbym ładnej okrągłej liczby, takiej jak 100, jako liczby znaków.
Peter Olson,

Co by się stało, gdybyś otrzymał dużą dawkę?
Mateen Ulhaq

8

Python ( 65 64)

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

Rodzi to błąd, jeśli słowo zawiera znaki nieliterowe, ale nie jest pomocne ani informacyjne. (Edycja: czubek kapelusza do st0le dla sztuczki indeksującej.)


1
print sum(['',ord(i)-64]['@'<i<'[']for i in raw_input().upper())ogolił kilka znaków.
st0le 24.04.2011

Właściwie tylko jeden znak. : - \
st0le,

Zapisz 4 znaki, używając input; zmusza użytkownika do umieszczania cudzysłowów wokół ciągów wejściowych, ale „przyjazne dla użytkownika” i „nie niebezpieczne” nie są w specyfikacji!
jscs 24.04.2011

Po prostu zmień go na Python 3! raw_inputinput
Oleh Prypin

print sum([i,ord(i)-64]['@'<i<'[']for i in raw_input().upper()) kolejny bajt ogolony
Alexander Nigl

8

Ruby, 43 znaki

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

Jednak generowany komunikat o błędzie nie jest dokładnie pomocny. Oba zamieszczone tutaj rozwiązania zakładają, że wejście nie ma końca łamania linii, więc aby je przetestować, użyjecho -n .

Ruby, 76 znaków z funkcją sprawdzania słownika

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

Komunikat ostrzegawczy składa się z pojedynczego znaku „W”. Ścieżkę do słownika należy podać za pośrednictwem ARGV. Przykładowe użycie:

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

2
Możesz wyciąć 9 znaków w wersji sprawdzania słownika, czyniąc komunikat błędu wykrzyknikiem.
Peter Olson,

Otrzymasz nagrodę pocieszenia za najkrótszy wpis z sprawdzeniem słownika. Tak trzymać!
Zach

Dlaczego zaproponowano sprawdzenie słownika, jeśli nie daje ono żadnej realnej przewagi (wręcz przeciwnie, po prostu rozszerza kod)?
Metoda pomocnicza

5

Python 2.6 (72 znaki) Bez sprawdzania słownika

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

Python 2.6 (178 znaków *) Z funkcją sprawdzania słownika

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

* Można obniżyć do 156 za pomocą mniej pomocnego komunikatu o błędzie. :-)

Dziękujemy wszystkim komentującym za pomoc w ulepszeniu tego.


Możesz rozważyć użycie sumwbudowanego wyrażenia generatora zamiast forpętli. Pozwoliłoby to odciąć kilka znaków (~ 17).

@jloy: Dzięki za zwrócenie na to uwagi.
John

nawiasy na wydruku można wyeliminować
st0le

wygląda na to, że używasz atylko raz, więc użyj samego literału ... "0abc....z".index(i)będzie działał równo .
st0le 24.04.2011

0W macierzy punktacji jest mądry, ale oznacza to również, że cat0jest akceptowana bez błędu, który nie jest w porządku, myślę. Który jest tak źle, gdyż to pozwala przejść map(a.index,w)do sumzamiast (zastępując na dosłownym ajak sugeruje st0le).

4

Perl (52) (48)

jeszcze bardziej grał w golfa dzięki Timwi

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


Brakuje -etam flagi.
Lowjacker

1
Powinieneś przynajmniej uwzględnić flagi pi linterpreter w swojej liczbie znaków. Zobacz tę dyskusję na temat meta.
Ventero

syntax error at -e line 1, near "(=" Execution of -e aborted due to compilation errors.Co ja robię źle?
użytkownik nieznany

jeśli korzystasz z Uniksa, zmień podwójne cudzysłowy na pojedyncze
chiński perl goth

@Timwi: „Zaakceptuj dowolne słowo z dużymi i małymi literami”, przepraszam. Usunąłem to teraz. @chinese: Tak, dziękuję, z pojedynczymi cytatami jest w porządku. Tak długo, jak ograniczam się do ascii input. :)
użytkownik nieznany

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, ale char `zostanie zaakceptowany)

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

v3 (60 znaków, @ będą akceptowane, ale nie liczone, dzięki jloy)

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

WSKAZÓWKA: JEST SPOSÓB USUNIĘCIA JESZCZE WIĘCEJ CHARAKTERU Z ROZWIĄZAŃ. :)

2
@jloy Co za pomocna „wskazówka”. ;)
Mateen Ulhaq

4

Scala: 59 znaków, 7 z nich, bez dykt:

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

Do tej pory brak słownika. Wynik ujemny oznacza: Negatywny!

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

Nawiasem mówiąc, z wdziękiem radzi sobie z niemieckim umlautem:

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

Wow, mniej znaków niż wersja Perla (i wciąż bardziej czytelna).
Metoda pomocnicza

Próbowałem SHiNKiROU i rozwiązania chinesis-Perl, ale one nie działały dla mnie. Zapisał je jako alpha.pli zaczął od nich perl alpha.pl. Czy oni po prostu obsługują Ascii? Cóż - w Perlu jest taka stara bestia ... :)
użytkownik nieznany

Perl i Unicode to wielki bałagan. Prawdopodobnie będziesz musiał je uruchomić jako perl -M5.010 alpha.plcoś takiego.
Peter Taylor,

Słyszałem, że potrzebuję pojedynczych cudzysłowów zamiast podwójnych cudzysłowów w Linuksie i to zadziałało, dzięki.
użytkownik nieznany

4

Biblioteki Java + Google Guava, 347 znaków, z funkcją sprawdzania słownika

Nieczytelna wersja 1 długiego łańcucha :-)

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

Wersja czytelna dla człowieka (rodzaj :-))

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

Ścieżka słownika jest teraz przekazywana przez a[1], aby twierdzenia działały, musisz użyć -eaflagi (+3 więcej znaków). Jeśli chodzi o słownik, zastosowano słownik /usr/share/dict/words(powinien być dostępny w większości systemów * nix).


Jak na razie jesteś jedynym, który ma sprawdzanie słownika, więc +1
Zach

jedna linia? nie jest to szczególnie czytelne w ten sposób, ale wydaje mi się, że oszczędza to znaki
Nate Koppenhaver

Dodam bardziej czytelne rozwiązanie (a także krótsze przy użyciu Google Guava w celu zmniejszenia kodu płyty bazowej).
Metoda pomocnicza

Po prostu zezwalasz na ascii, ale używasz Charset.UTF-8?
użytkownik nieznany

1
Ponieważ String UTF-8jest krótszy niż inne zestawy znaków :-).
Metoda pomocnicza

4

Python 3, 95 znaków ze słownikiem

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

Słownik musi znajdować się w pliku o nazwie d.

Python 3, 61 bez słownika, ale skradziony pomysł

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


Edit: With validation is:

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

129 characters. In which case:

C#, 118

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

1
This doesn't validate the input.
Lowjacker

Oops! Hold on a second...
Ry-

3
I think you should provide complete programs. Your C# solution doesn’t compile; you need to place it in a Main method inside a class declaration, and count all the characters.
Timwi

1
No, because that code doesn't do anything, and it's not fair to disadvantage users of object-oriented languages. This is valid C#/VB.NET anyways.
Ry-

3

Improving slightly on John's answer: Python (90)

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

2
adding the dummy char in the string beginning is shorter...parentheses can be removed
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 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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.