更多牛铃……!


42

您提供技术支持布鲁斯·迪肯森,他产生了蓝牡蛎崇拜记录会话。当他要更多牛铃时,您可以给他。

你的任务

编写一个程序或函数,该程序或函数将字符串(或您的语言中的等效字符串)作为输入,并输出一个包含一个以上牛铃的相关字符串。

一个琴弦包含多少个牛铃?

字符串包含的牛铃数量等于通过排列字符串的字符可获得的“牛铃”不同副本的最大数量。例如,"bbbccceeellllllooowwwwwwwww"包含3个牛铃,而"bbccceeellllllooowwwwwwwww""bbbccceeelllllooowwwwwwwww"分别包含2个牛铃和"cowbel"0个牛铃。

输出应如何与输入相关?

输出应按此顺序包括输入字符串的级联和增加牛铃数量所需的输入字符串的最短前缀。

例如,"bbbccceeelllllooowwwwwwwww"只需要一个"l"即可容纳3个牛铃而不是2个;包含的最短前缀"l""bbbccceeel"。因此,如果输入为"bbbccceeelllllooowwwwwwwww",则输出应为"bbbccceeelllllooowwwwwwwwwbbbccceeel"

技术性

  • 您可以假定输入仅包含可打印的ASCII字符。如果有一个或两个令您的语言的字符串处理令人讨厌的字符(例如换行符或\),则可以假定输入中不包含这些字符,只需提及此限制。
  • 您可以进一步假设输入中的字母字符全部为小写或全部为大写。如果您不选择其中之一,则不区分大小写计算牛铃。
  • 您可以进一步假设输入包含每个字符的至少一个拷贝bcelo,和w。这等效于假定可以将字符串的某些前缀连接到该字符串以产生包含更多牛铃的字符串。(请注意,输入字符串本身不必包含牛铃。)
  • 如果您的语言具有可解决此问题的内建函数...则认真地使用它,真是太棒了。

镀金尿布

由于录制工作室的时间很昂贵,因此您的代码必须尽可能短。字节最少的条目是赢家!

测试用例

pastebin链接使复制/粘贴更加容易)

测试输入#1: "christopher walken begs for more cowbell!"

测试输出#1: "christopher walken begs for more cowbell!christopher wal"

测试输入2: "the quick brown fox jumps over the lazy dog"

测试输出2: "the quick brown fox jumps over the lazy dogthe quick brown fox jumps over the l"

测试输入#3: "cowbell"

测试输出#3: "cowbellcowbell"

测试输入#4: "cowbell cowbell cowbell"

测试输出4: "cowbell cowbell cowbellcowbell"

测试输入#5: "cowbell cowbell cowbel"

测试输出5: "cowbell cowbell cowbelcowbel"

测试输入6: "bcelow"

测试输出6: "bcelowbcel"

测试输入#7: "abcdefghijklmnopqrstuvwxyz"

测试输出#7: "abcdefghijklmnopqrstuvwxyzabcdefghijkl"

测试输入#8: "cccowwwwbbeeeeelllll"

测试输出#8: "cccowwwwbbeeeeelllllccco"

测试输入#9: "be well, programming puzzles & code golf"

测试输出#9: "be well, programming puzzles & code golfbe well, programming puzzles & c"

测试输入#10: "lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. wow!"

测试输出#10: "lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. wow!lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut lab"

测试输入#11:

"c-c-b-c

i have a cow, i have a bell.
uh! bell-cow!
i have a cow, i have a cowbell.
uh! cowbell-cow!

bell-cow, cowbell-cow.
uh! cow-cowbell-bell-cow.
cow-cowbell-bell-cow!
"

测试输出#11:

"c-c-b-c

i have a cow, i have a bell.
uh! bell-cow!
i have a cow, i have a cowbell.
uh! cowbell-cow!

bell-cow, cowbell-cow.
uh! cow-cowbell-bell-cow.
cow-cowbell-bell-cow!
c-c-b-c

i have a cow, i have a bell"

23
COW中回答的任何人都可以赚取10点互联网积分。
帕维尔

3
我认为,如果您在单个代码块中对输入/输出用例进行格式化,那么人们会更容易处理它们。就目前而言,它占用了大量空间,并且对复制粘贴不是很友好。
FryAmTheEggman

添加了Pastebin链接以进行复制/粘贴。如果本文中有隐藏/折叠/显示测试用例的方法,从而节省了垂直空间,我很乐意学习。
格雷格·马丁

2
通常,人们使用test case -> result一个大的预格式化代码块。从美学上讲它更好,并且更容易复制粘贴。
FlipTack

1
@MatthewRoh除了L单词中有两个s 的事实外,这不是挑战所要求的。
马丁·恩德

Answers:


13

50 42 38字节

T$<(MN{_NaM"lcowbe"}//^2M[aYa@<i])++iy

将字符串作为命令行参数传递,如有必要,请加引号。在线尝试!

说明

我将分两部分对此进行解释:牛铃函数和完整程序。首先,这是计算字符串中牛铃数量的函数:

MN{_NaM"lcowbe"}//^2

{...}定义一个函数。许多Pip运算子在套用至函式后,会传回另一个函式;例如,-{a+1}与相同{-(a+1)}。所以上面相当于

{MN(_NaM"lcowbe")//^2}

其工作原理如下:

{                    }  Function, in which a is the 1st argument (the string)
    _Na                 Lambda fn: returns number of times its argument occurs in a
       M"lcowbe"        Map that function to the characters of "lcowbe"
                   ^2   A devious way to get [2]: split the scalar 2 into characters
   (            )//     Int-divide the list of character counts by [2]
                        Since the lists are not the same length, this divides the first
                          element (# of l's) by 2 and leaves the others alone
 MN                     Take the min of the resulting list

现在我们有了完整的程序:

T$<(MN{_NaM"lcowbe"}//^2M[aYa@<i])++iy
                                        a is 1st cmdline arg, i is 0 (implicit)
T                                       Loop till condition is true:
                            a@<i        Slice leftmost i characters of a
                           Y            Yank that into y variable
                         [a     ]       List containing a and that value
                        M               To that list, map...
    MN{_NaM"lcowbe"}//^2                ... the cowbell function
                                        Result: a list containing the amount of cowbell
                                        in the original string and the amount in the slice
 $<(                             )      Fold on less-than: true if the first element is
                                        less than the second, otherwise false
                                  ++i   In the loop, increment i
                                     y  Once the loop exits, print y (the latest slice)

我输入cowbell cowbell cowbee的内容是,cowbellcowbelcowbel但我使用的IDE错误(PIP的新手)
Albert Renshaw

我得到@AlbertRenshaw cowbell cowbell cowbeecowbell在线尝试)。您正在使用TIO还是本地副本?
DLosc

不错哦!我将其粘贴在“输入”字段下而不是参数add下。+1
艾伯特·伦肖

真是一流。我将其移植到javascript。
edc65

6

C,511 488 474 470 463 454

void f(char*a){char*s;int i=-1,c,o,w,b,e=b=w=o=c=1,l=3,n,r,z=i;for(;s=a[++i];c+=s==67,o+=s==79,w+=s==87,b+=s==66,e+=s==69,l+=s==76);r=~-l/2;n=c<o?c:o;n=w<n?w:n;n=b<n?b:n;n=e<n?e:n;n=r<n?r:n;c=c==n;o=o==n;w=w==n;b=b==n;e=e==n;if(l=r==n?l:0)if(l%2)l=2;else l=1,c=o=w=b=e=0;else l+=l%2;n=c+o+w+b+e+l;for(printf("%s",a);s=n?a[++z]:0;s==67&&c?n--,c--:0,s==79&&o?n--,o--:0,s==87&&w?n--,w--:0,s==66&&b?n--,b--:0,s==69&&e?n--,e--:0,s==76&&l?n--,l--:0,putchar(s));}

在线尝试


可读格式+说明:

void f(char*a){
//a = input

    char*s;

    int i=-1,c,o,w,b,e=b=w=o=c=1,l=3,n,r,z=i;//c,o,w,b,e all start at 1; L starts at 3

    for(;s=a[++i];c+=s==67,o+=s==79,w+=s==87,b+=s==66,e+=s==69,l+=s==76);
    //loop to obtain number of times each character C,O,W,B,E,L is found in string (using the ASCII numeric values of each letter)

    //to get an extra cowbell we need to increment C,O,W,B,E by 1 and L by 2 (two Ls in cowbell); except we don't have to because we already did that by starting them at c=1, o=1, w=1, b=1, e=1, L=3 when we declared them. 

    r=~-l/2;
    //r is half of (1 less the number of times L is in string (+ init value))

    n=c<o?c:o;n=w<n?w:n;n=b<n?b:n;n=e<n?e:n;n=r<n?r:n;
    //n is the number of times that the least occouring character appears in the string, (use R instead of L since cowbell has two L's in it and we just need ~-l/2)

    c=c==n;o=o==n;w=w==n;b=b==n;e=e==n;
    //convert c,o,w,b,e to BOOL of whether or not we need 1 more of that letter to create one more cowbell (logic for L handled below since it's trickier)

    if(l=r==n?l:0)//if L-1/2 is [or is tied for] least occurring character do below logic, else set l to 0 and skip to `else`
        if(l%2)//if l is divisible by 2 then we need 2 more Ls
            l=2;
        else //otherwise we just need 1 more l and no other letters
            l=1,c=o=w=b=e=0;
    else //add 1 to L if it's divisible by 2 (meaning just 1 more L is needed in addition to possibly other C,O,W,B,E letters) (*Note: L count started at 3, so a count of 4 would be divisible by 2 and there is only 1 L in the string)
        l+=l%2;

    n=c+o+w+b+e+l;
    //n = number of specific characters we need before we reach 1 more cowbell

    for(printf("%s",a);s=n?a[++z]:0;s==67&&c?n--,c--:0,s==79&&o?n--,o--:0,s==87&&w?n--,w--:0,s==66&&b?n--,b--:0,s==69&&e?n--,e--:0,s==76&&l?n--,l--:0,putchar(s));
    //loop starts by printing the original string, then starts printing it again one character at a time until the required number of C,O,W,B,E,L letters are reached, then break (s=n?a[++z]:0) will return 0 when n is 0. Each letter subtracts from n only when it still requires letters of its type (e.g. b?n--,b--:0)

}

一些有趣的技巧:

•检查字符时,我输入'w'的字符w为3个字节,但是对于字符'c''b'我可以分别输入其ASCII值99和98以每次保存一个字节。(编辑:感谢@Titus,我知道所有COWBELL字母都通过仅使用大写输入(全部为2个字节的数字ascii值)来完成此操作)

r=~-l/2正在r=(l-1)/2使用移位

a[++i]我要在索引(i)处获取字符并同时遍历索引。我刚开始ii=-1,而不是i=0(我做相同的z,并启动它z=i才能拯救他人字节)


1
使用大写输入保存8个字节:所有低于100的ASCII码
Titus

@泰特斯辉煌!谢谢泰特斯(Titus),现在编辑
阿尔伯特·伦肖

1
目前,我们有一个关于您的陈述的问题:“第二个定义的int(在这种情况下c,始终设置为1 [...]”。我们很高兴收到您的陈述,说明您为什么在那边这么想,因为这对我们中的一些人来说似乎很奇怪。
cadaniluk

@Albert可能只是您的程序依赖于c,o,w,b,e初始化为相同的值,而不是1?因为您的提示#2似乎不正确,所以至少对于CI来说并不了解。你能澄清一下吗?SO问题
Felix Dombek

1
@FelixDombek也感谢您指出!是def。未定义的行为,我只是在许多IDE上对其进行了模拟(循环),它似乎总是将int初始化为0。尽管我的逻辑是将它们都设置为1,但我可能毕竟可以将其保留。我认为测试用例在0时正在使用它是一个巧合。干杯
阿尔伯特·伦肖

5

Python 2中,125个 113 112字节

n=lambda s:min(s.count(c)>>(c=='l')for c in "cowbel")
def f(s,i=0):
 while n(s)==n(s+s[:i]):i+=1
 return s+s[:i]

n 计算牛铃的数量


-12字节归@Rod
-1字节归@Titus


你不需要[]的列表理解时,它的唯一的参数,也可以滴enumeratemin(s.count(c)/-~(c=='l')for c in"cowbel")这里-~(n=='l')是一个较短的方式来写1+(n=='l')
罗德

1
也不会转回去>>比短/-~
泰特斯

@Titus你说得对
ovs '17

尝试进行编辑,如果使用单个分号替换最后一个换行符空间,则会删除一个字节。
小麦巫师

@Möbius那会不会return在while循环中?
ovs '17

5

Perl 6,91个字节

{my &c={.comb.Bag.&{|.<c o w b e>,.<l>div 2}.min}
first *.&c>.&c,($_ X~[\,](.comb)».join)}

假定为小写输入。

这个怎么运作

在lambda中,用于计算字符串中牛铃数量的另一个lambda定义如下:

my &c={                                        }  # Lambda, assigned to a variable.
       .comb                                      # Split the string into characters.
            .Bag                                  # Create a Bag (maps items to counts).
                .&{                       }       # Transform it into:
                   |.<c o w b e>,                 #   The counts of those letters, and
                                 .<l>div 2        #   half the count of "l" rounded down.
                                           .min   # Take the minimum count.

其余代码使用此内部lambda &c查找结果,如下所示:

                     [\,](.comb)».join   # All prefixes of the input,
               ($_ X~                 )  # each appended to the input.
first         ,                          # Return the first one for which:
      *.&c>                              #   The cowbell count is greater than
           .&c                           #   the cowbell count of the input.

4

MATL38 37字节

@DLosc使用模板字符串lcowbe而不是@DLosc的想法,节省了1个字节cowbel

n`Gt@q:)hXK!'lcowbe'=s32BQ/kX<wy-Q]xK

输入字符均为小写。如果输入中包含换行符,则需要输入换行符作为其ASCII代码并与普通字符连接(请参见链接中所有测试用例的最后输入)。

在线尝试!验证所有测试用例


3

的JavaScript(ES6),106 107 113 126 141

@DLosc将Pip答案移植到javascript。我需要一些时间来完全理解它,这是个天才。

在@Titus的提示之后编辑 -15个字节,直接将char附加到输入字符串中,a并避免提早返回(因此no for/if

编辑2枚举Min函数的6值可节省其他13个字节

编辑3再次更改c功能。我以为冗长lengthsplit冗长。我错了。

假设小写输入

a=>[...a].some(z=>c(a+=z)>b,c=a=>Math.min(...[...'lcowbe'].map((c,i)=>~-a.split(c).length>>!i)),b=c(a))&&a

少打高尔夫球

a=>{
  c=a=>{ // cowbell functions - count cowbells
    k = [... 'lcowbe'].map((c,i) => 
          (a.split(c).length - 1) // count occurrences of c in a
           / (!i + 1) // divide by 2 if first in list ('l')
    );
    return Math.min(...k);
  };
  b = c(a); // starting number of cowbells
  [...a].some(z => ( // iterate for all chars of a until true
    a += z,
    c(a) > b // exit when I have more cowbells
  ));
  return a;
}

测试

f=
a=>[...a].some(z=>c(a+=z)>b,c=a=>Math.min(...[...'lcowbe'].map((c,i)=>~-a.split(c).length>>!i)),b=c(a))&&a

;["christopher walken begs for more cowbell!"
,"the quick brown fox jumps over the lazy dog"
,"cowbell"
,"cowbell cowbell cowbell"
,"cowbell cowbell cowbel"
,"bcelow"
,"abcdefghijklmnopqrstuvwxyz"
,"cccowwwwbbeeeeelllll"
,"be well, programming puzzles & code golf"
,"lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. wow!"
,`c-c-b-c
 
i have a cow, i have a bell.
uh! bell-cow!
i have a cow, i have a cowbell.
uh! cowbell-cow!
 
bell-cow, cowbell-cow.
uh! cow-cowbell-bell-cow.
cow-cowbell-bell-cow!
`].forEach(x=>console.log(x+'\n\n'+f(x)))


我想那k[x]++会由于而失败undefined。但我可以肯定这是for(i=0;c(a)==c(a+=a[i++]);),a可行的。
泰特斯

@Titus我不确定。我会尝试一下
edc65 '17

@Titus哇保存了15个字节,非常感谢
edc65

>>!i节省3个字节。你为什么不使用c(a+=z)
泰特斯

我使用@Titus c(a+=z)。不要在少golfed版本,因为它是,你看,少golfed。使用>>!i将节省1个字节(在高尔夫球版本中)。再次感谢
edc65 '17

2

Bash + Unix实用程序,184个字节

f()(tr -cd cowbel<<<"$1"|sed 's/\(.\)/\1\
/g'|sort|uniq -c|awk '{print int($1/(($2=="l")?2:1))}'|sort -n|head -1)
for((m=1;`f "$1${1:0:m}"`!=$[`f "$1"`+1];m++)){ :;}
echo "$1${1:0:$m}"

在线尝试!

感谢@AlbertRenshaw打高尔夫球2个字节。


这可以进一步打高尔夫球,例如仅在!=
Albert Renshaw

1
@AlbertRenshaw谢谢您-我以为我已经尝试过并获得语法错误,但是您是对的。awk部分也可以打高尔夫球。我对awk不太熟悉。
米切尔·史派克

是的,我天真地尝试删除代码中的其他空格和换行符,并遇到语法错误,但是在那个上它起作用了__(ツ)_ /
Albert Renshaw

2

的JavaScript(ES6),124个 114字节

感谢Neil节省了一些字节

a=>eval("for(c=0,d=a;(A=$=>Math.min([...'cowbel'].map(_=>($.split(_).length-1)>>(_=='l'))))(a)==A(d+=a[c++]););d")

由于这与现有的JavaScript答案完全不同,因此我花了很多时间,因此决定自己创建一个答案。

用法

f=a=>eval("for(c=0,d=a;(A=$=>Math.min([...'cowbel'].map(_=>($.split(_).length-1)>>(_=='l'))))(a)==A(d+=a[c++]););d")
f("cowbell")

输出量

"cowbellcowbell"

.sort()[0]是一个很棒的主意。eval是邪恶的。:D
泰特斯

谢谢;-)我首先使用了Math.min(),但是那花了很多字符,而且我认为还有一种更短的方法。是的,eval打高尔夫球真的很棒。
路加福音

如果只是.sort()[0]工作,这将只花费10个字节,但它没有,和.sort((a,b)=>a-b)[0]费20个字节,但Math.min(...)成本只有13
尼尔

2

八度,80 87 97字节

s=input('');k=1;do;until(x=@(A)min(fix(sum('cowbel'==A')./('111112'-48))))(b=[s s(1:++k)])>x(s);b

在线尝试!


1
当我们需要两个l秒来完成额外的牛铃时,这将不起作用。例如,在输入时cowbell,它错误地返回cowbellcowbel而不是cowbellcowbell。(我希望您能解决它-我喜欢非典型算法!)
Greg Martin

@GregMartin谢谢!我会che!
rahnema1年

2

CJam,37岁

q___S\+{+"cowbel"1$fe=)2/+:e<\}%()#)<

在线尝试

如果我可以排除"\字符,那么……

35字节

q___`{+"cowbel"1$fe=)2/+:e<\}%()#)<

在线尝试

说明

该代码依次将字符串的每个字符附加到初始字符串(从原始字符串变为双倍字符串),确定每个字符串的牛铃数(计算每个字符在“ cowbel”中的出现次数,然后将其除以“ l”乘以2,然后取最小值),找到牛铃数增加1的第一个字符串的位置,然后取输入的相应前缀,并将其放在输入字符串之后。

为了也包括原始字符串(不附加任何字符),代码在要迭代的字符串前添加了中性字符。第一个版本带有空格,第二个版本使用字符串表示形式,即双引号之间的字符串。

q___          read input and make 3 more copies: one for output, one for prefix,
               one for appending and one for iterating
S\+           prepend a space to the iterating string
              or
`             get the string representation
{…}%          map each character of the string
  +           append the character to the previous string
  "cowbel"    push this string
  1$          copy the appended string
  fe=         get the number of occurrences of each "cowbel" character
  )2/+        take out the last number, divide by 2 and put it back
  :e<         find the minimum
  \           swap with the appended string
(             take out the first number (cowbells in the initial string)
)#            increment and find the index of this value in the array
)             increment the index (compensating for taking out one element before)
<             get the corresponding prefix
              another copy of the input is still on the stack
              and they are both printed at the end

除了“和\字符外,我也很满意!
Greg Martin

1

PHP,133字节

@Losc的Pip答案的@ edc65的JavaScript端口的PHP端口。

function f($s){for(;$c=lcowbe[$i];)$a[$c]=substr_count($s,$c)>>!$i++;return min($a);}for($s=$argv[1];f($s)==f($s.=$s[$i++]););echo$s;

从命令行参数接受小写输入。用运行-nr

分解

// function to count the cowbells:
function f($s)
{
    for(;$c=lcowbe[$i];)            # loop through "cowbel" characters
        $a[$c]=substr_count($s,$c)  # count occurences in $s
            >>!$i++;                # divide by 2 if character is "l" (first position)
        return min($a);             # return minimum value
}
for($s=$argv[1];    # copy input to $s, loop:
    f($s)               # 1. count cowbells in $s
    ==                  # 3. keep looping while cowbell counts are equal
    f($s.=$s[$i++])     # 2. append $i-th character of $s to $s, count cowbells
;);
echo$s;             # print $s
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.