Bilans alfanumeryczny

15

Napisz program, który pobiera ciąg wejściowy i zlicza w nim liczbę znaków alfanumerycznych i niealfanumerycznych. Musi wyświetlać swój wynik w następujący sposób:

wejście: http://stackexchange.com
wyjście:20 + 4 = 24

Haczyk polega na tym, że kod źródłowy musi mieć taką samą liczbę znaków alfanumerycznych jak znaki niealfanumeryczne. Komentarze nie są dozwolone, białe znaki są ignorowane. (Język o nazwie Whitespace może konkurować o głosy, ale oczywiście nie zostanie wybrany jako zwycięzca)

Znaków w kodzie musi mieć przynajmniej jakieś drobne uzasadnienie, nie powinny one być całkowicie zbędne. Na przykład dozwolone są dłuższe nazwy zmiennych, i = (j*3)+4;a i = j*3+4;nie dozwolone. Jednak i = i + 1;;;;;;nie jest.

Poza tym obowiązują standardowe zasady gry w golfa kodowego.

vsz
źródło
Gdybym zdefiniować nową, obróbce wstępnej wariant OOK gdzie kluczowe są O., O?i O!czym każdy zapis Program I spełnia ograniczenia klasy znak ... Oczywiście, że jest prawdopodobne, aby stracić na działalności długości.
dmckee --- były moderator kociąt
2
czy to wszystko będzie ascii?
Jordon Biondo
@JordonBiondo: Myślałem o wszystkim, co chcesz, od pełnego 8-bitowego ANSI do Unicode, ale jeśli twój kod obsługuje tylko 7-bitowy ASCII, również to zaakceptuję.
vsz
3
Czy białe znaki w ciągu wyjściowym są liczone do znaków innych niż alfanumeryczne? Lub zignorowany w przypadku wszystkich innych (nie-literalnych-ciągów) białych znaków?
Kninnug
1
@dmckee: Jeśli zamierzasz zdefiniować własny język, po prostu określ wariant wybranego języka, w którym niepuste programy działają tak jak w języku podstawowym, ale pusty program jest wstępnie przetwarzany na kod, który robi dokładnie to, co pytanie pyta.
user2357112 obsługuje Monikę

Odpowiedzi:

8

Perl, 32 + 32 = 64

Ciąg oczekuje się w STDIN. Dane wyjściowe są zapisywane w STDOUT. Białe znaki są ignorowane. Moją interpretacją tego zadania jest to, że program powinien być w stanie uruchomić się na sobie, aby uzyskać wynik.

$/ = $,;
$_ = <>;
s x\sxxg;
$\ = length;
print s x[0-9a-z]xxgi,
      ' + ',
      s x.xxg,
      ' = '

Niegolfowany z komentarzami

$/ = $,; # The input separator becomes undefined, because the default for $, is "undef"
$_ = <>; # now $_ takes the whole file (STDIN) instead of the first line
s x\sxxg; # $_ =~ s/\s//g;
          # white space is removed from $_
$\ = length; # The number of the other characters are put into $\,
             # which is automatically printed the end of "print".
print s x[0-9a-z]xxgi, # s/[0-9a-z]//gi
                       # Remove alphanumeric characters and return their count
      ' + ',
      s x.xxg, # s/.//g
               # Remove the remaining special characters and return their count.
               # "." does not catch new lines, but we have already
               # removed white spaces including new lines.
      ' = '

Znalazłem kilka odmian o tej samej liczbie bajtów, np .:

$/ = $x;
$_ = <>, s x\sxxg;
$\ = split $x;
print s x[\da-z]xxgi,
      " + ",
      s x.xxg,
      ' = '

Przykłady

  • Przykład z pytania:

    echo 'http://stackexchange.com' | perl a.pl
    20 + 4 = 24
  • Uruchamianie na sobie ( a.pl):

    cat a.pl | perl a.pl
    32 + 32 = 64

    Rozmiar pliku to 104 bajty, dlatego 40 bajtów jest ignorowanych jako białe znaki.

Perl, 29 + 29 = 58

$_=<>;s x\sxxg;$\=length;print s x[0-9a-z]xxgi,' + ',s/.//g,' = '

Ciąg oczekuje się na STDIN i jest ograniczony do pierwszego wiersza. Wynik zostanie wydrukowany do STDOUT. Białe znaki są ignorowane.

Nie golfił

$_ = <>;
s x\sxxg; # same as s/\s//gx; removes white space;
$\ = length($_); # sum is automatically appended at the end of print
print sx[0-9a-z]xxgi, # same as s/[0-9a-z]//gi;
                      # the number of alphanumeric characters
      ' + ',
      s/.//g, # the number of the remaining special characters
      ' = '

Przykłady

Plik a.plzawiera skrypt Perla.

  • Przykład z pytania:

    echo 'http://stackexchange.com' | perl a.pl
    20 + 4 = 24
  • Uruchamianie na sobie:

    cat a.pl | perl a.pl
    29 + 29 = 58

    Rozmiar pliku a.plto 65 bajtów, dlatego 7 bajtów jest ignorowanych jako białe znaki.

Heiko Oberdiek
źródło
Wygląda na to, że zakładasz, że dane wejściowe dotyczą tylko jednej linii ... Nie widziałem nic na ten temat w specyfikacji? Jakie jest uzasadnienie flagi / x przy pierwszym zamianie?
skibrianski
@skibrianski: (a) Pytanie nie jest zbyt jasne o określenie „łańcucha”. Teraz dodałem wariant, który może czytać całe pliki. (b) Nie jest dla mnie jasne, w jaki sposób skrypt powinien traktować białe spacje. Moja interpretacja jest taka, że ​​białe znaki są ignorowane zarówno w zadaniu, jak i w partyturze. (c) Flaga / x pozwala białym spacjom we wzorze na zwiększenie czytelności. Zaktualizowana odpowiedź korzysta z niej.
Heiko Oberdiek
Re a), autor nie mówi nic o tym, co będzie w ciągu, więc sądzę, że nierozsądne jest przyjmowanie założeń, co dla mnie oznacza, że ​​nowe linie muszą być dozwolone. Re b) zgodził się, nie jest jasne. Re c) Racja, ale w twojej odpowiedzi białe znaki nie zwiększają czytelności mojego oka, po prostu dodaje znak alfanumeryczny ... Może jestem zbyt trudny w tej kwestii, ale ujawnia mi, że używasz tylko / x w jednym z wyrażeń regularnych, prawdopodobnie dodając ten ostatni dodatkowy alfanumeryczny, aby wyrównać liczby =) Nadal lubię twoją odpowiedź. Ugotowałem coś podobnego.
skibrianski
haha, teraz mamy zasadniczo identyczny kod =) dobry show =)
skibrianski
@skibrianski: :-) Dzięki, dajesz mi powód do opublikowania jednego z innych wariantów z nieco większymi różnicami. Jednak liczba bajtów pozostaje.
Heiko Oberdiek
6

C - 96 (48 + 48) znaków

To jest trochę czytelne. Jest jednak miejsce na ulepszenia.

i,j;main(_){while((_=getchar())>=0)isspace(_)||(isalnum(_)?i++:j++);printf("%i + %i = %i",i,j
,i+j);}
Oberon
źródło
5

Bash + coreutils, 72 (36 + 36) znaków niebiałych

a=`tr -dc [:alnum:]<<<$1|wc -c`
n=`tr -dt [:space:]<<<$1|wc -c`
echo $a + $[n-a] = $n

Wynik:

$ ./alnumbalance.sh http://stackexchange.com 
20 + 4 = 24
$ ./alnumbalance.sh "$ (cat alnumbalance.sh)"
36 + 36 = 72
$ 

Poprzednia odpowiedź:

Pure Bash, 92 (46 + 46) znaki bez spacji

nosp=${1//[[:space:]]}
noaln=${nosp//[[:alnum:]]}
echo $[${#nosp}-${#noaln}] + ${#noaln} = ${#nosp}

Wynik:

$ ./alnumbalance.sh http://stackexchange.com 
20 + 4 = 24
$ ./alnumbalance.sh "$ (cat alnumbalance.sh)"
46 + 46 = 92
$ 
Cyfrowa trauma
źródło
Woohoo - nawet bije w golfa ! ;-)
Cyfrowa trauma
Co z postaciami kontrolnymi? [: alnum:] nie jest odwrotnością [: punct:]. Spróbuj np. Head -c256 / dev / urandom | tr -d [: alnum:] [: punct:]
skibrianski
@skibrianski dobry punkt. Zredagowałem odpowiedź, aby wziąć to pod uwagę.
Cyfrowa trauma
3

PowerShell (43 + 43 = 86)

Grał w golfa

function alf($i){$a=0;$n=0;[char[]]$i|%{if($_-match"[a-zA-Z0-9]"){$a++}else{$n++}}; write-host "$a+$n=$($a+$n)"}

Nie grał w golfa

function alf($i){
    $a=0;$n=0;  
    [char[]] $i | %{ if ($_ -match "[a-zA-Z0-9]") { $a++ } else { $n++ } };
    write-host "$a+$n=$($a + $n)"
}

Test

PS > alf "http://stackexchange.com"
20+4=24

Testowanie z samym kodem w celu spełnienia kryteriów

PS > alf "function alf($i){$a=0;$n=0;[char[]]$i|%{if($_-match`"[a-zA-Z0-9]`"){$a++}else{$n++}}; write-host `"$a+$n=$($a+$n)`"}"
43+43=86

" został zastąpiony znakiem `, który nie jest częścią ciągu.

drobnoustrój
źródło
2

GolfScript, 74 znaki (= 37 + 37)

{+}:PLUS;.,.@10,''*26,{65PLUS.32|}%PLUS$-,\1$-' + 'PLUS\PLUS' = 'PLUS\PLUS

Test online kodu z kodem jako danymi wejściowymi.

Howard
źródło
2

Rubin 38 + 38 = 76

Ten program zlicza końcowy znak nowej linii na wejściu.

puts"#{a=gets.scan(/[a-z0-9]/i).length}+#{b=$_.scan(/\W|_/).length}=#{a+b}"

Liczbę znaków wykonuje sam program: $ ruby alphabalance.rb alphabalance.rb:)

daniero
źródło
2

PowerShell, 70 bajtów (= 35 + 35)

param($s)"$(($l=$s.Length)-($n=($s|sls '\W' -a).Matches.Count))+$n=$l"

Skrypt testowy:

$f = {
param($s)"$(($l=$s.Length)-($n=($s|sls '\W' -a).Matches.Count))+$n=$l"
}

&$f "http://stackexchange.com"
&$f $f.toString().Trim()

Wynik:

20+4=24
35+35=70

PowerShell, 70 bajtów (= 35 + 35), alternatywnie

"$(($l="$args"|% Length)-($n=($args|sls '\W'-a).Matches.Count))+$n=$l"
mazzy
źródło
2

Python 2 (60 + 60 = 120)

Trudny, prawdopodobnie jest miejsce na poprawę. Podobnie jak sama funkcja może być wykorzystana do oceny własnej równowagi alfanumerycznej.

def f(s):
 i=j=0
 for c in s:
  t=ord(c)
  if (t!=2**5): 
   i+=1  
  if (48<=t<=57 or 65<=t<=90 or 97<=t<=122):
   j+=1 
 print `j`,'+',`i-j`,'=',i      

Test:

>>> f("http://stackexchange.com")
20 + 4 = 24
Willem
źródło
Jaka to wersja Pythona?
Gigaflop,
@Gigaflop Zredagowałem to. Instrukcja print to tylko Python 2, podobnie jak składnia backtick repr.
mbomb007,
1

C ++, 146 (73 + 73) 178 (89 + 89) znaków spoza #

Oryginał w zestawie <algorithm>bez wyraźnego powodu. Ups

//create a test string
#include<string>
std::string a = "\?\?=include <cstdio>\
int x,y;\
int main()\?\?<\
    for(char c : a)\
            !isspace(c) ? (isalnum(c) ? y++ : x++) : 0;\
    printf(\"%d\?\?/t%c\?\?/t%d\?\?/t%c\?\?/t%d\?\?/n\",y,'+',x,'=',(x+y));\
\?\?>";

//Code itself starts here
??=include <cstdio>
int x,y;
int main()??<
    for(char c : a)
        !isspace(c) ? (isalnum(c) ? y++ : x++) : 0;
    printf("%d??/t%c??/t%d??/t%c??/t%d??/n",y,'+',x,'=',(x+y));
??>

Liczę tylko znaki w wierszach po //Code itself starts here. W szczególności oznacza to brak liczenia #include <string>. Liczę też trigrafie jako trzy znaki każda, co być może jest dyskusyjne. Zauważ, że podczas testowania programu na własnym kodzie źródłowym należy zachować ostrożność, aby zapobiec zastąpieniu trygrafu w literale łańcucha.

Jest tu kilka osobliwych decyzji projektowych - w większości kodów produkcyjnych nie spotkasz w tej samej funkcji trygrafów i pętli opartych na zakresie - ale myślę, że wszystko to mieści się w granicach „uzasadnionego”.

użytkownik19057
źródło
1

python 52 +52 = 104

Ciekawe wyzwanie, ponieważ python unika znaków innych niż alfanumeryczne.

def f(_):
    _=_.replace(" ","");l=len(_);a=sum([c.isalnum() for c in _][:l]);print("{0} + {1} = {2}".format(a,l-a,l))

Niewielkie uzasadnienie użycia wycinka: przyspiesza to (może?)

qwr
źródło
Spróbuj użyć Python 2, ponieważ printnie wymaga nawiasów, i skorzystaj z '%d + %d = %d' % (a,l-a,l)metody. To powinno uratować niektóre postacie.
mbomb007
1

Julia, 64 lata

f(s)=(b=endof(s);a=sum([isalnum(c) for c in s]);"$(a) + $(b-a) = $(b)";)

Wszystkie jedyne niepotrzebne znaki niealfanumeryczne to ostatnie ;i niektóre z ()formatowania łańcucha. Wyszło prawie idealnie wyważone i jako potęga 2 bez większego kręcenia.

julia> f("http://stackexchange.com")
"20 + 4 = 24"
julia> nowhite(s)=join(split("s"," "))
julia> f(nowhite("f(s)=(b=endof(s);a=sum([isalnum(c) for c in s]);\"\$(a)+\$(b-a)=\$(b)\";)"))
"32 + 32 = 64"
gggg
źródło
1

perl, 64 znaki niebiałe:

$/=$,;
$_=<>;
s 0\s00g;
$\=length;
print s 1[a-z0-9]11ig .
      " + " .
      s 2.22g .
      " = "

Lekko wyjaśnione przez perl -MO = Deparse i kilka komentarzy:

$/ = $,;               # input record separator = a variable defaulting to undef
$_ = <ARGV>;           # slurp stdin
s/\s//g;               # strip whitespace
$\ = length $_;        # output record separator = total length of string sans whitespace
print s/[a-z0-9]//gi . ' + ' . s/.//g . ' = '; # count alphanumerics, then everything else

ORS, $ \ jest dodawany automatycznie do każdego wezwania do drukowania, umieszczając całkowitą liczbę na końcu.

skibrianski
źródło
Miałem 66 znaków przy pierwszym przejściu. Dzięki Heiko Oberdiek za pokazanie, że możesz rozbroić $ / z mniejszą liczbą znaków, ustawiając go na $, =)
skibrianski
1

Python 2, 50 + 50 = 100

import re
def f(i):
    w = re.sub('\s', '', i)
    s = re.subn('[\W_]', '', w)
    a = len(s[0])
    print '%d + %d = %d' % (a, s[1], a+s[1])

Uruchom tutaj: http://repl.it/8CH

mbomb007
źródło
0

Rebol (64 + 64 = 128)

f: func [x] [
    c: :charset
    a: c [#"a" - #"z"]
    s: c [#" " #"^/" #"^-"]
    n: complement union a s
    a+: n+: 0
    parse x [
        some [
            a (++ a+) |
            n (++ n+) |
            s
        ]
    ]
    print [a+ "+" n+ "=" a+ + n+]
]

Przykład użycia (w konsoli Rebol):

>> f "http://stackexchange.com"
20 + 4 = 24

NB Program ignoruje spacje, tabulacje i znaki nowej linii z zliczeń.

draegtun
źródło
0

J - 46 + 46 = 92

Liczy białe znaki, więc nie można wykonać autotestu bez modyfikacji. Pobiera dane wejściowe na standardowe wejście. Ma złe usta, należy go umyć mydłem.

;":&.>(+/;' + ';(#-+/);' = ';#)(e.~1!:1@1:)(,toupper)'golfscriptSUCKSabdehjkmnquvwxyz',,":"0 i.10

Stosowanie:

   ;":&.>(+/;' + ';(#-+/);' = ';#)(e.~1!:1@1:)(,toupper)'golfscriptSUCKSabdehjkmnquvwxyz',,":"0 i.10
http://stackexchange.com
20 + 4 = 24

   NB. modification for self-test:    vvvvvv - remove spaces, the only whitespace
   ;":&.>(+/;' + ';(#-+/);' = ';#)(e.~' '-.~1!:1@1:)(,toupper)'golfscriptSUCKSabdehjkmnquvwxyz',,":"0 i.10
;":&.>(+/;' + ';(#-+/);' = ';#)(e.~1!:1@1:)(,toupper)'golfscriptSUCKSabdehjkmnquvwxyz',,":"0 i.10
46 + 46 = 92
algorytmshark
źródło
0

JavaScript - 76 (38 + 38)

_ = prompt()
o = _.match(/[a-z0-9]/gi).length
$ = _.length - o
alert(o + " + " + $ + " = " + (o + $))

Przykładowe wejście: http://stackexchange.com
wyjście:20 + 4 = 24

Uruchamianie na własną rękę:

var a  = '_ = prompt()o = _.match(/[a-z0-9]/gi).length$ = _.length - oalert(o + " + " + $ + " = " + (o + $))'

var letters = a.match(/[a-z0-9]/g).length; 
var nons = a.match(/[^a-z0-9 ]/g).length; // excludes whitespace from count

console.log(nons + " = " + letters); // 38 = 38 :)

PS W przypadku osób zainteresowanych (o + $)utrzymaniem równowagi alfanumerycznej tak nie jest. Ponieważ po zobaczeniu o + " + "JS zdecyduje, że wszystkie +będą konkatenatorami łańcuchów, a nie sumatorami liczb. Dlatego nawiasy są konieczne, a raczej 20 + 4staną się20424 : D

Happy Coding!

Gaurang Tandon
źródło
0

Clojure: (31 + 31 = 62) znaki niebiałe

(def ff #(let [c count y (c %) x (c (re-seq #"\w" %))] (str x " + " (- y x) " = " y)))

Wynik:

alphabalance.core=> (ff "http://stackexchange.com")
"20 + 4 = 24"
Jarlax
źródło
0

CJam, 27 + 27 = 54

CJam jest kilka miesięcy nowszy od tego wyzwania, więc ta odpowiedź nie kwalifikuje się do zielonego znacznika wyboru. To i tak było zabawne ćwiczenie!

ea0=eu{A,s'[,65>+#)g}%_:+1@f-:+ea0=,]"DODDaD"36f-3/]zo

Bierze ciąg wejściowy jako argument wiersza poleceń, więc nie będzie działał w tłumaczu online, ale można go przetestować za pomocą interpretera Java .

Wyjaśnienie

"Distinguish alphanumeric characters:";
ea0=eu{A,s'[,65>+#)g}%
ea0=                   "Get the first command-line argument.";
    eu                 "Convert it to upper case.";
      {             }% "Map this block onto each character.";
       A,s             "Get the string '0123456789'.";
          '[,          "Get a string with all characters from the null byte to Z.";
             65>       "Remove the first 65 characters, to leave A to Z.";
                +      "Add to digit.";
                 #     "Find character in that string. Returns -1 if not alphanumeric.":
                  )g   "Increment and get signum. Yields 1 for alphanumeric characters,
                        0 otherwise.";

"Now we've got an array of 0s and 1s. Let's do the counting:";
_:+1@f-:+ea0=,]
_               "Duplicate array.";
 :+             "Get the sum. This is the number of alphanumeric characters.";
   1@           "Push a 1 and pull up the other copy of the array.";
     f-         "Subtract each element from 1, this swaps 0s and 1s.";
       :+       "Get the sum. This is the number of symbol characters.";
         ea0=   "Get the first command-line argument again.";
             ,  "Get its length. This is the total number of characters.";
              ] "Collect everything in an array.";

"And now the formatting:";
"DODDaD"36f-3/]zo
"DODDaD"          "Push this string.";
        36f-      "Subtract 36 from each character. This yields ' +  = '.";
            3/    "Split into two halves of 3 characters each.";
              ]   "Wrap this and the previous array in another array.";
               z  "Zip. Transposes the array to interleave strings with numbers.";
                o "Output the resulting array without delimiters.";
Martin Ender
źródło