Balance alphanumérique

15

Écrivez un programme qui obtient une chaîne comme entrée et compte le nombre de caractères alphanumériques et non alphanumériques qu'il contient. Il doit afficher son résultat comme ceci:

entrée: http://stackexchange.com
sortie:20 + 4 = 24

Le hic, c'est que votre code source doit avoir le même nombre de caractères alphanumériques que les caractères non alphanumériques. Les commentaires ne sont pas autorisés, les espaces sont ignorés. (La langue appelée Whitespace pourrait concourir pour les votes, mais ne sera pas sélectionnée comme gagnante, évidemment)

Les caractères du code doivent avoir au moins une justification mineure, ils ne doivent pas être complètement superflus. Par exemple, des noms de variables plus longs sont autorisés, i = (j*3)+4;au lieu de i = j*3+4;est également autorisé. Mais ce i = i + 1;;;;;;n'est pas le cas.

En plus de cela, les règles de code-golf standard s'appliquent.

vsz
la source
Si je définir une nouvelle variante de prétraité Ook où les mots clés sont O., O?et O!puis tout programme I écriture répond à la restriction de classe de caractères ... Bien sûr , il est de perdre probablement sur l'activité de longueur.
dmckee --- chaton ex-modérateur
2
sera-ce tout ascii?
Jordon Biondo
@JordonBiondo: Je pensais à tout ce que vous voulez, de l'ANSI 8 bits complet à l'unicode, mais si votre code ne prend en charge que l'ASCII 7 bits, je l'accepterai également.
vsz
3
L'espace à l'intérieur de la chaîne de sortie est-il compté dans les caractères non alphanumériques? Ou ignoré avec tous les autres espaces (non littéraux de chaîne)?
Kninnug
1
@dmckee: Si vous allez définir votre propre langue, définissez simplement une variante de la langue de votre choix où les programmes non vides fonctionnent exactement comme dans la langue de base, mais le programme vide est prétraité en code qui fait exactement ce que le demande la question.
user2357112 prend en charge Monica

Réponses:

8

Perl, 32 + 32 = 64

La chaîne est attendue dans STDIN. La sortie est écrite dans STDOUT. L'espace blanc est ignoré. Mon interprétation de la tâche est que le programme devrait pouvoir s'exécuter sur lui-même pour obtenir le score.

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

Non golfé avec des commentaires

$/ = $,; # 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.
      ' = '

J'ai trouvé plusieurs variantes avec le même nombre d'octets, par exemple:

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

Exemples

  • Exemple de la question:

    echo 'http://stackexchange.com' | perl a.pl
    20 + 4 = 24
  • Fonctionnant sur lui-même ( a.pl):

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

    La taille du fichier est de 104 octets, donc 40 octets sont ignorés comme espace blanc.

Perl, 29 + 29 = 58

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

La chaîne est attendue à STDIN et elle est limitée à la première ligne. Le résultat est imprimé sur STDOUT. L'espace blanc est ignoré.

Non golfé

$_ = <>;
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
      ' = '

Exemples

Le fichier a.plcontient le script Perl.

  • Exemple de la question:

    echo 'http://stackexchange.com' | perl a.pl
    20 + 4 = 24
  • Fonctionnant sur lui-même:

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

    La taille du fichier a.plest de 65 octets, donc 7 octets sont ignorés comme espace blanc.

Heiko Oberdiek
la source
Il semble que vous supposiez que l'entrée est sur une seule ligne ... Je n'ai rien vu à ce sujet dans la spécification? En outre, quelle est la justification de l'indicateur / x dans le premier remplacement?
skibrianski
@skibrianski: (a) La question n'est pas trop claire sur la spécification de "chaîne". Maintenant, j'ai ajouté une variante qui peut lire des fichiers entiers. (b) De plus, il n'est pas clair pour moi comment le blanc doit être traité par le script. Mon interprétation est que l'espace blanc est ignoré à la fois dans la tâche et dans la partition. (c) L'indicateur / x permet un espace blanc dans le motif pour augmenter la lisibilité. La réponse mise à jour en fait usage.
Heiko Oberdiek
En ce qui concerne a), l'auteur ne dit rien de ce qu'il y aura dans la chaîne, donc je suppose qu'il est imprudent de faire des hypothèses, ce qui signifie pour moi que les nouvelles lignes doivent être autorisées. Re b) d'accord, ce n'est pas clair. Re c) D'accord, mais dans votre réponse, les espaces blancs n'ajoutent pas de lisibilité à mes yeux, ils ajoutent juste un caractère alphanumérique ... Peut-être que je suis trop dur sur ce point, mais cela me révèle que vous n'utilisez que / x dans l'un de vos regex, probablement pour ajouter un dernier alphanumérique supplémentaire pour que les nombres soient alignés =) Pourtant, j'aime votre réponse. J'ai concocté quelque chose d'assez similaire.
skibrianski
haha maintenant, nous avons un code essentiellement identique =) bon spectacle =)
skibrianski
@skibrianski: :-) Merci, vous me donnez une raison de poster une des autres variantes avec un peu plus de différences. Cependant, le nombre d'octets reste.
Heiko Oberdiek
6

C - 96 (48 + 48) caractères

C'est un peu lisible. Il y a cependant place à amélioration.

i,j;main(_){while((_=getchar())>=0)isspace(_)||(isalnum(_)?i++:j++);printf("%i + %i = %i",i,j
,i+j);}
Oberon
la source
5

Bash + coreutils, 72 (36 + 36) caractères non blancs

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

Production:

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

Réponse précédente:

Pure Bash, 92 (46 + 46) caractères non blancs

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

Production:

$ ./alnumbalance.sh http://stackexchange.com 
20 + 4 = 24
$ ./alnumbalance.sh "$ (cat alnumbalance.sh)"
46 + 46 = 92
$ 
Traumatisme numérique
la source
Woohoo - il bat même golfscript ! ;-)
Digital Trauma
Et les personnages de contrôle? [: alnum:] n'est pas l'inverse de [: punct:]. Essayez par exemple head -c256 / dev / urandom | tr -d [: alnum:] [: punct:]
skibrianski
@skibrianski bon point. J'ai édité la réponse pour en tenir compte.
Digital Trauma
3

PowerShell (43 + 43 = 86)

Golfé

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

Non golfé

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

Tester

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

Test avec le code lui-même pour passer les critères

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

" a été échappé avec `qui ne fait pas partie de la chaîne.

microbien
la source
2

GolfScript, 74 caractères (= 37 + 37)

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

Test en ligne du code avec le code en entrée.

Howard
la source
2

Rubis 38 + 38 = 76

Ce programme compte le retour à la ligne dans l'entrée.

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

Le décompte des caractères est effectué par le programme lui-même: $ ruby alphabalance.rb alphabalance.rb:)

daniero
la source
2

Powershell, 70 octets (= 35 + 35)

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

Script de test:

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

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

Production:

20+4=24
35+35=70

Powershell, 70 octets (= 35 + 35), alternative

"$(($l="$args"|% Length)-($n=($args|sls '\W'-a).Matches.Count))+$n=$l"
mazzy
la source
2

Python 2 (60 + 60 = 120)

Difficile, il y a probablement place à amélioration. Comme le fait que la fonction elle-même peut être utilisée pour évaluer son propre équilibre alphnumérique.

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      

Tester:

>>> f("http://stackexchange.com")
20 + 4 = 24
Willem
la source
De quelle version de Python s'agit-il?
Gigaflop
@Gigaflop Je l'ai édité. L'instruction print est uniquement en Python 2, tout comme la syntaxe de backtick pourrepr .
mbomb007
1

C ++, 146 (73 + 73) 178 (89 + 89) caractères non blancs #

Original inclus <algorithm>sans raison valable. Oups.

//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));
??>

Je ne compte que les caractères dans les lignes après //Code itself starts here . En particulier, cela signifie ne pas compter #include <string>. Je compte également les trigraphes comme trois caractères chacun, ce qui est peut-être discutable. Notez que lors du test du programme sur son propre code source, un certain soin est requis pour empêcher le remplacement du trigraphe dans le littéral de chaîne.

Il y a des décisions de conception particulières ici - dans la plupart des codes de production, vous ne rencontrerez pas de trigraphes et de boucles basées sur la plage pour la même fonction - mais je pense que tout est dans les limites de `` justifiable ''.

user19057
la source
1

python 52 +52 = 104

Défi intéressant car python évite les caractères non alphanumériques.

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

Justification mineure de l'utilisation de la tranche: elle accélère (peut-être?)

qwr
la source
Essayez d'utiliser Python 2, car printne nécessite pas de parenthèses, et utilisez la '%d + %d = %d' % (a,l-a,l)méthode. Cela devrait sauver quelques caractères.
mbomb007
1

Julia, 64 ans

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

Tous les seuls caractères non alphanumériques inutiles sont les derniers ;et certains ()dans la mise en forme des chaînes., Il est sorti presque parfaitement équilibré, et en tant que puissance de 2 sans trop jouer.

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
la source
1

perl, 64 caractères non blancs:

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

Clarifié légèrement via perl -MO = Deparse et quelques commentaires:

$/ = $,;               # 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

L'ORS, $ \ est ajouté automatiquement à chaque appel à imprimer, en mettant le nombre total à la fin.

skibrianski
la source
Il y avait 66 personnages lors de ma première passe. Merci à Heiko Oberdiek d'avoir montré que vous pouvez supprimer $ / avec moins de caractères en le définissant sur $, =)
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])

Exécutez-le ici: http://repl.it/8CH

mbomb007
la source
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+]
]

Exemple d'utilisation (dans la console Rebol):

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

NB. Le programme ignore les espaces, les tabulations et les nouvelles lignes des décomptes.

draegtun
la source
0

J - 46 + 46 = 92

Compte les espaces blancs, vous ne pouvez donc pas effectuer d'autotest sans modification. Prend une entrée sur stdin. A une mauvaise bouche, devrait aller le laver avec du savon.

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

Usage:

   ;":&.>(+/;' + ';(#-+/);' = ';#)(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
algorithmshark
la source
0

Javascript - 76 (38 + 38)

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

Exemple d'entrée: http://stackexchange.com
Sortie:20 + 4 = 24

Courir sur soi:

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 Pour ceux soucieux (o + $)de maintenir l'équilibre alphanumérique, ce n'est pas le cas. Parce qu'après avoir vu o + " + "JS, tout serait décidé +comme étant des concaténateurs de chaînes plutôt que des additionneurs de nombres. Ainsi, les parenthèses sont nécessaires, ou20 + 4 deviendraient 204plutôt que 24: D

Codage heureux!

Gaurang Tandon
la source
0

Clojure: (31 + 31 = 62) caractères non blancs

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

Production:

alphabalance.core=> (ff "http://stackexchange.com")
"20 + 4 = 24"
Jarlax
la source
0

CJam, 27 + 27 = 54

CJam est quelques mois plus récent que ce défi, donc cette réponse n'est pas éligible pour la coche verte. C'était quand même un exercice amusant!

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

Il prend la chaîne d'entrée comme argument de ligne de commande, il ne fonctionnera donc pas dans l'interpréteur en ligne, mais vous pouvez le tester avec l' interpréteur Java .

Explication

"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
la source