Balanço alfanumérico


15

Escreva um programa que receba uma string como entrada e conte o número de caracteres alfanuméricos e não alfanuméricos nele. Ele deve exibir seu resultado assim:

entrada: http://stackexchange.com
saída:20 + 4 = 24

O problema é que seu código-fonte precisa ter o mesmo número de caracteres alfanuméricos que os caracteres não alfanuméricos. Comentários não são permitidos, espaço em branco é ignorado. (O idioma chamado espaço em branco pode competir por votos, mas não será selecionado como vencedor, obviamente)

Os caracteres no código devem ter pelo menos algumas justificativas menores, eles não devem ser completamente supérfluos. Por exemplo, nomes de variáveis ​​mais longos são permitidos, em i = (j*3)+4;vez de i = j*3+4;também são permitidos. No entanto, i = i + 1;;;;;;não é.

Além disso, aplicam-se regras padrão de código-golfe.


Se eu definir uma nova variante, pré-processados de Ook onde as palavras-chave são O., O?e, O!em seguida, qualquer gravação programa que eu atenda a restrição classe de personagem ... Claro que é provável que perca no negócio do comprimento.
dmckee --- ex-moderador gatinho

2
tudo será ascii?
Jordon Biondo

@JordonBiondo: Eu estava pensando em qualquer coisa que você queira, desde o ANSI de 8 bits completo até o unicode, mas se o seu código suportar apenas ASCII de 7 bits, eu também o aceitarei.
vsz 14/03

3
O espaço em branco dentro da sequência de saída é contado nos não alfanuméricos? Ou ignorado com todos os outros espaços em branco (não literal de cadeia de caracteres)?
Kninnug

1
@dmckee: Se você definir sua própria linguagem, defina apenas uma variante da linguagem de sua escolha, na qual programas não vazios funcionam exatamente como na linguagem base, mas o programa vazio é pré-processado em código que faz exatamente o que o pergunta pede.
User2357112 suporta Monica

Respostas:


8

Perl, 32 + 32 = 64

A sequência é esperada em STDIN. A saída é gravada em STDOUT. O espaço em branco é ignorado. Minha interpretação da tarefa é que o programa deve ser capaz de rodar sozinho para obter a pontuação.

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

Ungolfed com comentários

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

Encontrei várias variações com a mesma contagem de bytes, por exemplo:

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

Exemplos

  • Exemplo da pergunta:

    echo 'http://stackexchange.com' | perl a.pl
    20 + 4 = 24
  • Executando em si mesmo ( a.pl):

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

    O tamanho do arquivo é 104 bytes, portanto, 40 bytes são ignorados como espaço em branco.

Perl, 29 + 29 = 58

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

A sequência é esperada em STDIN e é limitada à primeira linha. O resultado é impresso em STDOUT. O espaço em branco é ignorado.

Ungolfed

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

Exemplos

O arquivo a.plcontém o script Perl.

  • Exemplo da pergunta:

    echo 'http://stackexchange.com' | perl a.pl
    20 + 4 = 24
  • Executando em si mesmo:

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

    O tamanho do arquivo a.plé de 65 bytes, portanto, 7 bytes são ignorados como espaço em branco.


Parece que você está assumindo que a entrada está em apenas uma linha ... Eu não vi nada sobre isso nas especificações? Além disso, qual é a justificativa para o sinalizador / x na primeira substituição?
skibrianski

@skibrianski: (a) A questão não é muito clara sobre a especificação de "string". Agora eu adicionei uma variante que pode ler arquivos inteiros. (b) Também não está claro para mim como o espaço em branco deve ser tratado pelo script. Minha interpretação é que o espaço em branco é ignorado na tarefa e na pontuação. (c) O sinalizador / x permite espaço em branco no padrão para aumentar a legibilidade. A resposta atualizada faz uso dela.
Heiko Oberdiek

Re a), o autor não diz nada sobre o que estará na string, então acho que não é sensato fazer suposições, o que para mim significa que novas linhas devem ser permitidas. Re b) concordou, não está claro. Re c) Certo, mas na sua resposta o espaço em branco não acrescenta legibilidade aos meus olhos, apenas adiciona um caractere alfanumérico ... Talvez eu esteja sendo muito duro nesse ponto, mas está me revelando que você só usa / x em uma de suas expressões regulares, presumivelmente para adicionar esse último alfanumérico extra para alinhar as contagens =) Ainda gosto da sua resposta. Eu cozinhei algo bem parecido.
skibrianski

haha agora temos código essencialmente idêntica =) bom show =)
skibrianski

@skibrianski: :-) Obrigado, você me deu um motivo para postar uma das outras variantes com um pouco mais de diferença. No entanto, a contagem de bytes permanece.
Heiko Oberdiek 15/03

6

Caracteres C - 96 (48 + 48)

É um pouco legível. Há espaço para melhorias, no entanto.

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

5

Bash + coreutils, 72 (36 + 36) caracteres não em branco

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

Resultado:

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

Resposta anterior:

Pure Bash, 92 (46 + 46) caracteres não em branco

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

Resultado:

$ ./alnumbalance.sh http://stackexchange.com 
20 + 4 = 24
$ ./alnumbalance.sh "$ (gato alnumbalance.sh)"
46 + 46 = 92
$ 

Woohoo - ainda bate golfscript ! ;-)
Trauma digital

E quanto aos caracteres de controle? [: alnum:] não é o inverso de [: punct:]. Tente, por exemplo, head -c256 / dev / urandom | tr -d [: alnum:] [: punct:]
skibrianski 15/03

@skibrianski good point. Editei a resposta para levar isso em consideração.
Digital Trauma

3

PowerShell (43 + 43 = 86)

Golfe

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

Sem golfe

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

Teste

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

Testando com o próprio código para passar os critérios

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

" foi escapado com `, que não faz parte da string.


2

GolfScript, 74 caracteres (= 37 + 37)

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

Teste online do código com o código como entrada.


2

Rubi 38 + 38 = 76

Este programa conta uma nova linha à direita na entrada.

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

A contagem de caracteres é feita pelo próprio programa: $ ruby alphabalance.rb alphabalance.rb:)


2

PowerShell, 70 bytes (= 35 + 35)

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

Script de teste:

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

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

Resultado:

20+4=24
35+35=70

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

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

2

Python 2 (60 + 60 = 120)

Difícil, provavelmente há espaço para melhorias. Assim como a própria função pode ser usada para avaliar seu próprio saldo 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      

Teste:

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

Que versão do Python é essa?
Gigaflop 11/12/19

@ Gigaflop eu editei. A instrução print é apenas Python 2, assim como a sintaxe de backtick para repr.
mbomb007

1

C ++, 146 (73 + 73) 178 (89 + 89) caracteres sem espaço em branco #

Original incluído <algorithm>sem motivo. Opa

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

Estou apenas contando caracteres nas linhas depois //Code itself starts here. Em particular, isso significa não contar#include <string> . Também estou contando trigramas com três caracteres cada, o que talvez seja discutível. Observe que, ao testar o programa em seu próprio código-fonte, é necessário algum cuidado para impedir a substituição do trigrafo na literal da string.

Existem algumas decisões de design peculiares aqui - na maioria dos códigos de produção, você não encontrará trigraphs e loops baseados em intervalo na mesma função - mas acho que tudo dentro dos limites de 'justificável'.


1

python 52 +52 = 104

Desafio interessante porque o python evita caracteres não alfanuméricos.

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

Justificativa menor para usar fatia: acelera (talvez?)


Tente usar o Python 2, pois printnão requer parênteses e use o '%d + %d = %d' % (a,l-a,l)método Isso deve salvar alguns caracteres.
mbomb007

1

Julia, 64

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

Todos os únicos caracteres não alfanuméricos desnecessários são os últimos ;e alguns dos que estão ()na formatação de string.

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"

1

perl, 64 caracteres não em branco:

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

Esclarecido um pouco via perl -MO = Deparse e alguns comentários:

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

O ORS, $ \ é anexado automaticamente em todas as chamadas para impressão, colocando a contagem total no final.


Tinha 66 caracteres no meu primeiro passe. Graças a Heiko Oberdiek para mostrar que você pode resetar $ / com menos caracteres, definindo-a $, =)
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])

Execute-o aqui: http://repl.it/8CH


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

Exemplo de uso (no console Rebol):

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

NB Programa ignora espaços, guias e novas linhas de contagens.


0

J - 46 + 46 = 92

Conta espaço em branco, para que você não possa fazer o autoteste sem uma modificação. Aceita stdin. Tem uma boca ruim, deve lavá-lo com sabão.

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

0

Javascript - 76 (38 + 38)

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

Entrada de amostra: http://stackexchange.com
Saída:20 + 4 = 24

Executando sozinho:

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 Para aqueles que se preocupam (o + $)em manter o equilíbrio alfanumérico, não é assim. Porque, depois de ver o o + " + "JS, todos decidiriam +ser concatenadores de strings, em vez de somadores de números. Assim, os parênteses são necessários, ou20 + 4 se tornariam, em 204vez de24 : D

Feliz codificação!


0

Clojure: (31 + 31 = 62) caracteres sem espaço em branco

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

Resultado:

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

0

CJam, 27 + 27 = 54

O CJam é um par de meses mais novo que esse desafio, portanto, essa resposta não é elegível para a marca de seleção verde. Mas foi um exercício divertido!

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

Ele usa a cadeia de entrada como argumento da linha de comando, para que não funcione no interpretador online, mas você pode testá-la com o interpretador Java .

Explicação

"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.";
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.