Perl: 8 o 10 caracteres distintos
s///
solución: 10 distintos, 13 en total
La técnica (supuesta; ver más abajo) sed siempre funciona también en perl, y produce el número de nombre de caracteres distintos (10):
s/[aeiou]//gi
Por ejemplo:
$ echo 'This program will remove VOWELS. So we can speak without them.' |
perl -ple 's/[aeiou]//gi'
Ths prgrm wll rmv VWLS. S w cn spk wtht thm.
Son 10 caracteres distintos, como lo demuestra:
$ echo 's/[aeiou]//gi' | perl -nle '@s{split//}=(); print scalar keys %s'
10
El problema con la solución de sed es que su /i
es no parte de POSIX sed, y por lo tanto no es portátil:
$ echo 'This program will remove VOWELS. So we can speak without them.' |
sed -e 's/[aeiou]//gi'
sed: 1: "s/[aeiou]//gi": bad flag in substitute command: 'i'
Eso se ejecuta en un sistema OpenBSD. Por el contrario, debido a /i
que siempre es parte del perl estándar, puede contar con que siempre esté allí. A diferencia de sed.
Si desea incluir "y" en la lista de vocales, es, por supuesto, una mayor si utiliza la misma técnica:
$ echo 'This nifty program remove any VOWELS. So we easily can speak without them.' |
perl -ple 's/[aeiouy]//gi'
Ths nft prgrm rmv n VWLS. S w sl cn spk wtht thm.
$ echo 's/[aeiouy]//gi' | perl -nle '@s{split//}=(); print scalar keys %s'
11
Y ahora son 14 caracteres en total.
tr[][]
solución: 8 distintos 10 en total
También puede usar tr///
para eliminar cualquier cosa que coincida. Perl incluso puede usar el y///
alias de sed para tr
:
y/aeiou//d
que ahora tiene 8 caracteres distintos, pero no funciona en mayúsculas. Termina teniendo que agregar 5 caracteres más para hacer frente a los mapas de casos:
$ echo 'y/aeiouAEIOU//d' | perl -nle '@s{split//}=(); print scalar keys %s'
13
y, por supuesto, ahora son 15 en total.
Sin embargo, agregar "y" a la mezcla como vocal no aumenta el número de caracteres distintos como lo hizo con la s///
versión:
$ echo 'This nifty program remove any VOWELS. So we easily can speak without them.' |
perl -ple 'y/aeiouy//d'
Ths nft prgrm rmv n VOWELS. S w sl cn spk wtht thm.
Así que sigue siendo solo el original 8 de un total de 11:
$ echo 'y/aeiouy//d' | perl -nle '@s{split//}=(); print scalar keys %s'
8
EDITAR : Contabilidad para diacríticos
¿Y qué hay de las entradas como Renée’s naïveté
? La salida correcta debería ser, por supuesto Rn’s nvt
. A continuación, le indicamos cómo hacerlo, utilizando el /r
indicador de v5.14 para s///
:
$ echo 'Renée’s naïveté' |
perl5.14.0 -CS -MUnicode::Normalize -nle 'print NFD($_)=~s/[aeiou]\pM*//rgi'
Rn’s nvt
Eso es 27 caracteres distintos:
$ echo 'print NFD($_) =~ s/[aeiou]\pM*//rgi' |
perl -nle '@s{split//}=(); print scalar keys %s'
27
Se puede recortar de que a 26 si se puede garantizar que se está ejecutando al menos v5.10 mediante el canje de la print
de say
:
$ echo 'Renée’s naïveté' |
perl -Mv5.14 -CS -MUnicode::Normalize -nlE 'say NFD($_) =~ s/[aeiou]\pM*//rgi'
Rn’s nvt
$ echo 'say NFD($_) =~ s/[aeiou]\pM*//rgi' |
perl -nle '@s{split//}=(); print scalar keys %s'
26
Y puede bajarlo a 22 si no le importa mover los diacríticos en lugar de eliminarlos:
$ echo 'Renée’s naïveté' |
perl -Mv5.14 -CS -MUnicode::Normalize -nlE 'say NFD($_) =~ s/[aeiou]//rgi'
Rń’s n̈vt́
Lo cual es ... interesante de ver, por decir lo menos. :) Aquí está su cuenta distinta:
$ echo 'say NFD($_) =~ s/[aeiou]//rgi' |
perl -nle '@s{split//}=(); print scalar keys %s'
22
¡Buena suerte con cualquier otro idioma para tratar adecuadamente los signos diacríticos con menos caracteres que este!