Çıtırtı bir dize ile ünlü


22

Görev tanımı

Bazen küçük bir alana yazdığınız bir şeye gerçekten uymanız gerekir. Ünlüleri bırakmak ve lk thk - ve başarısız olmak, gerçekten kim boşluklara ihtiyaç duyar? Thssprfctlrdbl!

Kaldırır ünlüleri küçük harfli bir işlev veya program yazın aeiouve sonra boşluk ve ardından herhangi bir karakterleri girdi dizesi . Ayrıca, bir karakteri her kaldırışınızda , kaldırmaya uygun en doğru karakter olmalıdır . Dize verilen giriş uzunluğundan daha uzun olmayana kadar bu işlemi tekrarlamalıdır .

† “Bu mükemmel bir şekilde okunuyor!” Ama eğer bu dipnotu okuyorsanız, muhtemelen değil ... :)

Örnekler

Burada art arda daha küçük giriş boyutları için uygulanan bu işlemi görebilirsiniz:

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

Dizeyi 17 karaktere kadar sıktıktan sonra, çıkarmamız için sesli harfler tükenir, bu yüzden kaldırdığımız bir sonraki karakter en sağdaki boşluktur; 14 karaktere bastığımızda , tüm ünlü harfleri ve boşlukları kaldırdık , bu yüzden ipi sağdan sola doğru çekmeye başlıyoruz.

İşte bu meydan okuma çözen bazı sözde kod Python kodu:

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

kurallar

  • Bu , yani bayt cinsinden en kısa kod kazanır.

  • Giriş dizesi, boşluktan ( , ondalık 32) ve tilde ( ~, ondalık 126) içeren basılabilir ASCII karakterlerinden oluşacaktır . AEIOUDize hiçbir büyük harf olmaz . Özellikle, hiçbir Unicode, sekme veya yeni satır eklenmeyecektir.

  • Giriş dizesini s ve giriş hedef uzunluğunu t arayın . Daha sonra, 0 <t ≤ uzunluğu ( ler ) ≤ 10000 garanti edilir. (Özellikle, girdi dizesi boş olmayacak. Eğer t uzunluğunu (= ler ), sadece değiştirilmemiş dize dönmelidir.)

Test durumları

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
ybir sesli harf?
edc65

1
Bunu açıklamayı unuttuğuma inanamıyorum! Hayır, aeiouünlüler ve AEIOUbasitlik için oluşmayacak. (Büyük / küçük harflerin tümü odaklanmak istediğim şey değil.) Açıklama ekledim.
Lynn,

1
Çok güzel bir meydan okuma!
Luis Mendo

@ edc65 unutma w(kelime eş, örneğin w , wTabii ki, bu biri için anlaştık sesli harf!), ama o ünlülerinin kümesidir belirtti değil nereye aeiou, bazen içermelidir yve w. : -O
corsiKa

Golf ile ilgisi yok, fakat yapı for index, char in enumerate(string)yerine düşününrange(len(str))
Jeremy Weirich

Yanıtlar:


6

MATL , 20 bayt

t11Y2mEG32=+K#Si:)S)

Çevrimiçi deneyin!

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 bayt

Şunlar için +4 içerir -Xlpi(-X dışlanabilir, ancak STDERR'de çirkin uyarılar bırakır)

-iSeçeneğin sonrasındaki sayıyı ve STDIN'deki girişi çalıştırın (çoklu satırları da destekler). Örneğinperl -Xlpi50 crunch.pl <<< "Duis commodo scelerisque ex, ac consectetur metus rhoncus."

crunch.pl:

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

/$+/Vewhile
hmatt1

Sanırım "^ I" yerine ^ I (sekme karakteri) kullanarak bir baytı traş ettiniz. (
Denenmemiş

@chilemagic: / $ + / arasında boşluk bırakmak ve sadece eski perls ile çalışmak. Son perls ayrıştırıcıyı yeni regex değiştiricileri ekleme yeteneğini açık tutabilmek için değiştirdi (aw modifier gibi)
Ton Hospel

@ msh210: Bazı sihirli değişkenler için çalışıyor, ancak boşluklara dayalı olanlar için değil
Ton Hospel

6

JavaScript (ES6), 66 61 bayt

@Neil sayesinde 5 bayt kaydedildi

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

Regex'in daha fazla golf oynayabileceğini sanmıyorum. Şaşırtıcı bir şekilde, önden arkaya çıkarmak için bulabildiğim en kısa süre, bir bayt daha uzun:

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

Daha ilginç deneme (ES7), 134 bayt

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

Bu MATL cevabına benzer bir yaklaşım kullanır.


1
Golf oynamak olmasa da umrumda değil, bu güzel bir regex.
Neil

Yine de, |.$/,"$1$2"5 bayt kaydetmek için kullanabileceğinizi fark ettim .
Neil

@Neil Tahmininiz için teşekkürler!
ETHproductions

2

sh + gnu sed, 78 61

Dize STDIN, ilk argüman olarak uzunluğu verin.

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 bayt

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

Biçiminde, komut satırı argümanları olarak girdi Alır lua crunch.lua 10 "This is a string"çıkışı ile Ths sstrng.

Açıklama:

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

Sağdan kaldırmak, tonlarca karakter ekler, belki de bunu yapmanın daha iyi bir yolu vardır.

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

-iNumara girmek için kullanın . Bu 65 karakter artı 3 olduğunu i, pve lkomut satırında.

Çalıştır:

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

Sen kullanabilirsiniz y///cyerine lengthve süre sona döngü taşıyabilirsiniz:s///||s///||s///while$^I<y///c
andlrc

1

Java 8, 303 bayt

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

Bu YOL çok uzun. Yakında kısaltmaya çalışacağım. Java'nın dizeleri ters çevirmek ve geriye doğru değiştirmek için bir yöntemi olsaydı daha kısa olurdu.

Aşağıdakilerle test edin:

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


@Cyoce, bu durumda, köreltmenin işe yaramadığı görülüyor ( s->j->{...}). Bence ya Java çok iyi desteklemiyor ya da yanlış ayarlıyorum.
GamrCorps

Derlenmiş diller, birinci sınıf işlevler nedeniyle muhtemelen kurutmada zor zamanlar geçiriyor
CalculatorFeline

@GamrCorps Eve döndüğümde çalışıp çalışamayacağımı kontrol edip göreceğim
Cyoce

1

C #, 180 bayt

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

Tester:

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 bayt

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

Tester:

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

1

Dyalog APL, 77 45 42 bayt

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

t[... ]mektupları t endeksleriyle ...
t←⌽⍞ t ters metin giriş alır
i←⍳⍴t i uzunluğunun indisleri alır t
/¨⊂i çoklu elemanların (3) mantıksal seçimler i :
1. (t∊'aeiou')boolean sesli
2. (' '=t)Boolean alanı
3. 1Tüm ∪∊kayıtlı benzersiz ( düzleştirilmiş) 3 seçim,
⌽⎕↓⌽değerlendirilen en son girilen karakterleri (aynı (-⎕)↓)
⌽i~, bıraktıktan sonra kalan dizinleri tersine çevirir


Orijinal cevap:

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

Ehm, evet, olan biraz okumak zor. Temel olarak OP'nin APL'ye doğrudan çevirisi:

  1. Ters giriş
  2. İstenilen uzunluk (ters) giriş dizesinin sayısına eşitse daha uzun veya eşitse, ters çevrilmiş (ters) değişkene geri dönün.
  3. Aksi halde, eğer bir argüman ünlüse, ilkini (yani sonuncuyu) kaldırın ve kalanları tekrarlayarak arayın.
  4. Aksi halde, eğer argümanın herhangi bir yeri varsa, ilkini (yani sonuncuyu) kaldırın ve kalanları tekrarlayarak arayın.
  5. Aksi halde, ilk (son karakter) karakteri kaldırın ve kalanları tekrarlayarak arayın.

0

Mathematica, 201 Bayt

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

Bundan daha iyi bir yol olmalı.


0

R ', 169 143 bayt

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

* düzenleme ile yeniden yazma yoluyla 36 bayt kaydedildi utf8ToInt -> intToUtf8dönüşümler strstplitvepaste0(...,collapse)

açıklama ile asılmamış

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))])}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.