Entfernen Sie mehr als n aufeinanderfolgende Vokale aus der Eingabezeichenfolge

19

Ich mag keine Saiten mit mehr als drei Vokalen hintereinander. Können Sie ein Programm schreiben, das alle Vokale entfernt, die ich nicht aus Worten entfernen möchte?

Sie können ein Programm oder eine Funktion schreiben, indem Sie eine Eingabe über STDIN (oder die nächstgelegene Alternative), ein Befehlszeilenargument oder ein Funktionsargument vornehmen und das Ergebnis über STDOUT (oder die nächstgelegene Alternative), einen Funktionsrückgabewert oder einen Funktionsparameter (out) ausgeben.

Die Eingabe ist eine Zeichenfolge, die nur druckbare ASCII-Zeichen enthält (einschließlich 0x20 bis 0x7E).

Die Ausgabe ist eine Zeichenfolge, die nur Reihen von höchstens 3 aufeinanderfolgenden Vokalen enthält. Wenn die Eingabezeichenfolge mehr als 3 aufeinanderfolgende Vokale enthält, sollte Ihr Programm eine Ausgabezeichenfolge erstellen, die die ersten drei Vokale enthält, die bei dieser Ausführung auftreten, und alle weiteren aufeinanderfolgenden Vokale verwerfen.

Y ist kein Vokal im Sinne dieser Herausforderung.

Das ist Code Golf, also gewinnt der kürzeste Code (in Bytes).

Testfälle

"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
quelle
2
Sie sollten weitere Tests mit gemischten Fällen wie hinzufügen aaYYAAaaaAERGH.
Zgarb

Antworten:

5

Pyth, 21 Bytes

sfg3=Z&}rT0"aeiou"hZz

Probieren Sie es online aus: Demo oder Test Suite

Erläuterung:

Ich durchlaufe alle Zeichen und halte fest, wie viele Vokale ich mithilfe eines Zählers übergeben habe. Jedes Mal, wenn ich ein Zeichen übergebe, das kein Vokal ist, setze ich den Zähler auf 0 zurück. Ich entferne Zeichen, wenn der Zähler> 4 ist.

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

Nicht lesbar , 1647 Bytes

"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "

Erläuterung

Dieses Programm entspricht dem folgenden Pseudocode:

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
    }
}

mit folgenden variablen Zuordnungen:

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)

Wie Sie sehen, habe ich den variablen Steckplatz 0 vermieden, da 0es sich um eine so lange zu schreibende Konstante handelt.

Also lesen wir jedes Zeichen und speichern den Wert in cpund ch. Wir werden Änderungen vornehmen, diese cpaber beibehalten, chdamit wir sie bei Bedarf ausdrucken können. Wir subtrahieren nacheinander die Zahlen 65, 4, 4, 6 usw. cp, um zu überprüfen, ob es sich um jedes der 10 möglichen Vokalzeichen in ASCII handelt (beachten Sie, dass das allerletzte keine Zuweisung sein muss).

vsEnthält immer 3 weniger als die Anzahl der Vokale, die noch gedruckt werden dürfen. Es fängt bei an 0, also können 3 Vokale gedruckt werden. Wenn es erreicht ist -3, hören wir auf, Vokale zu drucken.

Wenn wir auf einen Nicht-Vokal (einschließlich des Leerzeichens) stoßen , führen wir print(ch)gefolgt von aus vs = 0. Wie Sie wahrscheinlich erraten haben, wird der Vokalzähler dadurch zurückgesetzt.

Wenn wir auf einen Vokal stoßen , führen wir aus ((--vs)+4) ? print(ch) : (++vs). Lassen Sie uns das aufschlüsseln:

  • Dekrement vs;
  • Wenn der Wert jetzt ist -4, sind wir zu weit gegangen, drucken Sie also nichts aus, sondern erhöhen Sie ihn vsauf, -3damit wir das Drucken von Vokalen weiterhin ablehnen.
  • Andernfalls drucken Sie das Zeichen.
Timwi
quelle
1
Diese Sprache ist ihrem Namen treu.
bkul
2
Ich frage mich immer in diesen Sprachen ... "Haben sie das tatsächlich von Hand geschrieben? Wenn ja, ich bedaure sie ..." +1
Addison Crump
9

Retina , 25 Bytes

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

Probieren Sie es online aus.

Ziemlich unkomplizierte Regex-Substitution. Dies funktioniert auch für die gleiche Byteanzahl:

Ri`(?<=[aeiou]{3})[aeiou]
Martin Ender
quelle
3
Endlich! Ein Online-Dolmetscher! Sie sollten in Betracht ziehen, auf Ihrer Github-Seite darauf zu verlinken.
mbomb007
6

JavaScript (ES6), 42

Als anonyme Funktion

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

Perl, 27 Zeichen

(26 Zeichen Code + 1 Zeichen Befehlszeilenoption)

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

Keine große Sache, nur eine seltene Gelegenheit, an die ich mich erinnere \K.

Probelauf:

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.
Mann bei der Arbeit
quelle
2
Als ich die Retina-Antwort schrieb, dachte ich "Ich wünschte, .NET Regex hätte \K". :)
Martin Ender
Interessant, @ MartinBüttner. Ich hatte das Gefühl, dass diese regulären Ausdrücke auf eine ernsthafte Steroiddiät gesetzt wurden. Haben sie aus Neugierde ein rekursives Submuster? Kann helfen, Ersatz einen Vokal Aufzählung, obwohl mehr das Ergebnis: s/([aeiou]{1,3})(?1)+/$1/gi.
manatwork
Leider haben sie auch keine Wiederverwendung von Mustern. Das sind die beiden Dinge , die mich gelegentlich dazu bringen , zu Perl oder PCRE zu wechseln . Wenn ich ein paar einfache Dinge in die Regex-Variante von Retina einflicken will, füge ich diese hinzu (keine echte Rekursion, aber zumindest Wiederverwendung von Mustern und endliche Rekursion).
Martin Ender
2

Im Ernst, 34 Bytes

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

Hex Dump:

2c3b9730bb604f6b226165696f75224f6b
642d593bbd2b2a3bbb343e604d40b0ee6a

Probieren Sie es online aus

Es wird derselbe Algorithmus wie für die Pyth-Antwort verwendet. Dabei wird die Länge der aktuellen Vokallaufzeit in einem Register aufgezeichnet, die Länge jedes Mal erhöht, wenn das aktuelle Zeichen ein Vokal ist, und geprüft, ob die zulässige Länge überschritten wurde. Wenn dies der Fall ist, wird 0 zurückgegeben und die ursprüngliche Zeichenfolge mit diesem generierten Filter gefiltert. Es wird viel kürzer sein, wenn wir die Mengen-Subtraktion für Strings verwenden können. (Das Okkann gelöscht werden und das Okdkann mit nur ersetzt werden @). Ich habe gehört, dass diese Funktion im nächsten Update verfügbar ist.

Quintopie
quelle
2

C 166 Bytes

bei weitem nicht die kürzeste Antwort, aber ich denke, schön golfen ..

#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++;}

Testfall:

$ 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
quelle
2

Mathematica, 68 Bytes

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

Die Regex-Antwort wäre gleich lang, aber wer verwendet Regex?

LegionMammal978
quelle
2

Java, 115 Bytes

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

Erwartet die Eingabe als Programmparameter.

Unit-Test-Ausgang:

Aei
screeen
We're queung up for the Hawaiin movie.
Tomas Langer
quelle
Speichern Sie ein Byte, indem Sie das Leerzeichen zwischen String[]und entfernen a. String[]a
Poke
Sparen Sie 2 Bytes, indem Sie printanstatt verwenden println. Ich glaube nicht, dass die Spezifikation einen nachgestellten Zeilenumbruch erfordert.
Poke
2

APL, 40 Zeichen

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

Auf Englisch:

  • 'aeiouAEIOU'∊⍨' ',⍵: finde die Vokale (und stelle ein Leerzeichen voran, um bei der Drehung zu brechen);
  • (1-⍳4)⌽¨⊂: 0, 1, 2, 3-mal drehen (mit Umlauf) und dabei den booleschen Vektor nach rechts drücken;
  • ⊃+/ sum: die Drehungen und Unbox
  • 1↓4≠: Finde den Unterschied zu 4 und entferne den ersten (um den Platz zu ersetzen, den wir vorangestellt haben)
  • ⍵/⍨: Behalten Sie in dem Argument nur das Element bei, bei dem sich die Summe von 4 unterschied.
lstefano
quelle
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

Verwendung:

$ 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
quelle
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);}}}}

(Ein Zeilenumbruch zur Verdeutlichung hinzugefügt)

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

Javascript ES6, 43 Zeichen

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

Prüfung:

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

x86 MS-DOS .COM-Datei , 44 Byte, 36 Byte

.COM-Dateien werden von MS-DOS 1 bis heute weitgehend unterstützt. Ich verwende Dosemu nur mit 8086-Befehlen.

Reduziert von 44 auf 36 Byte durch Verwendung von REPNE SCASB zum Testen auf Vokale, anstatt einen separaten Befehl zum Testen jedes Vokals zu verwenden.

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

Matlab / Octave, 54 Bytes

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

Beispiel:

>> @(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.

Probiere es bei ideone aus .

Luis Mendo
quelle
1

V , 21 Bytes (nicht konkurrierend)

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

Probieren Sie es online!

Erläuterung:

ñ[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

Dies ist kaum kürzer als die einfachere Lösung:

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

(22 Bytes)

DJMcMayhem
quelle
0

Ruby, 44 Bytes

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

Beispiel:

% 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
quelle
Sie haben es geschrieben: "Eingabe ist eine Zeichenfolge, die nur druckbare ASCII-Zeichen enthält (0x20 bis 0x7E, einschließlich)." Warum sollten Sie dann zusätzliche Zeichen verwenden $<.read, um die mehrzeilige Eingabe (also das Zeichen 0x0a außerhalb des Bereichs) zu verarbeiten gets?
manatwork
@manatwork das ist ein wirklich guter Punkt, danke! Denke, es könnte 2-3 Bytes sparen :)
Joseph Weissman