Balance alfanumérico

15

Escriba un programa que obtenga una cadena como entrada y cuente la cantidad de caracteres alfanuméricos y no alfanuméricos que contiene. Tiene que mostrar su resultado así:

entrada: http://stackexchange.com
salida:20 + 4 = 24

El problema es que su código fuente debe tener el mismo número de caracteres alfanuméricos que los no alfanuméricos. No se permiten comentarios, se ignora el espacio en blanco. (El lenguaje llamado Whitespace podría competir por votos, pero obviamente no será seleccionado como ganador)

Los caracteres en el código deben tener al menos alguna justificación menor, no deben ser completamente superfluos. Por ejemplo, se permiten nombres de variables más largos, en i = (j*3)+4;lugar de i = j*3+4;también. Sin embargo, i = i + 1;;;;;;no lo es.

Además de esto, se aplican las reglas estándar de código de golf.

vsz
fuente
Si defino una nueva variante, preprocesado de Ook donde las palabras clave son O., O?y O!a continuación, cualquier programa que cumple con la restricción de escritura clase de caracteres ... Por supuesto, es probable que pierda en el negocio de longitud.
dmckee --- ex-gatito moderador
2
¿será todo ascii?
Jordon Biondo
@JordonBiondo: Estaba pensando en cualquier cosa que desee, desde el ANSI completo de 8 bits hasta el Unicode, pero si su código solo admite ASCII de 7 bits, lo aceptaré también.
vsz
3
¿Se cuenta el espacio en blanco dentro de la cadena de salida en los no alfanuméricos? ¿O ignorado con todos los otros espacios en blanco (no literal de cadena)?
Kninnug
1
@dmckee: si va a definir su propio idioma, simplemente defina una variante del idioma de su elección donde los programas no vacíos funcionan igual que en el idioma base, pero el programa vacío se procesa previamente en un código que hace exactamente lo que el pregunta pide.
user2357112 es compatible con Monica

Respuestas:

8

Perl, 32 + 32 = 64

La cadena se espera en STDIN. La salida se escribe en STDOUT. El espacio en blanco se ignora. Mi interpretación de la tarea es que el programa debería poder ejecutarse solo para obtener el puntaje.

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

Ungolfed con comentarios

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

Encontré varias variaciones con el mismo número de bytes, por ejemplo:

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

Ejemplos

  • Ejemplo de la pregunta:

    echo 'http://stackexchange.com' | perl a.pl
    20 + 4 = 24
  • Corriendo sobre sí mismo ( a.pl):

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

    El tamaño del archivo es 104 bytes, por lo que 40 bytes se ignoran como espacios en blanco.

Perl, 29 + 29 = 58

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

La cadena se espera en STDIN y está limitada a la primera línea. El resultado se imprime en STDOUT. El espacio en blanco se ignora.

Sin 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
      ' = '

Ejemplos

El archivo a.plcontiene el script Perl.

  • Ejemplo de la pregunta:

    echo 'http://stackexchange.com' | perl a.pl
    20 + 4 = 24
  • Corriendo sobre sí mismo:

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

    El tamaño del archivo a.ples de 65 bytes, por lo tanto, 7 bytes se ignoran como espacios en blanco.

Heiko Oberdiek
fuente
Parece que está asumiendo que la entrada está en una sola línea ... ¿No vi nada al respecto en la especificación? Además, ¿cuál es la justificación para el indicador / x en el primer reemplazo?
skibrianski
@skibrianski: (a) La pregunta no es muy clara acerca de la especificación de "cadena". Ahora he agregado una variante que puede leer archivos completos. (b) Tampoco está claro para mí, cómo el guión debe tratar el espacio en blanco. Mi interpretación es que el espacio en blanco se ignora tanto en la tarea como en la puntuación. (c) La bandera / x permite espacios en blanco en el patrón para aumentar la legibilidad. La respuesta actualizada la utiliza.
Heiko Oberdiek
Re a), el autor no dice nada sobre lo que habrá en la cadena, por lo que supongo que no es prudente hacer suposiciones, lo que para mí significa que se deben permitir nuevas líneas. Re b) de acuerdo, no está claro. Re c) Correcto, pero en su respuesta el espacio en blanco no agrega legibilidad a mi ojo, solo agrega un carácter alfanumérico ... Tal vez estoy siendo demasiado duro en este punto, pero me revela que solo usa / x en una de sus expresiones regulares, presumiblemente para agregar ese último alfanumérico adicional para que los recuentos se alineen =) Todavía me gusta su respuesta. Cociné algo bastante similar.
skibrianski
jaja ahora tenemos un código esencialmente idéntico =) buen espectáculo =)
skibrianski
@skibrianski: :-) Gracias, me das una razón para publicar una de las otras variantes con un poco más de diferencias. Sin embargo, el recuento de bytes permanece.
Heiko Oberdiek
6

C - 96 (48 + 48) caracteres

Es algo legible. Sin embargo, hay margen de mejora.

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

Bash + coreutils, 72 caracteres (36 + 36) sin espacios en blanco

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

Salida:

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

Respuesta anterior:

Pure Bash, 92 (46 + 46) caracteres que no son espacios en blanco

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

Salida:

$ ./alnumbalance.sh http://stackexchange.com 
20 + 4 = 24
$ ./alnumbalance.sh "$ (cat alnumbalance.sh)"
46 + 46 = 92
PS 
Trauma digital
fuente
Woohoo: ¡incluso supera a golfscript ! ;-)
Digital Trauma
¿Qué pasa con los personajes de control? [: alnum:] no es el inverso de [: punct:]. Pruebe, por ejemplo, head -c256 / dev / urandom | tr -d [: alnum:] [: punct:]
skibrianski
@skibrianski buen punto. He editado la respuesta para tener esto en cuenta.
Digital Trauma
3

PowerShell (43 + 43 = 86)

Golfed

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

Sin 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)"
}

Prueba

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

Prueba con el código en sí para pasar los criterios

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

" se ha escapado con `que no es parte de la cadena.

microbiano
fuente
2

GolfScript, 74 caracteres (= 37 + 37)

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

Prueba en línea para el código con el código como entrada.

Howard
fuente
2

Rubí 38 + 38 = 76

Este programa cuenta la nueva línea final en la entrada.

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

El recuento de caracteres lo realiza el propio programa: $ ruby alphabalance.rb alphabalance.rb:)

daniero
fuente
2

Powershell, 70 bytes (= 35 + 35)

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

Script de prueba:

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

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

Salida:

20+4=24
35+35=70

Powershell, 70 bytes (= 35 + 35), alternativa

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

Python 2 (60 + 60 = 120)

Difícil, probablemente hay margen de mejora. Como el hecho de que la función en sí misma se puede usar para evaluar su propio equilibrio alfanumérico.

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      

Prueba:

>>> f("http://stackexchange.com")
20 + 4 = 24
Willem
fuente
¿Qué versión de Python es esta?
Gigaflop
@Gigaflop lo edité. La declaración de impresión es solo Python 2, al igual que la sintaxis de retroceso repr.
mbomb007
1

C ++, 146 (73 + 73) 178 (89 + 89) caracteres que no son espacios en blanco #

Original incluido <algorithm>sin ninguna buena razón. 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));
??>

Solo estoy contando caracteres en las líneas después //Code itself starts here. En particular, esto significa no contar #include <string>. También cuento los trigrafos como tres caracteres cada uno, lo cual es quizás discutible. Tenga en cuenta que al probar el programa en su propio código fuente se requiere cierto cuidado para evitar el reemplazo de trigraph dentro del literal de cadena.

Aquí hay algunas decisiones de diseño peculiares: en la mayoría de los códigos de producción no encontrará trigrafos y bucles basados ​​en rango en la misma función, pero creo que todo está dentro de los límites de 'justificable'.

usuario19057
fuente
1

pitón 52 +52 = 104

Desafío interesante porque python evita caracteres no alfanuméricos.

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

Justificación menor para usar el corte: lo acelera (¿tal vez?)

qwr
fuente
Intenta usar Python 2, ya printque no requiere paréntesis, y usa el '%d + %d = %d' % (a,l-a,l)método. Eso debería salvar a algunos personajes.
mbomb007
1

Julia, 64

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

Todos los únicos caracteres no alfanuméricos innecesarios son el último ;y algunos de los ()del formato de cadena., Salió casi perfectamente equilibrado, y como una potencia de 2 sin mucho violín.

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
fuente
1

perl, 64 caracteres que no son espacios en blanco:

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

Aclarado ligeramente a través de perl -MO = Deparse y algunos comentarios:

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

El ORS, $ \ se agrega automáticamente en cada llamada a imprimir, colocando el recuento total al final.

skibrianski
fuente
Tenía 66 personajes en mi primer pase. Gracias a Heiko Oberdiek por mostrar que puede desactivar $ / con menos caracteres estableciéndolo en $, =)
skibrianski
1

Pitón 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])

Ejecútelo aquí: http://repl.it/8CH

mbomb007
fuente
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+]
]

Ejemplo de uso (en la consola Rebol):

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

NÓTESE BIEN. El programa ignora espacios, pestañas y nuevas líneas de conteos.

draegtun
fuente
0

J - 46 + 46 = 92

Cuenta los espacios en blanco, por lo que no puede realizar una autocomprobación sin una modificación. Toma entrada en stdin. Tiene mala boca, debe ir a lavar con jabón.

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

Uso:

   ;":&.>(+/;' + ';(#-+/);' = ';#)(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
Algoritmo de tiburón
fuente
0

Javascript - 76 (38 + 38)

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

Entrada de muestra: http://stackexchange.com
Salida:20 + 4 = 24

Corriendo en uno mismo:

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

PD Para aquellos preocupados por (o + $)hacer para mantener el equilibrio alfanumérico, no es así. Porque después de ver a o + " + "JS, todos decidirían +ser concatenadores de cadenas en lugar de sumadores numéricos. Por lo tanto, los paréntesis son necesarios, o 20 + 4se convertirían204 lugar de 24: D

¡Feliz codificación!

Gaurang Tandon
fuente
0

Clojure: (31 + 31 = 62) caracteres que no son espacios en blanco

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

Salida:

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

CJam, 27 + 27 = 54

CJam es un par de meses más nuevo que este desafío, por lo que esta respuesta no es elegible para la marca de verificación verde. ¡Sin embargo, fue un ejercicio divertido!

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

Toma la cadena de entrada como un argumento de línea de comandos, por lo que no funcionará en el intérprete en línea, pero puede probarlo con el intérprete de Java .

Explicación

"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
fuente