Agrupa las vocales de una cuerda

22

Descripción de la tarea

A veces, realmente necesitas adaptar algo que estás escribiendo en un espacio pequeño. Puede ser tentador abandonar las vocales y las palabras, y en su defecto, ¿quién realmente necesita espacios? Thssprfctlrdbl!

Escriba una función o programa que elimine las vocales en minúsculas aeiou, y luego los espacios, y luego los caracteres de una cadena de entrada . Además, cada vez que eliminas un personaje, debe ser el personaje más adecuado para eliminarlo. Debe repetir este proceso hasta que la cadena no supere una longitud de entrada determinada .

† “¡Esto es perfectamente legible!” Pero si estás leyendo esta nota al pie, probablemente no lo sea, realmente ... :)

Ejemplos

Aquí, puede ver este proceso aplicado para tamaños de entrada sucesivamente más pequeños:

23: Hello, Code Golf World!
22: Hello, Code Golf Wrld!
21: Hello, Code Glf Wrld!
20: Hello, Cod Glf Wrld!
19: Hello, Cd Glf Wrld!
18: Hell, Cd Glf Wrld!
17: Hll, Cd Glf Wrld!
16: Hll, Cd GlfWrld!
15: Hll, CdGlfWrld!
14: Hll,CdGlfWrld!
13: Hll,CdGlfWrld
12: Hll,CdGlfWrl
11: Hll,CdGlfWr
(etc.)

Después de apretar la cadena hasta 17 caracteres, nos quedamos sin vocales para eliminar, por lo que el siguiente carácter que eliminamos es el espacio más a la derecha; Cuando llegamos a 14 caracteres, hemos eliminado todas las vocales y espacios, por lo que simplemente comenzamos a masticar la cadena de derecha a izquierda.

Aquí hay un código pseudocódigo de Python que resuelve este desafío:

def crunch_string(string, to_length):
    while len(string) > to_length:
        # Store the best candidate index for deletion here.
        best = None

        # First, find the rightmost vowel's index.
        for i in range(len(string)):
            if string[i] in 'aeiou':
                best = i

        # If there were no vowels, find the rightmost space's index.
        if best is None:
            for i in range(len(string)):
                if string[i] == ' ':
                    best = i

        # If there were no spaces either, use the final index.
        if best is None:
            best = len(string) - 1

        # Remove the selected character from the string.
        string = string[:best] + string[best + 1:]

    # Return the string once `len(string) <= to_length`.
    return string

Reglas

  • Este es el , por lo que gana el código más corto en bytes.

  • La cadena de entrada consistirá en los caracteres ASCII imprimibles desde el espacio ( decimal 32) hasta tilde (inclusive ~, decimal 126). No habrá vocales mayúsculas AEIOUen la cadena. En particular, no habrá Unicode, pestañas o nuevas líneas involucradas.

  • Llame a la cadena de entrada s , y la longitud del objetivo de entrada t . Entonces 0 <t ≤ longitud ( s ) ≤ 10000 está garantizado. (En particular, la cadena de entrada nunca estará vacía. Si t = longitud ( s ), simplemente debe devolver la cadena sin modificar).

Casos de prueba

Input:  50, Duis commodo scelerisque ex, ac consectetur metus rhoncus.
Output: Duis commodo scelerisque ex, ac cnscttr mts rhncs.

Input:  20, Maecenas tincidunt dictum nunc id facilisis.
Output: Mcnstncdntdctmnncdfc

Input:  150, golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf
Output: glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glfglfglfglfglfglfglfglfglfglf
Lynn
fuente
55
Es yuna vocal?
edc65
1
¡No puedo creer que se me haya olvidado explicar eso! No, aeiouson vocales, y AEIOUno ocurrirán, por simplicidad. (Todo el asunto en mayúsculas / minúsculas no es en lo que quiero centrarme). Agregué una aclaración.
Lynn
1
Muy buen desafío!
Luis Mendo
@ edc65 No lo olvides w(por ejemplo, en la palabra co w , ¡ wes una vocal!) Por supuesto, eso está resuelto para este, pero para donde no se dice que el conjunto de vocales es aeiou, a veces debes incluir yy w. : -O
corsiKa
Sin relación con el golf, pero considere en for index, char in enumerate(string)lugar de la range(len(str))construcción
Jeremy Weirich

Respuestas:

6

MATL , 20 bytes

t11Y2mEG32=+K#Si:)S)

Pruébalo en línea!

t       % implicitly input string. Duplicate
11Y2    % predefined literal 'aeiou'
m       % ismember. Gives true for input characters that are vowels
E       % multiply by 2
G       % push input string again
32      % ASCII for space
=       % gives true for input characters that are spaces
+       % add: gives 2 for vowels, 1 for space, 0 for non-vowels-and-non space
K#S     % sort and push only the indices of the sorting. Sorting is stable, so first 
        % will be non-vowels-and-non space characters in their original order, then
        % spaces in their original order, then vowels in their original order
i       % input number n of characters that should be kept
:       % range [1,2,...,n]
)       % index with that: keep first n indices of the sorting
S       % sort those indices to restore their original order
)       % index into input string to keep only those characters. Implicitly display
Luis Mendo
fuente
11

Perl, 48 45 43 bytes

Incluye +4 para -Xlpi(-X puede omitirse pero deja advertencias feas en STDERR)

Ejecute con el número después de la -iopción y la entrada en STDIN (también admite varias líneas). p.ejperl -Xlpi50 crunch.pl <<< "Duis commodo scelerisque ex, ac consectetur metus rhoncus."

crunch.pl:

s/.*\K[aeiou]|.*\K |.$// while pos=-$^I
Ton Hospel
fuente
No necesita el espacio entre /$+/ywhile
hmatt1
Creo que afeita un byte utilizando un ^ I (carácter de tabulación) en lugar de "^ I". (Sin probar)
msh210
@chilemagic: soltando el espacio entre / $ + / y mientras solo funciona con perls más antiguos. Los perls recientes cambiaron el analizador para mantener abierta la capacidad de agregar nuevos modificadores de
expresiones
@ msh210: funciona para algunas variables mágicas, pero no para las basadas en espacios en blanco
Ton Hospel
6

JavaScript (ES6), 66 61 bytes

Guardado 5 bytes gracias a @Neil

f=(s,n)=>s[n]?f(s.replace(/(.*)[aeiou]|(.*) |.$/,"$1$2"),n):s

No creo que la expresión regular sea golfable aún más. Sorprendentemente, lo más corto que puedo encontrar para eliminar de adelante hacia atrás es un byte más largo:

f=(s,n)=>s[n]?f(s.replace(/(.*?)[aeiou]|(.*?) |./,"$1$2"),n):s

Intento más interesante (ES7), 134 bytes

(s,n,i=0)=>[for(c of s)[/[aeiou]/.test(c)*2+(c<'!'),i++,c]].sort(([x],[y])=>x-y).slice(0,n).sort(([,x],[,y])=>x-y).map(x=>x[2]).join``

Esto utiliza un enfoque similar a la respuesta MATL.

ETHproducciones
fuente
1
No me importa si no es golfable, es una hermosa expresión regular.
Neil
Aunque acabo de notar que puedes usar |.$/,"$1$2"para guardar 5 bytes.
Neil
@Neil ¡Gracias por el consejo!
ETHproductions
2

sh + gnu sed, 78 61

Proporcione la cadena a STDIN, la longitud como primer argumento.

rev|sed -r ":                       # reverse + invoke sed + jump label ":"
/..{$1}/!q                          # if the length is not greater $1, quit
p                                   # print
s/[aeiou]//                         # delete the first vowel
t                                   # if successful, start over at ":"
s/ //                               # delete the first space
t                                   # if successful, start over at ":"
s/.//                               # delete the first character
t"|rev                              # if successful, start over at ":" + reverse
Rainer P.
fuente
2

Lua, 120 bytes

s=arg[2]:reverse()a=s:len()-arg[1]s,n=s:gsub('[aeiou]','',a)s,m=s:gsub(' ','',a-n)print(s:gsub('.','',a-n-m):reverse())

Toma entrada como argumentos de línea de comando, en el formato lua crunch.lua 10 "This is a string", con salida Ths sstrng.

Explicación:

-- Set 's' to the reverse of the string
s=arg[2]:reverse()
-- Set 'a' to the number of characters to be removed
a=s:len()-arg[1]
-- Remove 'a' vowels, set 'b' to the number of substitutions
s,b=s:gsub('[aeiou]','',a)
-- Remove 'a-b' spaces, set 'c' to the number of substitutions
s,c=s:gsub(' ','',a-b)
-- Remove 'a-b-c' characters, and print the now un-reversed string
print(s:gsub('.','',a-b-c):reverse())
Jesse Paroz
fuente
1

Perl, 68

Al eliminar desde la derecha se agregan una tonelada de caracteres, tal vez haya una mejor manera de hacerlo.

$_=reverse;while(length>$^I){s/[aeiou]//||s/ //||s/.//}$_=reverse

Use -ipara ingresar el número. Es 65 caracteres más 3 para el i, py len la línea de comandos.

Corre con:

echo 'Hello, Code Golf World!' | perl -i13 -ple'$_=reverse;while(length>$^I){s/[aeiou]//||s/ //||s/.//}$_=reverse'
hmatt1
fuente
Puede usar en y///clugar de lengthy puede mover el ciclo while hasta el final:s///||s///||s///while$^I<y///c
andlrc
1

Java 8, 303 bytes

(s,j)->{String t="";for(int i=s.length()-1;i>=0;t+=s.charAt(i--));while(t.length()>j&&t.matches(".*[aeiou].*"))t=t.replaceFirst("[aeiou]","");while(t.length()>j&&t.contains(" "))t=t.replaceFirst("\\s","");s="";for(int i=t.length()-1;i>=0;s+=t.charAt(i--));return s.substring(0,Math.min(t.length(),j));};

Esto es demasiado largo. Trataré de acortarlo pronto. Sería mucho más corto si Java tuviera un método para invertir cadenas y reemplazos hacia atrás.

Prueba con lo siguiente:

public class StringCruncher {
    public static void main(String[] args) {
        Tester test = (s,j)->{String t="";for(int i=s.length()-1;i>=0;t+=s.charAt(i--));while(t.length()>j&&t.matches(".*[aeiou].*"))t=t.replaceFirst("[aeiou]","");while(t.length()>j&&t.contains(" "))t=t.replaceFirst("\\s","");s="";for(int i=t.length()-1;i>=0;s+=t.charAt(i--));return s.substring(0,Math.min(t.length(),j));};
        System.out.println(test.crunch("golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf", 150));
    }
}
interface Tester {
    String crunch(String s, int j);
}
GamrCorps
fuente
1
La mayoría decepcionante en meta dice que puede guardar un byte con curry
Cyoce
@Cyoce parece que curry no funciona en este caso ( s->j->{...}). Creo que Java no lo admite muy bien o lo estoy configurando mal.
GamrCorps
Es probable que los idiomas compilados tengan dificultades con el currículum debido a las funciones de primera clase
CalculatorFeline
@GamrCorps Comprobaré y veré si puedo hacer que funcione cuando llegue a casa
Cyoce
1

C #, 180 bytes

string c(int l,string s){while(s.Length>l){int i=0;Func<string,bool>f=t=>(i=s.LastIndexOfAny(t.ToCharArray()))!=-1;if(!(f("aeiou")||f(" ")))i=s.Length-1;s=s.Remove(i,1);}return s;}

Ensayador:

using System;
class Crunch
{
    static int Main()
    {
        var x = new Crunch();
        Console.WriteLine(x.c(50, "Duis commodo scelerisque ex, ac consectetur metus rhoncus."));
        Console.WriteLine(x.c(20, "Maecenas tincidunt dictum nunc id facilisis."));
        Console.WriteLine(x.c(150, "golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf"));
        Console.Read();
        return 0;
    }
    string c(int l,string s){while(s.Length>l){int i=0;Func<string,bool>f=t=>(i=s.LastIndexOfAny(t.ToCharArray()))!=-1;if(!(f("aeiou")||f(" ")))i=s.Length-1;s=s.Remove(i,1);}return s;}

    static string crunch(int len, string str)
    {
        Console.WriteLine($"{str.Length}: {str}");
        while (str.Length > len) {
            int idx=0;
            Func<string,bool> f = s => (idx = str.LastIndexOfAny(s.ToCharArray()))!= -1;
            if (!(f("aeiou") || f(" "))) idx = str.Length-1;
            str = str.Remove(idx,1);
            Console.WriteLine($"{str.Length}: {str}");
        }
        return str;
    }
}
DW.com
fuente
1

Scala, 160 bytes

type S=String;def f(s:S,l:Int)={def r(s:S,p:S):S=if(s.size>l){val j=s.replaceFirst("(?s)(.*)"+p,"$1");if(j==s)s else r(j,p)}else s;r(r(r(s,"[aeiou]")," "),".")}

Ensayador:

val t="Hello, Code Golf World!"
println((t.size to 11 by -1).map(f(t,_)).mkString("\n"))
claro
fuente
1

Dyalog APL, 77 45 42 bytes

t[⌽i~⌽⎕↓⌽∪∊(t∊'aeiou')(' '=t)1/¨⊂i←⍳⍴t←⌽⍞]

t[]Letras de t con índices ...
t←⌽⍞ t obtiene una entrada de texto invertida
i←⍳⍴t i obtiene índices de longitud de t
/¨⊂i múltiples (3) selecciones booleanas de elementos de i :
1. (t∊'aeiou')booleano donde vocal
2. (' '=t)booleano donde espacio
3. 1todos ∪∊únicos de los enlistados ( aplanado) 3 selecciones eliminan los
⌽⎕↓⌽últimos caracteres ingresados ​​evaluados (igual que (-⎕)↓)
⌽i~invierten los índices restantes después de eliminar algunos


Respuesta original:

⎕{⍺≥≢⍵:⌽⍵⋄∨/⍵∊⍨v←'aeiou':⍺∇⍵/⍨~<\(⍳⍴⍵)∊⍵⍳v⋄' '∊⍵:⍺∇⍵/⍨~<\(⍳⍴⍵)=⍵⍳' '⋄⍺∇1↓⍵}⌽⍞

Ehm, sí, eso es un poco difícil de leer. Básicamente, la traducción directa de OP a APL:

  1. Entrada inversa.
  2. Si la longitud requerida es mayor o igual al recuento de la cadena de entrada (invertida), entonces devuelva el argumento invertido (invertido).
  3. De lo contrario, si el argumento tiene alguna vocal, elimine la primera (es decir, la última) y recurra recursivamente a lo que queda.
  4. De lo contrario, si el argumento tiene algún espacio, elimine el primero (es decir, el último) y recurra recursivamente a lo que resta.
  5. De lo contrario, elimine el primer carácter (es decir, el último) y recurra recursivamente sobre lo que queda.
Adán
fuente
0

Mathematica, 201 Bytes

f@x_:=StringReplaceList[x,"a"|"e"|"i"|"o"|"u"->""];g@x_:=StringReplaceList[x," "->""];x_~l~y_:=NestWhile[If[f@#!={},Last@f@#,If[g@#!={},Last@g@#,Last@StringReplaceList[#,_->""]]]&,x,StringLength@#!=y&]

Debe haber una mejor manera que esta ...

Un simmons
fuente
0

R, 169143 bytes

function(x,y){d=utf8ToInt(x);o=c(rev(which(d%in%utf8ToInt('aeiou'))),rev(which(d==32)));intToUtf8(d[sort(tail(c(o,setdiff(nchar(x):1,o)),y))])}

* editar guardado 36 bytes a través de reescribir con utf8ToInt-> intToUtf8conversiones no strstplitypaste0(...,collapse)

no golfed con explicación

function(x,y){d=utf8ToInt(x);         # convert string (x) to integer
o=c(
 rev(which(d%in%utf8ToInt('aeiou'))), # index of vowels (reversed)
 rev(which(d==32)));                  # index of spaces
 intToUtf8(d[                         # convert subset back to character
   sort(tail(                         # return the first y index of 
                                      # "left over" characters
   c(o,setdiff(nchar(x):1,o))         # combine vowels, spaces and 
                                      # other indices in appropriate order
  ,y))])}
mnel
fuente