Eliminar más de n vocales consecutivas de la cadena de entrada

19

No me gustan las cuerdas con más de tres vocales seguidas. ¿Puedes escribir un programa que elimine todas las vocales que no quiero de las palabras?

Puede escribir un programa o función, tomando la entrada a través de STDIN (o la alternativa más cercana), argumento de línea de comando o argumento de función y generando el resultado a través de STDOUT (o la alternativa más cercana), el valor de retorno de la función o el parámetro de función (out).

La entrada es una cadena que contiene solo caracteres ASCII imprimibles (0x20 a 0x7E, inclusive).

La salida es una cadena que contiene solo corridas de como máximo 3 vocales consecutivas. Si hay una ejecución de más de 3 vocales consecutivas en la cadena de entrada, su programa debe producir una cadena de salida que incluya las primeras tres vocales encontradas en esa ejecución, descartando cualquier otra vocal consecutiva.

Y no es una vocal para los propósitos de este desafío.

Este es el código de golf, por lo que gana el código más corto (en bytes).

Casos de prueba

"Aeiou" => "Aei"
"screeeen" => "screeen"
"We're queueing up for the Hawaiian movie." => "We're queung up for the Hawaiin movie."
"Spaces break runs: aei iou." => "Spaces break runs: aei iou."
Joseph Weissman
fuente
2
Debe incluir algunas pruebas más con casos mixtos, como aaYYAAaaaAERGH.
Zgarb

Respuestas:

5

Pyth, 21 bytes

sfg3=Z&}rT0"aeiou"hZz

Pruébelo en línea: Demostración o conjunto de pruebas

Explicación:

Repito todos los caracteres y hago un seguimiento de cuántas vocales pasé usando un contador. Cada vez que paso un carácter, que no es una vocal, restablezco el contador a 0. Revoco los caracteres, siempre que el contador sea> 4.

sfg3=Z&}rT0"aeiou"hZz   implicit: z = input string
                                  Z = 0
 f                  z   test every char T in z; keep chars, that return true:
        rT0                convert T to lower
       }   "aeiou"         test if T is a vowel
      &           hZ       logical and with Z+1, 
                           gives 0 if ^ is false, otherwise Z+1
    =Z                     update Z with this value
  g3                       test if 3 >= Z
s                       sum up all remaining chars and print
Jakube
fuente
10

Ilegible , 1647 bytes

'"" "" "'" "'" "" "" "'" "" '"" "" "" "" "" "" "" "" "" "" "" "" "'" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" ""' "" "" "" "'" "" "" "" "" "" "" "" "'" """" "" "'" "" "" "" "'" "" "" "" '"" "" "" "" "" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" "" "" "" "" '"" "" "" "'" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" ""' "" "" "" "" "" "" "" "" "" "" """" "'" "" "" "" "" "" "" "" "'" "" "" "" '"" "" "" "" "" "" "" ""' " "" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'" "" "" " "" '"" "" "" ""' "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" """'" "" "" "" "'" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" "" "" "" " "" "" "'" "" "" "" "'" "" "" "" '"" "" "" "" "" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" "" "" "" "" '"" "" "" "'" "" "" "" "'"" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""' "" "" " "" "'" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" "" "" "'" "" "" "" "" '"" "" ""' "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "'" "" "" ""' "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" ""' "" "" "" '"" "'" "" "" "" "'" "" "" "'" ""' "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" ""' "" """" "" '"" "" "" "" "" "" "" "'" "" "" "" "" "" "'" "" ""' "" "'" "" "" "" "'" "" "" "" "'" "" "" "" '"" "" "" "" "" "" "" ""' "" "" "" "" '"" "" "" "'" "" "" "" "" "" "'" "" "" "" "" "" "" "" ""' "" """ "" "'" "" "" "" "'" "" "" "" '"" "" "" "" "" "" "" ""' "" "" "" "" '"" "" "" ""' "" "" "" "" "" "" "" "" '"" "" "" "'" "" "" "" "" "" "" "" "'" ""' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'"" "" "" ""' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "'" "" "" "" "'" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" ""' "" "' "" "" "" "" "'" "" "" "'" "" "" "" "" "" '"" "" "" "" "" "" "" """'" "" "" "" "'" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" "" "" "" " '"" "" "" ""' "" "" "" "" "" "" "" "" '"" "" "" "'" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'" "" '"" "'" ""' "" "'" ""' "" "'" ""' "" "" "" "" "" "" "" "" "" "" "" "" "" '""' "" "'" "" "" "" "" "" "" ""' "" '"" "" "" "" "" ""' "" '""' "" "'" "" "" "'" "'" ""' "" '"" "" ""' "" '"" "'" "" "'"' "" "" """ '""' "" '"" "'" "" "" "'" "'" "" '"" "" "" ""' "" "

Explicación

Este programa es equivalente a un pseudocódigo como este:

while (cp = (ch = read)) + 1 {
    (
        (cp -= 65) ?    // A
            (cp -= 4) ?     // E
                (cp -= 4) ?     // I
                    (cp -= 6) ?     // O
                        (cp -= 6) ?     // U
                            (cp -= 12) ?    // a
                                (cp -= 4) ?     // e
                                    (cp -= 4) ?     // i
                                        (cp -= 6) ?     // o
                                            (cp - 6) ?      // u
                                                0
                                            : 1
                                        : 1
                                    : 1
                                : 1
                            : 1
                        : 1
                    : 1
                : 1
            : 1
        : 1
    ) ? ((--vs)+4) ? print(ch) : (++vs) : {
        print(ch)
        vs = 0
    }
}

con las siguientes asignaciones variables:

0   (unused)   (13 bytes)
1   cp         ( 4 bytes; occurs 20× in the code)
2   vs         ( 7 bytes; occurs  5× in the code)
3   ch         (10 bytes; occurs  3× in the code)

Como puede ver, evité la ranura variable 0 porque 0es una constante muy larga para escribir.

Entonces leemos cada carácter y almacenamos el valor en ambos cpy ch. Lo modificaremos, cppero lo conservaremos chpara poder imprimirlo si es necesario. Seguidamente restamos los números 65, 4, 4, 6, etc. cppara verificar si se trata de cada uno de los 10 posibles caracteres vocales en ASCII (tenga en cuenta que el último no necesita ser una asignación).

vssiempre contiene 3 menos que el número de vocales que aún se pueden imprimir. Comienza en 0, por lo que se pueden imprimir 3 vocales. Cuando llega -3, dejamos de imprimir vocales.

Si nos encontramos con una no vocal (incluido el espacio), ejecutamos print(ch)seguido de vs = 0. Como probablemente haya adivinado, esto restablece el contador de vocales.

Si encontramos una vocal , ejecutamos ((--vs)+4) ? print(ch) : (++vs). Analicemos esto:

  • disminuir vs;
  • si el valor es ahora -4, hemos ido demasiado lejos, así que no imprima nada, pero incremente de vsnuevo para -3que sigamos negándonos a imprimir vocales;
  • de lo contrario, imprime el personaje.
Timwi
fuente
1
Este lenguaje es fiel a su nombre.
bkul
2
Siempre me pregunto en estos idiomas ... "¿Realmente escribieron esto a mano? Si es así, me da pena ..." +1
Addison Crump
9

Retina , 25 bytes

i`([aeiou]{3})[aeiou]+
$1

Pruébalo en línea.

Sustitución de expresiones regulares bastante sencilla. Esto también funciona para el mismo número de bytes:

Ri`(?<=[aeiou]{3})[aeiou]
Martin Ender
fuente
3
¡Finalmente! Un intérprete en línea! Deberías considerar vincularlo en tu página de Github.
mbomb007
6

JavaScript (ES6), 42

Como una función anónima

s=>s.replace(/[aeiou]+/gi,v=>v.slice(0,3))
edc65
fuente
4

Perl, 27 caracteres.

(Código de 26 caracteres + opción de línea de comando de 1 carácter)

s/[aeiou]{3}\K[aeiou]+//gi

No es gran cosa, solo una rara ocasión que recuerdo \Kexiste.

Ejecución de muestra:

bash-4.3$ perl -pe 's/[aeiou]{3}\K[aeiou]+//gi' <<< "
> Aeiou
> screeeen
> We're queueing up for the Hawaiian movie.
> Spaces break runs: aei iou."

Aei
screeen
We're queung up for the Hawaiin movie.
Spaces break runs: aei iou.
hombre trabajando
fuente
2
Cuando escribí la respuesta de Retina pensé: "Me gustaría que .NET regex tuviera \K". :)
Martin Ender
Interesante, @ MartinBüttner. Tenía la sensación de que esas expresiones regulares se ponían en una dieta seria de esteroides. Por curiosidad, ¿tienen subpatrón recursivo? Puede ayudar a las piezas de enumeración vocal uno, aunque el resultado es más largo: s/([aeiou]{1,3})(?1)+/$1/gi.
manatwork
Desafortunadamente, tampoco tienen reutilización de patrones. Esas son las dos cosas que ocasionalmente me hacen cambiar a Perl o PCRE. Cuando llegue a parchear algunas cosas simples en el sabor regex de Retina, creo que las agregaré (no es una verdadera recursión, pero al menos la reutilización de patrones y la recursividad finita).
Martin Ender
2

En serio, 34 bytes

,;ù0╗`Ok"aeiou"Okd-Y;╜+*;╗4>`M@░εj

Hex Dump:

2c3b9730bb604f6b226165696f75224f6b
642d593bbd2b2a3bbb343e604d40b0ee6a

Pruébalo en línea

Utiliza el mismo algoritmo que la respuesta de Pyth, mapea sobre la cadena mientras realiza un seguimiento de la longitud de la ejecución actual de vocales en un registro, incrementándola cada vez que el carácter actual es una vocal y verificando si ha excedido la longitud permitida, devolviendo 0 si es así, y luego filtrando la cadena original con este filtro generado. Será mucho más corto una vez que podamos usar la resta de conjuntos en las cadenas. (Se Okpuede eliminar y Okdse puede reemplazar por solo @). Escuché que esta característica llegará en la próxima actualización ...

quintapia
fuente
2

C, 166 bytes

No es la respuesta más corta con diferencia, pero creo que muy bien ...

#define V v[1][i]!=
#define P printf("%c",v[1][i]),j
j;main(i,v)char**v;{for(i=0;V 0;i++)(V 97&V 'e'&V 'i'&V 'o'&V 'u'&V 65&V 69&V 73&V 79&V 85)?P=0:j>3?j++:P++;}

caso de prueba:

$ a.exe "We're queueing up for the Hawaiian movie."

We're queung up for the Hawaiin movie.

$ wc -c vowels.c 

166 vowels.c
cleblanc
fuente
2

Mathematica, 68 bytes

a=Characters@"aeiouAEIOU";StringReplace[#,b:a~Repeated~{3}~~a..:>b]&

La respuesta regex tendría la misma longitud, pero ¿quién usa regex?

LegionMammal978
fuente
2

Java, 115 bytes

class a{public static void main(String[] a){System.out.println(a[0].replaceAll("(?i)([aeiou]{3})[aeiou]*","$1"));}}

Espera entrada como parámetro del programa.

Salida de prueba de la unidad:

Aei
screeen
We're queung up for the Hawaiin movie.
Tomás Langer
fuente
Ahorre un byte eliminando el espacio entre String[]y a. String[]a
Poke
Ahorre 2 bytes utilizando en printlugar de println. No creo que la especificación requiera una nueva línea final.
Poke
2

APL, 40 caracteres

{⍵/⍨1↓4≠⊃+/(1-⍳4)⌽¨⊂'aeiouAEIOU'∊⍨' ',⍵}

En inglés:

  • 'aeiouAEIOU'∊⍨' ',⍵: encuentra las vocales (y antepone un espacio para romper en la rotación);
  • (1-⍳4)⌽¨⊂: rotar 0, 1, 2, 3 veces (con envoltura) empujando hacia la derecha el vector booleano;
  • ⊃+/ sum: las rotaciones y unbox
  • 1↓4≠: encuentre el diferente de 4 y elimine el primero (para ocupar el espacio que anteponemos)
  • ⍵/⍨: en el argumento, mantenga solo el elemento donde la suma fue diferente de 4.
lstefano
fuente
1

Perl 6 ,  36  35 bytes

{S:g:i/(<[aeiou]>**3)<[aeiou]>+/$0/} # 36 bytes

$ perl6 -pe 's:g:i/(<[aeiou]>**3)<[aeiou]>+/$0/' # 34 + 1 = 35 bytes

uso:

$ perl6 -pe 's:g:i/(<[aeiou]>**3)<[aeiou]>+/$0/' <<< "
> Aeiou
> screeeen
> We're queueing up for the Hawaiian movie.
> Spaces break runs: aei iou."
Aei
screeen
We're queung up for the Hawaiin movie.
Spaces break runs: aei iou.
Brad Gilbert b2gills
fuente
1

C (205 bytes)

#include <stdio.h>
#define T(x)for(i=0;i<10;++i){if(v[i]==x){b=x;m=1;break;}}putchar(c);
main(b,c,i,m){char v[]="aeiouAEIOU";
while((c=getchar())!=EOF){if(!m){T(c);}else{if(b==c)continue;else{m=0;T(c);}}}}

(Se agregó un salto de línea para mayor claridad)

musaritmia
fuente
1

Scala, 107 bytes

readLine.foldLeft("",0)((a,n)=>if(!"aeiou".contains(n|32))a._1+n->0 else if(a._2>2)a else(a._1+n,a._2+1))_1
Ruslan
fuente
1

Javascript ES6, 43 caracteres

s=>s.replace(/([aeiou]{3})[aeiou]*/gi,"$1")

Prueba:

f=s=>s.replace(/([aeiou]{3})[aeiou]*/gi,"$1")
;`"Aeiou" => "Aei"
"screeeen" => "screeen"
"We're queueing up for the Hawaiian movie." => "We're queung up for the Hawaiin movie."
"Spaces break runs: aei iou." => "Spaces break runs: aei iou."`
.replace(/"/g,"").split("\n").every(s=>f((s=s.split(" => "))[0])==s[1])
Qwertiy
fuente
1

Archivo x86 MS-DOS .COM , 44 bytes 36 bytes

Los archivos .COM son ampliamente compatibles desde MS-DOS 1 hasta el presente --- Estoy ejecutando en dosemu, usando solo los comandos 8086.

Reducido de 44 a 36 bytes usando REPNE SCASB para probar vocales en lugar de usar un comando separado para probar cada vocal.

Hex dump, reversible using `xxd -r -seek -256`:
0100: b3 03 43 b4 08 cd 21 88 c2 24 df b1 05 bf 1f 01   ..C...!..$......
0110: f2 ae 74 02 b3 05 4b 74 e9 b4 02 cd 21 eb e4 41   ..t...Kt....!..A
0120: 45 49 4f 55                                       EIOU

Unassembled using debug:
0100 B303    MOV BL,03     ; initialize counter to 3 (will increment by 1 to be 4)
0102 43      INC BX        ; increment counter--runs each time it hits 0 so it never goes <0
0103 B408    MOV AH,08     ; 
0105 CD21    INT 21        ; with AH=8, read 1 char without echo
0107 88C2    MOV DL,AL     ; copy input for potential output
0109 24DF    AND AL,DF     ; make input uppercase for testing
010B B105    MOV CL,05     ; count of 5 vowels to test against
010D BF1F01  MOV DI,011F   ; location of first vowel to test against
0110 F2AE    REPNE SCASB   ; test input against each vowel
0112 7402    JZ 0116       ; if input was not a vowel:
0114 B305    MOV BL,05     ;    reset counter to 5 (will decrement by 1 to be 4)
0116 4B      DEC BX        ; decrement counter regardless
0117 74E9    JZ 0102       ; if hit 0 (fourth or later vowel): goto 102
0119 B402    MOV AH,02     ; 
011B CD21    INT 21        ; with AH=2, print char
011D EBE4    JMP 0103      ; go to 103 for next character

bytes 011f-0123 contain the uppercase vowels AEIOU
krubo
fuente
1

Matlab / Octave, 54 bytes

@(s)regexprep(s,'(?<=[aeiouAEIOU]{3})[aeiouAEIOU]','')

Ejemplo:

>> @(s)regexprep(s,'(?<=[aeiouAEIOU]{3})[aeiouAEIOU]','')
ans = 
    @(s)regexprep(s,'(?<=[aeiouAEIOU]{3})[aeiouAEIOU]','')

>> ans('We''re queueing up for the Hawaiian movie.')
ans =
We're queung up for the Hawaiin movie.

Pruébalo en ideone .

Luis Mendo
fuente
1

V , 21 bytes (sin competencia)

ñ[aeiou]ñÍãqû3}úsq*

Pruébalo en línea!

Explicación:

ñ[aeiou]ñ                     "Assign the string `[aeiou]` to register 'q'
         Íã                   "Search and replace on multiple lines (case insensitive):
           <C-r>q             "Register 'q'
                 û3}          "Repeated 3 times
                    ús        "Mark the following to be removed:
                      <C-r>q* "Register 'q' repeated any number of times

Esto es apenas más corto que la solución más sencilla:

Íã[aeiou]û3}ús[aeiou]*

(22 bytes)

DJMcMayhem
fuente
0

Ruby, 44 bytes

><<$<.read.gsub(/([aeiou]{3})[aeiou]+/i,'\1')

Ejemplo:

% ruby -e "$><<$<.read.gsub(/([aeiou]{3})[aeiou]+/i,'\1')" <<< "
Aeiou
screeeen
We're queueing up for the Hawaiian movie.
Spaces break runs: aei iou."

Aei
screeen
We're queung up for the Hawaiin movie.
Spaces break runs: aei iou.
Joseph Weissman
fuente
Lo escribió: "La entrada es una cadena que contiene solo caracteres ASCII imprimibles (0x20 a 0x7E, inclusive)". Entonces, ¿por qué gastar caracteres adicionales $<.readpara que maneje la entrada multilínea (por lo tanto, contiene caracteres fuera de rango 0x0a) en lugar de gets?
manatwork
@manatwork es un muy buen punto, ¡gracias! Creo que podría ahorrar 2-3 bytes :)
Joseph Weissman