Triturar vogais de uma corda

22

Descrição da tarefa

Às vezes, você realmente precisa ajustar algo que está escrevendo em um espaço pequeno. Pode ser tentador abandonar as vogais e escrever coisas erradas - e na falta disso, quem realmente precisa de espaços? Thssprfctlrdbl!

Escreva uma função ou programa que remova vogais em minúsculas aeiou, espaços e, em seguida, qualquer caractere de uma sequência de entrada . Além disso, cada vez que você remove um personagem, ele deve ser o personagem mais à direita elegível para remoção. Ele deve repetir esse processo até que a string não tenha mais que um determinado comprimento de entrada .

† “Isso é perfeitamente legível!” Mas se você está lendo esta nota de rodapé, provavelmente não é, realmente ... :)

Exemplos

Aqui, você pode ver esse processo aplicado para tamanhos de entrada sucessivamente menores:

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

Depois de espremer a string para 17 caracteres, ficamos sem vogais para removê-las, portanto o próximo caractere que removemos é o espaço mais à direita; quando atingimos 14 caracteres, removemos todas as vogais e espaços, então começamos a mastigar a corda da direita para a esquerda.

Aqui está um código Python com pseudocódigo que resolve esse desafio:

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

Regras

  • Isso é , então o código mais curto em bytes vence.

  • A sequência de entrada consistirá nos caracteres ASCII imprimíveis do espaço ( , decimal 32) até e incluindo o til ( ~, decimal 126). Não haverá vogais maiúsculas AEIOUna string. Em particular, não haverá Unicode, guias ou novas linhas envolvidas.

  • Chame a sequência de entrada s e o comprimento do destino de entrada t . Então 0 <t ≤ comprimento ( s ) ≤ 10000 é garantido. (Em particular, a sequência de entrada nunca estará vazia. Se t = comprimento ( ões ), você deve retornar a sequência sem modificação.)

Casos de teste

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
fonte
5
É yuma vogal?
edc65
1
Não acredito que esqueci de explicar isso! Não, aeiousão vogais e AEIOUnão ocorrerão por simplicidade. (A coisa toda em maiúsculas / minúsculas não é o que eu quero focar.) Adicionei esclarecimentos.
Lynn
1
Muito bom desafio!
Luis Mendo
@ edc65 Não se esqueça w(por exemplo, na palavra co w , wé uma vogal!) É claro que isso está resolvido para esta, mas para onde não está declarado que o conjunto de vogais é aeiou, às vezes você deve incluir ye w. : -O
corsiKa 01/03
Alheios ao golfe, mas considere for index, char in enumerate(string), em vez da range(len(str))construção
Jeremy Weirich

Respostas:

6

MATL , 20 bytes

t11Y2mEG32=+K#Si:)S)

Experimente online!

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
fonte
11

Perl, 48 45 43 bytes

Inclui +4 para -Xlpi(-X pode ser deixado de fora, mas deixa avisos feios em STDERR)

Execute o número após a -iopção e a entrada STDIN (também suporta várias linhas). por exemploperl -Xlpi50 crunch.pl <<< "Duis commodo scelerisque ex, ac consectetur metus rhoncus."

crunch.pl:

s/.*\K[aeiou]|.*\K |.$// while pos=-$^I
Ton Hospel
fonte
Você não precisa do espaço entre /$+/ewhile
hmatt1
Eu acho que você raspa um byte usando um ^ I (caractere de tabulação) em vez de "^ I". (Não testado.) #
1100 msh210
@chilemagic: diminuindo o espaço entre / $ + / e enquanto apenas trabalha com perls mais antigos. Perls recentes mudaram o analisador para manter aberta a possibilidade de adicionar novos modificadores regex (como modificador aw)
Ton Hospel
@ msh210: Obras para algumas variáveis mágicas, mas não para os baseados em espaços em branco
Ton Hospel
6

JavaScript (ES6), 66 61 bytes

Guardado 5 bytes graças a @Neil

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

Não acho que o regex seja ainda mais jogável. Surpreendentemente, o menor tempo possível para remover a frente para trás é um byte mais longo:

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

Tentativa mais interessante (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``

Isso usa uma abordagem semelhante à resposta MATL.

ETHproductions
fonte
1
Eu não me importo se não é um jogo de golfe, isso é um belo regex.
Neil
Embora eu tenha acabado de notar que você pode usar |.$/,"$1$2"para salvar 5 bytes.
Neil
@ Neil Obrigado pela dica!
ETHproductions
2

sh + gnu sed, 78 61

Forneça a string para STDIN, o comprimento como primeiro 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.
fonte
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())

Recebe entrada como argumentos de linha de comando, no formato lua crunch.lua 10 "This is a string", com saída Ths sstrng.

Explicação:

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

Perl, 68

Remover da direita adiciona uma tonelada de caracteres, talvez haja uma maneira melhor de fazer isso.

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

Use -ipara inserir o número. É 65 caracteres mais 3 para o i, pe lna linha de comando.

Correr com:

echo 'Hello, Code Golf World!' | perl -i13 -ple'$_=reverse;while(length>$^I){s/[aeiou]//||s/ //||s/.//}$_=reverse'
hmatt1
fonte
Você pode usar em y///cvez de lengthe pode mover o loop while até o fim: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));};

Isso é muito longo. Vou tentar encurtar em breve. Seria muito mais curto se o java tivesse um método para reverter seqüências de caracteres e substituições anteriores.

Teste com o seguinte:

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
fonte
1
A maioria underwhelming na meta diz que você pode salvar um byte com currying
Cyoce
@ Cyy parece que o curry não funciona neste caso ( s->j->{...}). Acho que o Java não suporta muito bem ou estou configurando errado.
GamrCorps
Linguagens compiladas provavelmente tem um tempo duro com currying por causa de funções de primeira classe
CalculatorFeline
@GamrCorps Vou verificar e ver se eu posso fazê-lo funcionar quando eu chegar em 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;}

Testador:

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
fonte
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]")," "),".")}

Testador:

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

Dyalog APL, 77 45 42 bytes

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

t[]Letras de t com índices ...
t←⌽⍞ t obtém entrada de texto invertida
i←⍳⍴t i obtém índices de comprimento de t
/¨⊂i várias (3) seleções booleanas de elementos de i :
1. (t∊'aeiou')booleano onde vogal
2. (' '=t)booleano onde espaço
3. 1todos ∪∊exclusivos do alistado ( nivelado) 3 seleções
⌽⎕↓⌽eliminam os últimos caracteres introduzidos avaliados (o mesmo que (-⎕)↓)
⌽i~invertem os índices restantes após remover alguns


Resposta original:

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

Ehm, sim, isso é um pouco difícil de ler. Basicamente, a tradução direta do OP no APL:

  1. Entrada reversa.
  2. Se o comprimento necessário for maior ou igual à contagem da string de entrada (invertida), retorne o argumento invertido (invertido).
  3. Caso contrário, se o argumento tiver alguma vogal, remova a primeira (ou seja, a última) e chame recursivamente o que resta.
  4. Caso contrário, se o argumento tiver algum espaço, remova o primeiro (ou seja, o último) e chame recursivamente o que resta.
  5. Senão, remova o primeiro (ou seja, último) caractere e chame recursivamente o que resta.
Adão
fonte
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&]

Deve haver uma maneira melhor do que isso ..

A Simmons
fonte
0

R, 169 143 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 economizou 36 bytes através de reescrever com utf8ToInt-> intToUtf8conversões não strstplitepaste0(...,collapse)

ungolfed com explicação

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
fonte