連続した文字の実行をnの長さに切り捨てます


14

チャレンジ

入力文字列と整数nを指定すると、連続する文字の実行を最大長nまで切り捨てます。文字は、特殊文字を含め、何でもかまいません。関数は大文字と小文字を区別する必要があり、nの範囲は0から無限です。

入力/出力の例:

f("aaaaaaabbbccCCCcc", 2) //"aabbccCCcc" 
f("aaabbbc", 1) //"abc"
f("abcdefg", 0) //""
f("aaaaaaabccccccccCCCCCC@", 4) //"aaaabccccCCCC@"

得点

スコアリングは、使用されるバイト数に基づいています。かくして

function f(s,n){return s.replace(new RegExp("(.)\\1{"+n+",}","g"),function(x){return x.substr(0, n);});}

104ポイントになります。

ハッピーゴルフ!

編集:言語の制限を削除しましたが、私はまだJavaScriptの回答を見たいです


1
ES6を許可しないのはなぜですか?
TuxCrafting

7
言語要件を失うことをお勧めします。Javascriptは、ここで最も一般的な言語の1つです。あなたが得たもので自己回答すると、おそらくあなたをゴルフに誘ってくれる人を招待するか、別のアプローチであなたを打ち負かそうとします。さらに、十分な評判を得た場合、特定の言語を念頭に置いて質問に報奨金を追加できます。それがうまくいかない場合は、この質問をヒントの質問に変更して、特定のゴルフの助けを求めることができます。
-FryAmTheEggman

結果として言語の制限を削除し、スコアリングルールを変更しました。私はまだjavascriptのエントリーを見たいと思っていますが、4〜5文字のゴルフ言語で生活できると思います。
TestSubject06

プログラミングパズルとコードゴルフへようこそ!コードゴルフのチャレンジは、デフォルトで長さをバイト単位で記録されます。文字の長さでスコアリングすることは可能ですが、このようないくつかの答えが得られます。
デニス

ああ、神。バイトスコアリングに変更されました。
TestSubject06

回答:


6

Python 2、52バイト

lambda s,n:reduce(lambda r,c:r+c*(r[-n:]!=c*n),s,'')

プログラム(54バイト)として記述:

s,n=input();r=''
for c in s:r+=c*(r[-n:]!=c*n)
print r

入力文字列を反復処理し、最後の文字がその文字でない限りs、各文字を出力文字列に追加します。rnr

最後の0文字(空の文字列)ではなく、文字列全体であるn==0ため、これは失敗しr[-0:]ます。ただし、文字列は空のままであるため機能し、0文字の文字列と一致し続けます。

lambda繰り返しのために再帰は56を与えました

f=lambda s,n:s and s[:f(s[1:],n)[:n]!=s[0]*n]+f(s[1:],n)

i最後の文字の繰り返しのカウンターを保持する別の戦略も、最後のn文字を直接チェックするよりも長くなりました。


6

C、81 78

着信文字列を変更します。

c,a;f(p,n)char*p;{char*s=p;for(;*p;s+=c<n)*s=*p++,a^*s?c=0:++c,a=*s;c=a=*s=0;}

テストプログラム

2つのパラメーターが必要です。最初のパラメーターは切り捨てる文字列、2番目のパラメーターは長さの制限です。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, const char **argv)
{
    char *input=malloc(strlen(argv[1])+1);
    strcpy(input,argv[1]);
    f(input,atoi(argv[2]));
    printf("%s\n",input);
    free(input);
    return 0;
}

説明:

c,a;                 //declare two global integers, initialized to zero.
                     //c is the run length, a is the previous character
f(char*p,int n){...} //define function f to truncate input
char*s=p;            //copy p to s; p is source, s is destination
for(;*p              //while there is a source character
;s+=c<n)             //increment copied pointer if run is under the limit
*s=*p++,             //copy from source to destination, increment source
a^*s?c=0:++c,        //if previous character != current then run=0 else increment run
a=*s;                //previous character = current source character
c=a=*s=0;            //after loop, terminate destination string with NUL and reset c and a.

これは、ソースポインターが常に宛先ポインターと等しいかそれよりも大きいため、解析時に文字列を上書きできるためです。


これはすごいです、説明できますか?
TestSubject06

@ TestSubject06-説明を追加しました。
owacoder

これは、n = 0の場合に機能しますか?ここでテストするためにコンパイルすることはできません。
TestSubject06

はい、そうです。コンパイルできるようにテストプログラムを追加しました。
owacoder

素晴らしい、反例は見つかりませんでした。短くてうまくいきます!
TestSubject06

5

Haskell、36バイト

import Data.List
(.group).(=<<).take

のポイントフリーバージョン\n s -> concatMap (take n) (group s)


4

JavascriptをES6、60 54 55 43バイト

@ TestSubject06と@Downgoatのおかげで-12バイト

(s,n)=>s.replace(/(.)\1*/g,x=>x.slice(0,n))

実行例:

f("aaaaaaabbbccCCCcc"      , 2) -> "aabbccCCcc" 
f("aaabbbc"                , 1) -> "abc"
f("abcdefg"                , 0) -> ""
f("aaaaaaabccccccccCCCCCC@", 4) -> "aaaabccccCCCC@"
f("a"                      , 1) -> "a"

f( "a"、1)-> ""
TestSubject06

1
RegExpは動的に制御されないため、RegExp( "(。)\\ 1 *"、 "g")-> /(.)\1*/g
TestSubject06

1
変換RegExp("(.)\\1*","g")/(.)\1*/g
Downgoat

1
JSでこれが完全に異なる角度から来ない限り、これが小さくなることはありません。@Dendrobiumさん、お疲れ様でした!
TestSubject06

1
に変更(s,n)して1バイト削ります。s=>n使用法は次のようになりますf("aaaaaaabbbccCCCcc")(2)
パトリックロバーツ

3

MATL、9バイト

Y'i2$X<Y"

オンラインで試す

説明

        % Implicitly grab input as a string
Y'      % Perform run-length encoding. Pushes the values and the run-lengths to the stack
i       % Explicitly grab the second input
2$X<    % Compute the minimum of the run lengths and the max run-length
Y"      % Perform run-length decoding with these new run lengths
        % Implicitly display the result

'@@@@@ bbbbbcccddeegffsassss' 3から '@@@ bbbcccddeegffsass'が返されましたが、最後の 's'がありませ
ん-TestSubject06

@ TestSubject06それを指摘してくれてありがとう。
-Suever



2

Python 2、56バイト

import re
lambda s,n:re.sub(r'(.)(\1{%d})\1*'%n,r'\2',s)

2

gs2、6バイト

CP437でエンコード

╠c╨<ΘΣ

これは、スタックの一番上の数字とその下の文字列を期待する無名関数(ブロック)です。

     Σ   Wrap previous five bytes in a block:
╠          Pop number into register A.
 c         Group string.
    Θ      Map previous two bytes over each group:
  ╨<         Take the first A bytes.

オンラインでお試しください。(ここのコードはlines, dump, read number, [the answer], run-blockです。)


1

Perl 6の 38の  36バイト

->$_,$n {S:g/(.)$0**{$n..*}/{$0 x$n}/}
->$_,\n{S:g/(.)$0**{n..*}/{$0 x n}/}

説明:

-> $_, \n { # pointy block lambda
  # regex replace ( return without modifying variant )
  # globally
  S:global /
    # a char
    (.)
    # followed by 「n」 or more identical chars
    $0 ** { n .. * }
  /{
    # repeat char 「n」 times
    $0 x n
  }/
}

テスト:

#! /usr/bin/env perl6
use v6.c;
use Test;

my &truncate-char-runs-to = ->$_,\n{S:g/(.)$0**{n..*}/{$0 x n}/}

my @tests = (
  ("aaaaaaabbbccCCCcc", 2) => "aabbccCCcc",
  ("aaabbbc", 1) => "abc",
  ("abcdefg", 0) => "",
  ("aaaaaaabccccccccCCCCCC@", 4) => "aaaabccccCCCC@",
);

plan +@tests;

for @tests -> $_ ( :key(@input), :value($expected) ) {
  is truncate-char-runs-to(|@input), $expected, qq'("@input[0]", @input[1]) => "$expected"';
}
1..4
ok 1 - ("aaaaaaabbbccCCCcc", 2) => "aabbccCCcc"
ok 2 - ("aaabbbc", 1) => "abc"
ok 3 - ("abcdefg", 0) => ""
ok 4 - ("aaaaaaabccccccccCCCCCC@", 4) => "aaaabccccCCCC@"

0

Javascript ES5、73

function f(s,n){return s.replace(RegExp("(.)(\\1{"+n+"})\\1*","g"),"$2")}

PythonのanswerからLynnの正規表現を再利用します


コードは、nがゼロの場合を処理せず、元の文字列全体を返すだけです。
-TestSubject06

はい、Firefoxでは、中括弧とreturnステートメントを削除できますが、その構文は(残念ながら)非推奨であり、削除されます(実際にはいくつかのバージョンが存在しなかったため、元に戻したことに気付きませんでした)。
デンドロビウム

new-4バイトのキーワードを削除することもできます。
デンドロビウム

@ TestSubject06おかげで、回答を編集しました。テストケースに合格したと思います。
-FryAmTheEggman

0

Perl 5、50バイト

46バイトのコード+ 3 -iと1の場合-p

経由で切り捨てる番号を取得し-iます。

s!(.)\1+!$&=~s/(.{$^I}).+/$1/r!ge

使用法

perl -i4 -pe 's!(.)\1+!$&=~s/(.{$^I}).+/$1/r!ge' <<< 'aaaaaaabccccccccCCCCCC@'
aaaabccccCCCC@

なぜ-p1バイトしかないのですか?
someonewithpc

@someonewithpcを-eこれらのオプションと組み合わせることができる場合、1バイトしか消費しません。スクリプトをファイルから実行する必要がある場合、スペースに3のコストがかかり、自分自身にフラグを立てます。私が試してみようと思うメタ投稿がありますが、今はモバイルです。
ドムヘイスティングス


0

Bash 46バイト

read c;sed -r ":l;s/(.)(\1{$c})(.*)/\2\3/;t l"

使用法:制限する文字数を入力し、Enterキーを押して文字列を入力します。Ctrl+ Dで終了sed(EOFを送信)。


0

Java 7、107 106バイト

String c(String s,int i){String x="";for(int i=-1;++i<j;)x+="$1";return s.replaceAll("(.)\\1{"+i+",}",x);}

文字列連結のための以前の代替インラインforループ(これはString s="";for(int i=-1;++i<j;)s+="$1";残念ながら1バイト多くなります):

String c(String s,int i){return s.replaceAll("(.)\\1{"+i+",}",new String(new char[i]).replace("\0","$1")));}

未ゴルフ&テストケース:

ここで試してみてください。

class Main {
  static String c(String s, int i){
    String x="";
    for(int j = -1; ++j < i;){
      x += "$1";
    }
    return s.replaceAll("(.)\\1{"+i+",}", x);
  }

  public static void main(String[] a){
    System.out.println(c("aaaaaaabbbccCCCcc", 2));
    System.out.println(c("aaabbbc", 1));
    System.out.println(c("abcdefg", 0));
    System.out.println(c("aaaaaaabccccccccCCCCCC@", 4));
    System.out.println(c("@@@@@bbbbbcccddeegffsassss", 5));
  }
}

出力:

aabbccCCcc
abc

aaaabccccCCCC@
@@@@@bbbbbcccddeegffsassss

0

Javascript(外部ライブラリを使用)(115バイト)

(s,r)=>_.From(s).Aggregate((c,n)=>{if(c.a!=n){c.c=1;c.a=n}else{c.c++}if(c.c<=r){c.b+=n}return c},{a:"",b:"",c:0}).b

libへのリンク: https //github.com/mvegh1/Enumerable

コードの説明:文字列をライブラリにロードします。ライブラリは内部的にchar配列として解析します。シーケンスにアキュムレーターを適用し、カスタムオブジェクトをシード値として渡します。プロパティaは現在の要素、bは蓄積された文字列、cは現在の要素の連続カウントです。アキュムレータは、現在の反復値nが最後の要素値caに等しいかどうかを確認します。そうでない場合は、カウントを1にリセットし、現在の要素を設定します。現在の要素のカウントが目的の長さ以下の場合、それを戻り文字列に蓄積します。最後に、蓄積された文字列であるプロパティbを返します。最もゴルフなコードではありませんが、うまくいく解決策を手に入れて幸せです...

ここに画像の説明を入力してください


0

J、31 30バイト

((<.#@>)#{.@>@])]<;.1~1,2~:/\]

入力文字列を同一文字の実行(部分文字列)にグループ化し、その実行の最小の長さと、文字列を切り捨てるために入力された最大の長さを取得します。次に、各実行の最初の文字を何回もコピーします。

使用法

   f =: ((<.#@>)#{.@>@])]<;.1~1,2~:/\]
   2 f 'aaaaaaabbbccCCCcc'
aabbccCCcc
   1 f 'aaabbbc'
abc
   0 f 'abcdefg'

   4 f 'aaaaaaabccccccccCCCCCC@'
aaaabccccCCCC@

説明

((<.#@>)#{.@>@])]<;.1~1,2~:/\]  Input: k on LHS, s on RHS
                             ]  Get s
                        2~:/\   Test if each pair of consecutive chars are not equal
                      1,        Prepend a 1
                ]               Get s
                 <;.1~          Chop s where a 1 occurs to get the runs in s
    #@>                         Get the length of each run
  <.                            Take the min of the length and k
         {.@>@]                 Get the head of each run
        #                       Copy the head of each run min(k, len(run)) times
                                Return that string as the result

0

Dyalog APL22 20 バイト

(∊⊢↑¨⍨⎕⌊⍴¨)⊢⊂⍨1,2≠/⊢

nを要求し、入力文字列を引数として受け取ります。

(暗黙の機能...
    平ら
    ⊢↑¨⍨に切り捨て引数(すなわち、各パーティション)の各要素
    ⎕⌊⍴¨の数値入力の最小値と現在の長さ
)[暗黙関数の端部は]に適用される
⊢⊂⍨で分配入力ᴛʀᴜᴇのS
1, ᴛʀᴜᴇにプリペンド(最初の文字は)その非現存前身と等しくない
2≠/⊢ペアで入力中の文字の、等しくありません



-1

TCC、7 5バイト

$~(;)

入力は、スペースで区切られた文字列と数値です。

オンラインでお試しください!

       | Printing is implicit
$~     | Limit occurence
  (;   | First part of input
    )  | Second part of input

1
回答のどちらのリビジョンもtcc.lua、タイムスタンプが16-07-25 16:57 UTCのファイルでは機能せず、一度に複数の入力を読み取ることができませんでした。回答にチャレンジをポストデートする言語のバージョンが必要な場合は、ヘッダーで非競合としてラベル付けする必要があります。あなたがするとき、私は下票を削除します。
デニス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.