Nguyên âm giòn ra khỏi một chuỗi


22

Mô tả công việc

Đôi khi, bạn thực sự cần phải phù hợp với những gì bạn đang viết trong một không gian nhỏ. Nó có thể hấp dẫn để thả các nguyên âm và viết lk ths - và thất bại rằng, ai thực sự cần không gian? Thssprfctlrdbl!

Viết hàm hoặc chương trình loại bỏ các nguyên âm chữ thường aeiou, rồi khoảng trắng và sau đó bất kỳ ký tự nào từ chuỗi đầu vào . Hơn nữa, mỗi khi bạn loại bỏ một ký tự, nó phải là ký tự ngoài cùng bên phải đủ điều kiện để loại bỏ. Nó phải lặp lại quá trình này cho đến khi chuỗi không dài hơn một số độ dài đầu vào đã cho .

† Điều này hoàn toàn có thể đọc được!, Nhưng nếu bạn đang đọc chú thích này, có lẽ nó không, thực sự ... :)

Ví dụ

Tại đây, bạn có thể thấy quy trình này được áp dụng cho các kích cỡ đầu vào nhỏ hơn liên tiếp:

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

Sau khi ép chuỗi xuống còn 17 ký tự, chúng tôi hết nguyên âm để xóa, vì vậy ký tự tiếp theo chúng tôi loại bỏ là khoảng trống ngoài cùng bên phải; Khi chúng tôi đạt 14 ký tự, chúng tôi đã xóa tất cả các nguyên âm dấu cách, vì vậy chúng tôi chỉ cần bắt đầu nhai chuỗi từ phải sang trái.

Dưới đây là một số Python giả để giải quyết thách thức này:

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

Quy tắc

  • Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng.

  • Chuỗi đầu vào sẽ bao gồm các ký tự ASCII có thể in từ khoảng trắng ( , thập phân 32) cho đến và bao gồm dấu ngã ( ~, thập phân 126). Sẽ không có nguyên âm viết hoa AEIOUtrong chuỗi. Đặc biệt, sẽ không có Unicode, tab hoặc dòng mới liên quan.

  • Gọi chuỗi đầu vào s và độ dài mục tiêu đầu vào t . Sau đó, 0 <t ≤ chiều dài ( s ) ≤ 10000 được đảm bảo. (Đặc biệt, chuỗi đầu vào sẽ không bao giờ trống. Nếu t = length ( s ), bạn chỉ nên trả về chuỗi không được sửa đổi.)

Các trường hợp thử nghiệm

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

5
ymột nguyên âm?
edc65

1
Không thể tin được là tôi quên giải thích điều đó! Không, aeioulà nguyên âm, và AEIOUsẽ không xảy ra, vì đơn giản. (Toàn bộ chữ hoa / chữ thường không phải là thứ tôi muốn tập trung vào.) Tôi đã thêm làm rõ.
Lynn

1
Thử thách rất hay!
Luis Mendo

@ edc65 Đừng quên w(ví dụ: trong từ co w , wlà một nguyên âm!) Tất nhiên, điều đó được giải quyết cho cái này, nhưng đối với trường hợp không nói rằng bộ nguyên âm là aeiou, đôi khi bạn nên bao gồm yw. : -O
corsiKa

Không liên quan đến việc chơi gôn, nhưng hãy xem xét for index, char in enumerate(string)thay vì range(len(str))xây dựng
Jeremy Weirich

Câu trả lời:


6

MATL , 20 byte

t11Y2mEG32=+K#Si:)S)

Hãy thử trực tuyến!

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

11

Perl, 48 45 43 byte

Bao gồm +4 cho -Xlpi (-X có thể bị bỏ qua nhưng để lại những cảnh báo xấu xí trên STDERR)

Chạy với số sau -itùy chọn và đầu vào trên STDIN (cũng hỗ trợ nhiều dòng). ví dụperl -Xlpi50 crunch.pl <<< "Duis commodo scelerisque ex, ac consectetur metus rhoncus."

crunch.pl:

s/.*\K[aeiou]|.*\K |.$// while pos=-$^I

Bạn không cần khoảng trống giữa /$+/while
hmatt1

Tôi nghĩ rằng bạn cạo một byte bằng cách sử dụng ^ I (ký tự tab) thay vì "^ I". (Chưa được kiểm tra.)
msh210

@chilemagic: bỏ khoảng trắng giữa / $ + / và trong khi chỉ hoạt động với các perls cũ hơn. Các perls gần đây đã thay đổi trình phân tích cú pháp để tiếp tục mở khả năng thêm các công cụ sửa đổi regex mới (như sửa đổi aw)
TonMedel

@ msh210: Hoạt động cho một số biến số ma thuật, nhưng không hoạt động cho các biến số dựa trên khoảng trắng
TonMedel

6

JavaScript (ES6), 66 61 byte

Đã lưu 5 byte nhờ @Neil

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

Tôi không nghĩ rằng regex có thể chơi gôn hơn nữa. Đáng ngạc nhiên, ngắn nhất tôi có thể đưa ra để loại bỏ mặt trước là một byte dài hơn:

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

Nỗ lực thú vị hơn (ES7), 134 byte

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

Điều này sử dụng một cách tiếp cận tương tự như câu trả lời MATL.


1
Tôi không quan tâm nếu nó không thể chơi được, đó là một regex đẹp.
Neil

Mặc dù tôi vừa nhận thấy rằng bạn có thể sử dụng |.$/,"$1$2"để lưu 5 byte.
Neil

@Neil Cảm ơn vì tiền boa!
Sản xuất ETH

2

sh + gnu sed, 78 61

Cung cấp chuỗi cho STDIN, độ dài như đối số đầu tiên.

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

2

Lua, 120 byte

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

Đưa đầu vào làm đối số dòng lệnh, ở định dạng lua crunch.lua 10 "This is a string", với đầu ra Ths sstrng.

Giải trình:

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

1

Perl, 68

Loại bỏ từ bên phải thêm một tấn ký tự, có thể có một cách tốt hơn để làm điều này.

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

Sử dụng -iđể nhập số. Đó là 65 ký tự cộng 3 cho i, pltrên dòng lệnh.

Chạy với:

echo 'Hello, Code Golf World!' | perl -i13 -ple'$_=reverse;while(length>$^I){s/[aeiou]//||s/ //||s/.//}$_=reverse'

Bạn có thể sử dụng y///cthay vì lengthvà bạn có thể di chuyển vòng lặp while đến cuối:s///||s///||s///while$^I<y///c
andlrc

1

Java 8, 303 byte

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

Đây là CÁCH quá dài. Ill cố gắng rút ngắn nó sớm. Sẽ ngắn hơn nhiều nếu java có phương pháp đảo ngược chuỗi và thay thế ngược.

Kiểm tra với những điều sau đây:

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

1
Đa số áp đảo trên meta nói rằng bạn có thể tiết kiệm một byte bằng cách currying
Cyoce

@Cyoce có vẻ như cà ri không hoạt động trong trường hợp này ( s->j->{...}). Tôi nghĩ rằng Java không hỗ trợ nó rất tốt hoặc tôi đang thiết lập sai.
GamrCorps

Các ngôn ngữ được biên dịch có thể có một thời gian khó khăn với cà ri vì các chức năng hạng nhất
CalculatorFeline

@GamrCorps Tôi sẽ kiểm tra xem liệu tôi có thể làm cho nó hoạt động khi tôi về nhà không
Cyoce

1

C #, 180 byte

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

Người kiểm tra:

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

1

Scala, 160 byte

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

Người kiểm tra:

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

1

APL Dyalog, 77 45 42 byte

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

t[Các ]chữ cái của t với các chỉ mục ...
t←⌽⍞ t được đảo ngược nhập văn bản
i←⍳⍴t tôi nhận được các chỉ số về độ dài của t
/¨⊂i (3) các lựa chọn boolean của các phần tử của i :
1. (t∊'aeiou')boolean trong đó nguyên âm
2. (' '=t)boolean trong đó khoảng trống
3. 1tất cả là ∪∊duy nhất của danh sách ( làm phẳng) 3 lựa chọn
⌽⎕↓⌽thả các ký tự được đánh giá cuối cùng (giống như (-⎕)↓)
⌽i~đảo ngược các chỉ số còn lại sau khi xóa một số


Câu trả lời gốc:

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

Ehm, yeah, đó một chút khó đọc. Về cơ bản bản dịch trực tiếp của OP sang APL:

  1. Đảo ngược đầu vào.
  2. Nếu độ dài yêu cầu dài hơn hoặc bằng số chuỗi đầu vào (đảo ngược), thì trả về đối số đảo ngược (đảo ngược).
  3. Khác, nếu đối số có bất kỳ nguyên âm nào, hãy loại bỏ nguyên âm đầu tiên (tức là cuối cùng) và gọi đệ quy về những gì còn lại.
  4. Khác, nếu đối số có bất kỳ khoảng trắng nào, hãy xóa cái đầu tiên (tức là cuối cùng) và gọi đệ quy trên phần còn lại.
  5. Khác, loại bỏ ký tự đầu tiên (tức là cuối cùng) và gọi đệ quy trên những gì còn lại.

0

Toán học, 201 byte

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&]

Phải có một cách tốt hơn thế này ..


0

R, 169 143 byte

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

* chỉnh sửa lưu 36 byte thông qua viết lại với utf8ToInt->intToUtf8 không chuyển đổi strstplitpaste0(...,collapse)

không giải thích

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))])}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.