Hancurkan vokal dari seutas tali

22

Deskripsi tugas

Terkadang, Anda benar-benar perlu memasukkan sesuatu yang Anda tulis di ruang kecil. Mungkin tergoda untuk menjatuhkan huruf vokal dan menulisnya - dan gagal itu, siapa yang benar-benar membutuhkan ruang? Thssprfctlrdbl!

Tulis fungsi atau program yang menghilangkan vokal huruf kecil aeiou, lalu spasi, lalu karakter apa pun dari string input . Selanjutnya, setiap kali Anda menghapus karakter, itu harus karakter paling kanan yang memenuhi syarat untuk dihapus. Ini harus mengulangi proses ini sampai string tidak lebih dari beberapa panjang input yang diberikan .

† “Ini benar-benar bisa dibaca!” Tetapi jika Anda membaca catatan kaki ini, mungkin tidak, sungguh ... :)

Contohnya

Di sini, Anda dapat melihat proses ini diterapkan untuk ukuran input yang lebih kecil secara berturut-turut:

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

Setelah menekan string ke 17 karakter, kita kehabisan vokal untuk dihapus, jadi karakter berikutnya yang kita hapus adalah ruang paling kanan; ketika kami menekan 14 karakter, kami telah menghapus semua vokal dan spasi, jadi kami mulai mengunyah string dari kanan ke kiri.

Berikut adalah beberapa kode pseudocode Python yang memecahkan tantangan ini:

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

Aturan

  • Ini adalah , jadi kode terpendek dalam byte menang.

  • String input akan terdiri dari karakter ASCII yang dapat dicetak dari luar angkasa ( , desimal 32) hingga dan termasuk tilde ( ~, desimal 126). Tidak akan ada vokal huruf besar AEIOUdalam string. Secara khusus, tidak akan ada Unicode, tab, atau baris baru yang terlibat.

  • Panggil string input s , dan panjang target input t . Maka 0 <t ≤ panjang ( s ) ≤ 10000 dijamin. (Secara khusus, input string tidak akan pernah kosong. Jika t = panjang ( s ), Anda hanya harus kembali string yang tidak dimodifikasi.)

Uji kasus

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
sumber
5
Apakah yvokal?
edc65
1
Tidak percaya saya lupa menjelaskan itu! Tidak, aeiouadalah vokal, dan AEIOUtidak akan muncul, untuk kesederhanaan. (Seluruh huruf besar / huruf kecil bukan apa yang ingin saya fokuskan.) Saya menambahkan klarifikasi.
Lynn
1
Tantangan yang sangat bagus!
Luis Mendo
@ edc65 Jangan lupa w(misalnya, dalam kata co w , wadalah vokal!) Tentu saja, itu cocok untuk yang satu ini, tetapi untuk yang tidak menyatakan bahwa rangkaian vokal adalah aeiou, Anda terkadang harus memasukkan ydan w. : -O
corsiKa
Tidak terkait dengan golf, tetapi pertimbangkanlah for index, char in enumerate(string)alih-alih range(len(str))konstruksi
Jeremy Weirich

Jawaban:

6

MATL , 20 byte

t11Y2mEG32=+K#Si:)S)

Cobalah 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
sumber
11

Perl, 48 45 43 byte

Termasuk +4 untuk -Xlpi(-X dapat diabaikan tetapi meninggalkan peringatan jelek di STDERR)

Jalankan dengan nomor setelah -iopsi dan input pada STDIN (mendukung beberapa baris juga). misalnyaperl -Xlpi50 crunch.pl <<< "Duis commodo scelerisque ex, ac consectetur metus rhoncus."

crunch.pl:

s/.*\K[aeiou]|.*\K |.$// while pos=-$^I
Ton Hospel
sumber
Anda tidak memerlukan ruang antara /$+/danwhile
hmatt1
Saya pikir Anda mencukur byte dengan menggunakan ^ I (karakter tab) alih-alih "^ I". (Belum diuji.)
msh210
@chememagic: menjatuhkan spasi antara / $ + / dan sementara hanya bekerja dengan perl yang lebih lama. Perl baru-baru ini mengubah pengurai untuk tetap membuka kemampuan untuk menambahkan pengubah regex baru (seperti pengubah aw)
Ton Hospel
@ msh210: Berfungsi untuk beberapa variabel ajaib, tetapi tidak untuk yang berdasarkan pada spasi putih
Ton Hospel
6

JavaScript (ES6), 66 61 byte

Disimpan 5 byte berkat @Neil

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

Saya tidak berpikir regex bisa golf lebih jauh. Anehnya, yang terpendek yang dapat saya lakukan untuk menghapus front-to-back adalah satu byte lebih lama:

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

Upaya yang lebih menarik (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``

Ini menggunakan pendekatan yang mirip dengan jawaban MATL.

Produksi ETH
sumber
1
Saya tidak peduli jika tidak golf, itu regex yang indah.
Neil
Meskipun saya baru saja memperhatikan bahwa Anda dapat menggunakan |.$/,"$1$2"untuk menghemat 5 byte.
Neil
@Neil Terima kasih atas tipnya!
ETHproduk
2

sh + gnu sed, 78 61

Berikan string STDIN, panjang sebagai argumen pertama.

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

Mengambil input sebagai argumen baris perintah, dalam format lua crunch.lua 10 "This is a string", dengan output Ths sstrng.

Penjelasan:

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

Perl, 68

Menghapus dari kanan menambah banyak karakter, mungkin ada cara yang lebih baik untuk melakukan ini.

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

Gunakan -iuntuk memasukkan nomor. Ini adalah 65 karakter ditambah 3 untuk i, pdan lpada baris perintah.

Jalankan dengan:

echo 'Hello, Code Golf World!' | perl -i13 -ple'$_=reverse;while(length>$^I){s/[aeiou]//||s/ //||s/.//}$_=reverse'
hmatt1
sumber
Anda dapat menggunakan y///csebagai gantinya lengthdan Anda dapat memindahkan loop sementara ke akhir: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));};

Ini terlalu panjang. Aku akan mencoba untuk mempersingkatnya segera. Akan jauh lebih pendek jika java memiliki metode untuk membalik string dan penggantian mundur.

Tes dengan yang berikut ini:

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
sumber
1
Mayoritas underwhelming pada meta mengatakan Anda dapat menyimpan byte dengan kari
Cyoce
@Cyoce sepertinya kari tidak berfungsi dalam kasus ini ( s->j->{...}). Saya pikir Java tidak mendukungnya dengan baik atau saya salah mengaturnya.
GamrCorps
Bahasa yang dikompilasi mungkin mengalami kesulitan dalam menjelajah karena fungsi kelas satu
CalculatorFeline
@GamrCorps Saya akan memeriksa dan melihat apakah saya bisa membuatnya bekerja ketika saya sampai di rumah
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;}

Penguji:

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

Penguji:

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

Dyalog APL, 77 45 42 byte

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

t[... ]huruf t dengan indeks ...
t←⌽⍞ t mendapat input teks terbalik
i←⍳⍴t saya mendapat indeks panjang t
/¨⊂i beberapa (3) pilihan elemen boolean dari i :
1. (t∊'aeiou')boolean di mana vokal
2. (' '=t)boolean di mana ruang
3. 1semuanya ∪∊unik dari yang terdaftar ( diratakan) 3 pilihan
⌽⎕↓⌽drop karakter terakhir yang di-input-input (sama seperti (-⎕)↓)
⌽i~ membalikkan indeks yang tersisa setelah menghapus beberapa


Jawaban asli:

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

Ehm, ya, itu dia agak sulit untuk dibaca. Pada dasarnya terjemahan langsung OP ke APL:

  1. Masukan terbalik.
  2. Jika panjang yang dibutuhkan lebih panjang atau sama dengan jumlah string input (terbalik), lalu kembalikan argumen terbalik (terbalik).
  3. Lain, jika argumen memiliki vokal, hapus yang pertama (yaitu yang terakhir) dan panggilan secara rekursif pada apa yang tersisa.
  4. Lain, jika argumen memiliki ruang, hapus yang pertama (yaitu yang terakhir) dan panggil secara rekursif tentang apa yang tersisa.
  5. Lain, hapus karakter pertama (yaitu terakhir) dan panggil secara rekursif tentang apa yang tersisa.
Adm
sumber
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&]

Pasti ada cara yang lebih baik dari ini ..

A Simmons
sumber
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))])}

* Edit 36 ​​byte yang disimpan melalui penulisan ulang dengan utf8ToInt-> intToUtf8konversi tidak strstplitdanpaste0(...,collapse)

ungolfed dengan penjelasan

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
sumber