もっとカウベル…!


42

あなたはに技術サポートを提供している彼はブルー・オイスター・カルトの記録セッションを生成してブルースディッキンソン。彼がより多くのカウベルを要求するとき、あなたは彼にそれを与えることができます。

あなたのタスク

入力として文字列(または言語で同等のもの)を受け取り、もう1つのカウベルを含む関連文字列を出力するプログラムまたは関数を作成します。

文字列には何個のカウベルが含まれていますか?

文字列に含まれるカウベルの数は、文字列の文字を並べ替えることによって取得できる「カウベル」の個別のコピーの最大数に等しくなります。たとえば、"bbbccceeellllllooowwwwwwwww"3つのカウベルが含まれ"bbccceeellllllooowwwwwwwww""bbbccceeelllllooowwwwwwwww"それぞれに2つのカウベル"cowbel"が含まれ、0のカウベルが含まれます。

出力は入力とどのように関連する必要がありますか?

出力は、入力文字列とカウベルの数を増やすために必要な入力文字列の最短プレフィックスのこの順序での連結で構成する必要があります。

たとえば、2つではなく3つのカウベルを含める"bbbccceeelllllooowwwwwwwww"ために1つ追加"l"するだけで十分です。それを含む最短のプレフィックス"l""bbbccceeel"です。したがって、入力がの場合、出力は"bbbccceeelllllooowwwwwwwww"である必要があります"bbbccceeelllllooowwwwwwwwwbbbccceeel"

技術

  • 入力には印刷可能なASCII文字のみが含まれていると想定できます。言語の文字列処理に迷惑な文字(改行やなど\)が1つまたは2つある場合、入力にそれらが含まれていないと想定できます。この制限に言及してください。
  • さらに、入力のアルファベット文字がすべて小文字またはすべて大文字であると想定することもできます。これらのいずれかを想定しない場合は、大文字と小文字を区別せずにカウベルを数えてください。
  • あなたはさらに、入力文字のそれぞれの少なくとも一つのコピーが含まれていると仮定してbcelo、とw。これは、文字列のプレフィックスを連結して、より多くのカウベルを含む文字列を生成できると仮定するのと同じです。(入力文字列自体にカウベルを含める必要はありません。)
  • もしあなたの言語がこの問題を解決するビルトインを持っているなら...そしてそれを真剣に使いましょう。

金メッキおむつ

スタジオでの録音時間は高価なので、コードはできるだけ短くする必要があります。最少バイトのエントリが勝者です!

テストケース

(コピー/貼り付けを簡単にするペーストビンリンク

テスト入力#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

コピー/貼り付け用に貼り付けリンクが追加されました。この投稿でテストケースを非表示/折りたたみ/表示する方法があり、垂直方向のスペースを節約できる場合は、ぜひ学びたいと思います。
グレッグマーティン

2
通常、人々test case -> resultは1つの大きなフォーマット済みのコードブロックで使用します。審美的にはるかに優れており、貼り付けが簡単です。
FlipTack

1
@MatthewRoh L単語に2つのsがあるという事実は別として、これは挑戦が求めるものではありません。
マーティンエンダー

回答:


13

ピップ50 42 38バイト

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

文字列をコマンドライン引数として渡し、必要に応じて引用符で囲みます。オンラインでお試しください!

説明

これを、カウベル機能と完全なプログラムの2つの部分で説明します。まず、文字列のカウベルの量を計算する関数を次に示します。

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が、私は(新しいPIPに)IDEの間違った使用している場合があります
アルバート・レンショウ

@AlbertRenshawが得られますcowbell cowbell cowbeecowbellオンラインで試してみてください)。TIOまたはローカルコピーを使用していますか?
DLosc

いいね!引数addではなく、フィールド「input」の下に貼り付けていました。+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'3バイトであるwはcharのが、文字用'c''b'私はバイトを毎回保存するために、それぞれ自分のASCII値99と98を入力することができます。(編集:@Titusのおかげで、すべて2バイトの数値ASCII値である大文字入力のみを使用してすべてのCOWBELL文字でこれを行うことがわかっています)

•はr=~-l/2されr=(l-1)/2bitshiftsを使用して

a[++i]index(i)で文字を取得し、同時にインデックスを繰り返し処理しています。の代わりに開始ii=-1ますi=0(別のバイトを保存するのzと同じように開始しz=iます)


1
大文字入力で8バイトを節約:すべてのASCIIコードは100未満です。
Titus

@Titus Brilliant!編集中のタイタス、ありがとうございます
アルバートレンショー

1
現在、「2番目に定義されているint(この場合)は常に1 [...]に設定されています」というステートメントに関する質問がありますc。私たちの何人かには奇妙に思えるので、なぜあなたがそこにそう思うのかについてあなたの声明を持ってうれしいです。
-cadaniluk

@Albertは、プログラムc,o,w,b,eが1ではなく同じ値に初期化されることだけに依存している可能性がありますか?ヒント#2は当てはまらないように思われるため、少なくともCIについては知りません。明確にできますか?質問
Felix Dombek

1
@FelixDombekも指摘してくれてありがとう!デフです。未定義の動作、多くのIDEでそれをシミュレート(ループ)し、常に0としてintを初期化しているようです。テストケースが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 カウベルの数を数えます


@Rodのおかげで-12バイト@Titusのおかげで
-1バイト


あなたは必要いけない[]、それが唯一のパラメータだ時にリストの内包のために、また、あなたがドロップすることができますenumeratemin(s.count(c)/-~(c=='l')for c in"cowbel")どこ-~(n=='l')の書き込みへの短い方法です1+(n=='l')
ロッド

1
Wouldn't >>よりも短く/-~
タイタス

@Titusあなたしている右
OVS

最後の改行スペースを単一のセミコロンで置き換えることにより、バイトを削除する編集が試みられました。
小麦ウィザード

@Möbius returnそれでは、whileループになりませんか?
-ovs

5

Perl 6、91バイト

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

小文字の入力を想定しています。

使い方

ラムダ内部では、文字列内のカウベルの数をカウントするための別のラムダが次のように定義されています。

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.

コードの残りの部分では&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バイト

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バイトを編集し、入力文字列に文字を直接追加し、a早期復帰を回避します(そのためno for/if

Min関数の6値を列挙する2を編集すると、他の13バイトが節約されます

編集3はc関数を再び変更しました。私は冗長を考えたlengthし、splitあまりにも長くなります。私は間違っていた。

小文字入力を想定

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うまくいくと確信しています。
タイタス

@タイタス私は理解しているかわからない。試してみよう
-edc65

@Titusすごい15バイトが保存されました。ありがとう
-edc65

>>!i3バイトを節約します。なぜ使わc(a+=z)ないの?
タイタス

@Titusを使用しますc(a+=z)あまりゴルフされていないバージョンでは、そうではありませんが、ゴルフ少なくなっています。を使用すると、>>!i1バイト節約されます(ゴルフバージョン)。再びありがとう
edc65

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バイトのゴルフをありがとう。


これは、たとえば、ゴルフの前後にスペースを削除するだけで、さらにゴルフすることができます!=
アルバートレンショー

1
@AlbertRenshawありがとうございます-私はそれを試して、構文エラーになったと思いましたが、あなたは正しいです。awk部分もよりゴルフ可能です。私はawkにあまり詳しくありません。
ミッチェルスペクター

うん、私は単純にあなたのコード内の他のスペースや改行を削除し、構文エラーを得ていたが、それは_(ツ)_ /¯働いた1つにしようとした
アルバート・レンショウ

2

JavaScriptの(ES6)、124の 114バイト

数バイトを節約してくれたニールに感謝

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追加のカウベルを完了するために2が必要な場合、これは機能しません。たとえば、入力時にcowbellcowbellcowbelではなくを誤って返しますcowbellcowbell。(あなたがそれを修正できることを願っています—私は非定型アルゴリズムが好きです!)
グレッグ・マーティン

@GregMartinありがとう!私はそれをチェックします!
rahnema1

2

CJam、37

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

オンラインで試す

"\文字を除外できる場合、…

35バイト

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

オンラインで試す

説明

コードは、最初の文字列に文字列の各文字を連続して追加し(元の文字から2倍に)、各文字列のカウベルの数を決定します(「cowbel」の各文字の出現回数をカウントし、「l」 2、最小値を取得します)、カウベルの数が1増加する最初の文字列の位置を見つけ、対応する入力のプレフィックスを取得して、入力文字列の後に配置します。

元の文字列も(文字を追加せずに)含めるために、コードは反復される文字列の前にニュートラル文字を追加します。最初のバージョンではスペースが追加され、2番目のバージョンでは文字列表現、つまり二重引用符で囲まれた文字列が使用されます。

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

「」と「\」文字を除外して大丈夫です!
グレッグマーティン

1

PHP、133バイト

DLoscの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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.