Usuń więcej niż n kolejnych samogłosek z ciągu wejściowego

19

Nie lubię strun z więcej niż trzema samogłoskami z rzędu. Czy potrafisz napisać program, który usuwa wszystkie samogłoski, których nie chcę ze słów?

Możesz napisać program lub funkcję, pobierając dane wejściowe przez STDIN (lub najbliższą alternatywę), argument wiersza poleceń lub argument funkcji i wypisując wynik przez STDOUT (lub najbliższą alternatywę), wartość zwracaną funkcji lub parametr funkcji (wyjściowej).

Dane wejściowe to ciąg zawierający tylko drukowalny znak ASCII (od 0x20 do 0x7E włącznie).

Wyjście jest ciągiem zawierającym tylko najwyżej 3 kolejne samogłoski. Jeśli ciąg wejściowy zawiera więcej niż 3 kolejne samogłoski, program powinien wygenerować ciąg wyjściowy, w tym pierwsze trzy samogłoski napotkane w tym przebiegu, odrzucając kolejne kolejne samogłoski.

Y nie jest samogłoską dla celów tego wyzwania.

To jest kod golfowy, więc wygrywa najkrótszy kod (w bajtach).

Przypadki testowe

"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
źródło
2
Powinieneś dołączyć więcej testów z mieszanymi przypadkami, np aaYYAAaaaAERGH.
Zgarb,

Odpowiedzi:

5

Pyth, 21 bajtów

sfg3=Z&}rT0"aeiou"hZz

Wypróbuj online: pakiet demonstracyjny lub testowy

Wyjaśnienie:

Iteruję wszystkie znaki i śledzę, ile samogłosek przeszedłem za pomocą licznika. Za każdym razem, gdy przekazuję znak, który nie jest samogłoską, resetuję licznik na 0. Ponownie wyświetlam znaki, gdy licznik ma> 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
źródło
10

Nieczytelny , 1647 bajtów

„” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „„ ”„ ”„ „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ „” „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ „” „” „” „„ ”„ „” „„ ”„ „”„” „” „” „” „” „” „„ ”„ „” „” „” „” „„ ”„ „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „” „” „” „” „„ ”„ ”„ „” „” „„ ”„ „” „” „” „„ ”„ ”„ „” „” „” „”„” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „” „„ ”„ „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „” „” „„„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ „” „” „” „” „„ ”„ „” „” „”„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „„ ”„ ”„ ”„ ”„ „” „” „” „„ ”„ „” „” „” „” „” „”„” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ „” „” „” „” „” „„ ”„ „” „” „„ ”„ ”„ ”„” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „” „„ ”„ „” „„ ” „” „” „” „” „” „” „„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ „” „„ ”„ „” „” „„ ”„” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ” „” „” „” „„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„” „” „” „” „„ ”„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ” „” „” „” „” „” „” „„ ”„ „” „” „” „„ ”„ „” „„ ”„ ”„ ”„ ”„ ” „” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ „” „„ ”„ ”„ ”„ ”„ ”„ ”„” „” „” „” „” „” „” „„ ”„ ”„ ”„ ”„ ”„ „” „” „” „”

Wyjaśnienie

Ten program jest równoważny pseudokodowi tak:

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

z następującymi przypisaniami zmiennych:

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)

Jak widać, uniknąłem zmiennej szczeliny 0, ponieważ 0jest to tak długa stała do napisania.

Czytamy więc każdy znak i przechowujemy wartość zarówno w, jak cpi ch. Zmodyfikujemy, cpale pozostaniemy w chpobliżu, aby w razie potrzeby móc go wydrukować. Sukcesywnie odejmujemy liczby 65, 4, 4, 6 itd., cpAby sprawdzić, czy jest to każdy z 10 możliwych znaków samogłosek w ASCII (zwróć uwagę, że ostatni nie musi być przypisaniem).

vszawsze zawiera o 3 mniej niż liczba samogłosek, które można jeszcze wydrukować. Zaczyna się od 0, więc można wydrukować 3 samogłoski. Kiedy to osiągnie -3, przestajemy drukować samogłoski.

Jeśli napotkamy nie-samogłoskę (w tym spację), wykonujemy print(ch)po niej vs = 0. Jak zapewne się domyślacie, resetuje licznik samogłosek.

Jeśli napotkamy samogłoskę , wykonujemy ją ((--vs)+4) ? print(ch) : (++vs). Rozbijmy to:

  • ubytek vs;
  • jeśli wartość jest teraz -4, posunęliśmy się zbyt daleko, więc nic nie drukuje, ale przyrost vspowrotem do -3tak będziemy kontynuować do odmowy wydrukowania samogłosek;
  • w przeciwnym razie wydrukuj znak.
Timwi
źródło
1
Ten język jest zgodny ze swoją nazwą.
bkul,
2
Zawsze zastanawiam się w tych językach ... „Czy napisali to ręcznie? Jeśli tak, to szkoda mi ...” +1
Addison Crump,
9

Siatkówka , 25 bajtów

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

Wypróbuj online.

Dość prosta podstawienie wyrażenia regularnego. Działa to również dla tej samej liczby bajtów:

Ri`(?<=[aeiou]{3})[aeiou]
Martin Ender
źródło
3
Wreszcie! Tłumacz online! Powinieneś rozważyć link do niego na swojej stronie github.
mbomb007,
6

JavaScript (ES6), 42

Jako funkcja anonimowa

s=>s.replace(/[aeiou]+/gi,v=>v.slice(0,3))
edc65
źródło
4

Perl, 27 znaków

(Kod 26 znaków + opcja wiersza poleceń 1 znak)

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

Nic wielkiego, tylko rzadka okazja, którą pamiętam \K.

Przykładowy przebieg:

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.
człowiek w pracy
źródło
2
Kiedy napisałem odpowiedź Retina, pomyślałem: „Chciałbym mieć .NET regex \K”. :)
Martin Ender,
Interesujące, @ MartinBüttner. Miałem wrażenie, że te wyrażenia regularne zostały wprowadzone na poważną dietę steroidową. Czy z ciekawości mają rekursywny wzór? Może pomóc oszczędzić jedną samogłoskę wyliczenie, choć wynik jest już: s/([aeiou]{1,3})(?1)+/$1/gi.
manatwork,
Niestety, nie mają też ponownego użycia wzoru. Są to dwie rzeczy, które czasami zmuszają mnie do przejścia na Perl lub PCRE. Kiedy zajmę się łataniem kilku prostych rzeczy w smaku regex Retiny, myślę, że je dodam (nie jest to prawdziwa rekurencja, ale przynajmniej ponowne użycie wzoru i skończona rekurencja).
Martin Ender,
2

Poważnie, 34 bajty

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

Hex Dump:

2c3b9730bb604f6b226165696f75224f6b
642d593bbd2b2a3bbb343e604d40b0ee6a

Wypróbuj online

Wykorzystuje ten sam algorytm, co odpowiedź Pyth, mapując ciąg, śledząc długość bieżącego przebiegu samogłosek w rejestrze, zwiększając go za każdym razem, gdy obecny znak jest samogłoską i sprawdzając, czy przekroczył dozwoloną długość, zwracając 0, jeśli tak, a następnie filtrując oryginalny ciąg za pomocą tego wygenerowanego filtra. Będzie o wiele krótszy, gdy będziemy mogli użyć odejmowania ustawionego dla ciągów. ( OkMożna usunąć i Okdzastąpić je tylko @). Słyszałem, że ta funkcja pojawi się w następnej aktualizacji ....

kwintopia
źródło
2

C, 166 bajtów

jak dotąd nie najkrótsza odpowiedź, ale myślę, że ładnie grał w golfa

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

walizka testowa:

$ 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
źródło
2

Mathematica, 68 bajtów

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

Odpowiedź wyrażenia regularnego byłaby taka sama, ale kto używa wyrażenia regularnego?

LegionMammal978
źródło
2

Java, 115 bajtów

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

Oczekuje wprowadzenia jako parametru programu.

Wyjście testu jednostkowego:

Aei
screeen
We're queung up for the Hawaiin movie.
Tomas Langer
źródło
Zapisz jeden bajt, usuwając spację między String[]i a. String[]a
Poke
Zaoszczędź 2 bajty, używając printzamiast println. Nie wierzę, że specyfikacja wymaga końca nowej linii.
Poke
2

APL, 40 znaków

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

Po angielsku:

  • 'aeiouAEIOU'∊⍨' ',⍵: znajdź samogłoski (i wstaw spację, aby przerwać po obrocie);
  • (1-⍳4)⌽¨⊂: obróć 0, 1, 2, 3 razy (z zawijaniem) popychając w prawo wektor boolowski;
  • ⊃+/ sum: obroty i rozpakuj
  • 1↓4≠: znajdź inną niż 4 i usuń pierwszą (aby przygotować miejsce, które wcześniej zajęliśmy)
  • ⍵/⍨: w argumencie zachowaj tylko element, w którym suma była inna niż 4.
lstefano
źródło
1

Perl 6 ,  36  35 bajtów

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

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

stosowanie:

$ 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
źródło
1

C (205 bajtów)

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

(Dodano jeden podział linii dla zachowania przejrzystości)

musarithmia
źródło
1

Scala, 107 bajtów

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
źródło
1

JavaScript ES6, 43 znaki

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

Test:

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
źródło
1

x .86 MS-DOS .COM , 44 bajty 36 bajtów

Pliki .COM są szeroko obsługiwane od MS-DOS 1 do chwili obecnej --- działam w dosemu, używając tylko poleceń 8086.

Zmniejszono z 44 do 36 bajtów, używając REPNE SCASB do testowania samogłosek, zamiast osobnego polecenia do testowania każdej samogłoski.

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
źródło
1

Matlab / Octave, 54 bajty

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

Przykład:

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

Wypróbuj w ideone .

Luis Mendo
źródło
1

V , 21 bajtów (niekonkurencyjny)

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

Wypróbuj online!

Wyjaśnienie:

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

Jest to tylko nieco krótsze niż najprostsze rozwiązanie:

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

(22 bajty)

DJMcMayhem
źródło
0

Rubinowy, 44 bajty

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

Przykład:

% 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
źródło
Napisałeś: „Dane wejściowe to ciąg zawierający tylko drukowalny znak ASCII (0x20 do 0x7E włącznie).” Po co więc wydawać dodatkowe znaki, $<.readaby obsłużyć wprowadzanie wielowierszowe (a więc zawiera znak spoza zakresu 0x0a) zamiast gets?
manatwork
@manatwork to naprawdę dobry punkt, dziękuję! Pomyśl, że może to zaoszczędzić 2-3 bajty :)
Joseph Weissman,