琴弦中紧缩的元音


22

任务描述

有时,您确实需要在很小的空间里容纳正在写的东西。可能会很想丢元音和其他内容,但如果失败了,谁真正需要空格?谢谢!

编写一个函数或程序,该函数或程序除去小写的元音aeiou,然后除去空格,然后除去输入字符串中的所有字符。此外,每次删除字符时,它必须是最有资格删除的字符。它必须重复此过程,直到字符串不超过给定的输入长度为止。

†“这完全可读!”但是,如果您正在阅读此脚注,则可能不是,真的... :)

例子

在这里,您可以看到此过程适用于连续较小的输入大小:

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

将字符串压缩到17个字符后,我们用完了元音以进行删除,因此我们删除的下一个字符是最右边的空格;当我们击中14个字符时,我们删除了所有的元音空格,因此我们只需要从右到左开始用力嚼字符串。

以下是一些伪代码的 Python代码可以解决此难题:

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

规则

  • 这是,因此以字节为单位的最短代码获胜。

  • 输入字符串将由可打印的ASCII字符组成,从空格(,十进制32)到代字号(~,十进制126)并包括在内。AEIOU字符串中将没有大写元音。特别是,不会涉及Unicode,制表符或换行符。

  • 调用输入字符串s和输入目标长度t。这样就保证了0 <t≤length(s)≤10000。(特别是,输入字符串永远不会为空。如果t = length(s),则应只返回未修改的字符串。)

测试用例

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
y元音吗?
edc65 '16

1
不敢相信我忘了解释!不,aeiou是元音AEIOU,为了简单起见,不会出现。(整个大写/小写字母不是我想要关注的。)我添加了说明。
林恩

1
非常好的挑战!
路易斯·门多

@ edc65别忘了w(例如,在单词co ww是元音!)当然,这已经解决了,但是对于没有说明元音的集合是的情况aeiou,您有时应该包含yw。:-O
corsiKa '16

与打高尔夫球无关,但考虑for index, char in enumerate(string)而不是range(len(str))构造
Jeremy Weirich

Answers:


6

MATL,20字节

t11Y2mEG32=+K#Si:)S)

在线尝试!

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

包括+4 -Xlpi(可省略-X,但在STDERR上留下难看的警告)

使用-i选项后的数字和STDIN上的输入来运行(也支持多行)。例如perl -Xlpi50 crunch.pl <<< "Duis commodo scelerisque ex, ac consectetur metus rhoncus."

crunch.pl

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

你不需要之间的空间/$+/while
hmatt1

我认为您可以通过使用^ I(制表符)而不是“ ^ I”来剃光字节。(未经测试。)
msh210 '16

@chilemagic:在/ $ + /之间删除空格,而仅适用于较旧的perls。最近的perls更改了解析器,以保持打开添加新正则表达式修饰符(如aw修饰符)的能力
Ton Hospel

@ msh210:适用于某些魔术变量,但不适用于基于空格的变量
Ton Hospel

6

JavaScript(ES6),66 61字节

@Neil节省了5个字节

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

我认为正则表达式无法进一步推广。令人惊讶的是,我想出的从前到后删除的最短时间是一个字节长:

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

更有趣的尝试(ES7),134个字节

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

这使用类似于MATL答案的方法。


1
我不在乎它是否不能打高尔夫球,那是一个美丽的正则表达式。
尼尔

尽管我刚刚注意到您可以|.$/,"$1$2"用来保存5个字节。
尼尔

@Neil感谢您的提示!
ETHproductions's

2

sh + gnu sed,78 61

将字符串提供给STDIN,长度作为第一个参数。

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个字节

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

将输入作为命令参数,格式lua crunch.lua 10 "This is a string"为output Ths sstrng

说明:

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

从右侧删除会添加大量字符,也许有更好的方法可以做到这一点。

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

使用-i输入数字。它是65个字符加3的ip以及l在命令行上。

运行:

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

您可以使用y///c代替,length也可以将while循环移至末尾:s///||s///||s///while$^I<y///c
andlrc

1

Java 8,303字节

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

这太长了。不适尝试尽快将其缩短。如果Java有一个用于反转字符串和向后替换的方法,那将会更短。

测试以下内容:

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
meta上的压倒多数表示,您可以使用currying节省一个字节
Cyoce

@Cyoce在这种情况下(s->j->{...})似乎无法使用curring 。我认为Java不能很好地支持它,或者我将其设置为错误。
GamrCorps'3

编译语言可能有一个困难时期,因为第一类函数柯里
CalculatorFeline

@GamrCorps我将检查并确定我回家后能否使其工作
Cyoce

1

C#,180个字节

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

测试人员:

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

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

测试人员:

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

1

Dyalog APL,77 45 42字节

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

t[… 带索引]t字母...
t←⌽⍞ t获得反向文本输入
i←⍳⍴t i得到长度为t的索引
/¨⊂i倍数(3)i元素的布尔选择:
1. (t∊'aeiou')布尔元音
2. (' '=t)布尔空间
3. 所征对象的1所有 ∪∊唯一性( 3个选择
⌽⎕↓⌽删除最后一个求值输入的字符(与相同(-⎕)↓
⌽i~,在删除了一些后反转了剩余的索引


原始答案:

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

埃姆,是啊,这一个有点难以阅读。基本上将OP直接转换为APL:

  1. 反向输入。
  2. 如果所需的长度大于或等于(反向)输入字符串的计数,则返回反向(反向)参数。
  3. 否则,如果参数有任何元音,则删除第一个(即最后一个),然后递归调用剩下的。
  4. 否则,如果参数有任何空格,则删除第一个(即最后一个),然后递归调用剩余的内容。
  5. 否则,删除第一个(即最后一个)字符并递归调用剩余的字符。

0

Mathematica,201字节

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

肯定有比这更好的方法了。


0

R,169143字节

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

*编辑通过重写utf8ToInt-> intToUtf8转换不保存36个字节,strstplit并且paste0(...,collapse)

毫无解释

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))])}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.