Crunch Vokale aus einer Zeichenfolge

22

Aufgabenbeschreibung

Manchmal müssen Sie wirklich etwas anbringen, das Sie auf kleinem Raum schreiben. Es mag verlockend sein, die Vokale fallen zu lassen und diese zu schreiben - und wenn das nicht gelingt, wer braucht dann wirklich Leerzeichen? Thssprfctlrdbl!

Schreibe eine Funktion oder Programm , das entfernt Kleinbuchstaben Vokale aeiouund dann Leerzeichen und dann alle Zeichen aus einem Eingabezeichenfolge . Außerdem muss jedes Mal, wenn Sie einen Charakter entfernen, dieser Charakter der am weitesten rechts stehende Charakter sein, der zum Entfernen berechtigt ist. Dieser Vorgang muss wiederholt werden, bis die Zeichenfolge nicht länger als eine bestimmte Eingabelänge ist .

† „Das ist perfekt lesbar!“ Aber wenn Sie diese Fußnote lesen, ist es wahrscheinlich nicht wirklich ... :)

Beispiele

Hier sehen Sie diesen Vorgang für sukzessive kleinere Eingabegrößen:

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

Nachdem wir die Zeichenfolge auf 17 Zeichen reduziert haben, gehen uns die zu entfernenden Vokale aus, sodass das nächste Zeichen, das wir entfernen, das am weitesten rechts stehende Leerzeichen ist. Wenn wir 14 Zeichen erreicht haben, haben wir alle Vokale und Leerzeichen entfernt, sodass wir einfach anfangen, die Zeichenfolge von rechts nach links zu kauen.

Hier ist ein Pseudocode- Python-Code, der diese Herausforderung löst:

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

Regeln

  • Das ist , also gewinnt der kürzeste Code in Bytes.

  • Die Eingabezeichenfolge besteht aus den druckbaren ASCII-Zeichen von Leerzeichen ( Dezimalzahl 32) bis einschließlich Tilde ( ~Dezimalzahl 126). Es werden keine Vokale in Großbuchstaben angezeigtAEIOUDie Zeichenfolge enthält in . Insbesondere handelt es sich nicht um Unicode, Tabulatoren oder Zeilenumbrüche.

  • Rufen Sie die Eingabezeichenfolge s und die Eingabe-Ziellänge t auf . Dann ist 0 <t ≤ Länge ( n ) ≤ 10000 garantiert. (Insbesondere wird die Eingabezeichenfolge niemals leer sein. Wenn t = Länge ( s ), sollten Sie die Zeichenfolge nur unverändert zurückgeben.)

Testfälle

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
quelle
5
Ist yein Vokal?
Edc65
1
Kann nicht glauben, dass ich vergessen habe, das zu erklären! Nein, aeiousind Vokale und AEIOUwerden der Einfachheit halber nicht vorkommen. (Die ganze Groß- / Kleinschreibung ist nicht das, worauf ich mich konzentrieren möchte.) Ich fügte eine Klarstellung hinzu.
Lynn
1
Sehr schöne Herausforderung!
Luis Mendo
@ edc65 Vergessen Sie nicht w(zum Beispiel in dem Wort co w , wist ein Vokal!) Natürlich, die für diesen abgemacht, aber für , wo es nicht angegeben ist , dass der Satz von Vokalen ist aeiou, sollten Sie manchmal enthalten yund w. : -O
corsiKa
Nicht im Zusammenhang mit Golfspielen, aber for index, char in enumerate(string)statt des range(len(str))Konstrukts
Jeremy Weirich

Antworten:

6

MATL , 20 Bytes

t11Y2mEG32=+K#Si:)S)

Probieren Sie es 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
quelle
11

Perl, 48 45 43 Bytes

Beinhaltet +4 für -Xlpi(-X kann weggelassen werden, hinterlässt aber hässliche Warnungen bei STDERR)

Führen Sie mit der Nummer nach der -iOption und der Eingabe auf STDIN (unterstützt auch mehrere Zeilen). z.Bperl -Xlpi50 crunch.pl <<< "Duis commodo scelerisque ex, ac consectetur metus rhoncus."

crunch.pl:

s/.*\K[aeiou]|.*\K |.$// while pos=-$^I
Tonne Hospel
quelle
Du brauchst keinen Raum dazwischen /$+/ undwhile
hmatt1
Ich denke, Sie rasieren ein Byte, indem Sie ein ^ I (Tabulatorzeichen) anstelle von "^ I" verwenden. (Ungetestet.)
msh210
@chilemagic: Das Löschen des Leerzeichens zwischen / $ + / funktioniert nur mit älteren Perls. Aktuelle Perls änderten den Parser, um die Fähigkeit offen zu halten, neue Regex-Modifikatoren (wie aw-Modifikator) hinzuzufügen
Ton Hospel
@ msh210: Funktioniert für einige magische Variablen, aber nicht für diejenigen, die auf Leerzeichen basieren
Ton Hospel
6

JavaScript (ES6), 66 61 Bytes

5 Bytes dank @Neil gespart

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

Ich denke nicht, dass der Regex weiter Golf spielen kann. Überraschenderweise ist der kürzeste Zeitraum, in dem ich Front-to-Back entfernen kann, ein Byte länger:

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

Interessanter Versuch (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``

Dies verwendet einen Ansatz ähnlich der MATL-Antwort.

ETHproductions
quelle
1
Es ist mir egal, ob es nicht zum Golfen geeignet ist, das ist ein wunderschöner Regex.
Neil
Obwohl mir gerade aufgefallen ist, dass man damit |.$/,"$1$2"5 Bytes sparen kann .
Neil
@Neil Danke für den Tipp!
ETHproductions
2

sh + gnu sed, 78 61

Geben Sie den String an STDIN, die Länge als erstes Argument.

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

Übernimmt Eingaben als Befehlszeilenargumente im Format lua crunch.lua 10 "This is a string"mit Ausgabe Ths sstrng.

Erläuterung:

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

Perl, 68

Durch Entfernen von rechts werden eine Menge Zeichen hinzugefügt. Vielleicht gibt es einen besseren Weg, dies zu tun.

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

Verwenden Sie, -ium die Nummer einzugeben. Es ist 65 Zeichen plus 3 für das i, pundl in der Befehlszeile.

Laufen mit:

echo 'Hello, Code Golf World!' | perl -i13 -ple'$_=reverse;while(length>$^I){s/[aeiou]//||s/ //||s/.//}$_=reverse'
hmatt1
quelle
Sie können y///canstelle von verwenden lengthund Sie können die while-Schleife an das Ende verschieben: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));};

Das ist viel zu lang. Ich versuche es bald zu verkürzen. Es wäre viel kürzer, wenn Java eine Methode zum Umkehren von Zeichenfolgen und zum Ersetzen in Rückwärtsrichtung hätte.

Testen Sie mit den folgenden:

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
quelle
1
Die überwältigende Mehrheit auf Meta sagt, Sie können ein Byte mit Curry
speichern
@Cyoce anscheinend funktioniert das currying in diesem fall nicht ( s->j->{...}). Ich denke, entweder unterstützt Java es nicht sehr gut oder ich richte es falsch ein.
GamrCorps
Kompilierte Sprachen haben es aufgrund erstklassiger Funktionen wahrscheinlich schwer mit dem Currying
CalculatorFeline
@GamrCorps Ich werde nachsehen, ob ich es schaffen kann, wenn ich nach Hause
komme
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;}

Prüfer:

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

Prüfer:

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

Dyalog APL, 77 45 42 Bytes

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

t[... ]Buchstaben t mit den Indizes ...
t←⌽⍞ t wird reversed Texteingabe
i←⍳⍴t i Indizes der Länge bekommt t
/¨⊂i mehrere (3) boolean Auswahlen von Elementen der i :
1. (t∊'aeiou')boolean wo Vokal
2. (' '=t)boolean , wo der Platz
3. 1alle ∪∊einzigartig des eingetragen ( abgeflacht) 3 Auswahlen
⌽⎕↓⌽lassen die zuletzt eingegebenen Zeichen fallen (wie (-⎕)↓)
⌽i~kehren die verbleibenden Indizes um, nachdem einige entfernt wurden


Ursprüngliche Antwort:

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

Ähm, ja, das ist ein bisschen schwer zu lesen. Grundsätzlich die direkte Übersetzung von OP in APL:

  1. Eingabe umkehren.
  2. Wenn die erforderliche Länge größer oder gleich der Anzahl der (umgekehrten) Eingabezeichenfolgen ist, geben Sie das umgekehrte (umgekehrte) Argument zurück.
  3. Andernfalls, wenn das Argument einen Vokal hat, entfernen Sie den ersten (dh letzten) und rufen Sie rekursiv auf, was übrig bleibt.
  4. Wenn das Argument kein Leerzeichen enthält, entfernen Sie das erste (dh das letzte) und rufen Sie rekursiv auf, was übrig bleibt.
  5. Ansonsten entferne das erste (dh letzte) Zeichen und rufe rekursiv auf, was übrig bleibt.
Adam
quelle
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&]

Es muss einen besseren Weg geben als diesen.

Ein Simmons
quelle
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))])}

* Bearbeiten Sie gespeicherte 36 Byte durch Umschreiben mit utf8ToInt-> intToUtf8Konvertierungen nicht strstplitundpaste0(...,collapse)

ungolfed mit erklärung

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
quelle