연속 문자 실행을 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 포인트입니다.

행복한 골프!

편집 : 언어 제한을 제거했지만 여전히 자바 스크립트 답변을보고 싶습니다.


1
ES6을 허용하지 않는 이유는 무엇입니까?
TuxCrafting

7
언어 요구 사항을 잃어 버리는 것이 좋습니다. 자바 스크립트는 여기서 가장 일반적인 언어 중 하나입니다. 당신이 가진 것에 스스로 대답하면 아마도 사람들이 당신을 골프로 도울 수있게하거나 다른 접근법으로 당신을 이길 수있을 것입니다. 또한 평판이 충분하면 특정 언어를 고려하여 질문에 현상금을 추가 할 수 있습니다. 그래도 문제가 해결되지 않으면이 질문을 질문 으로 수정 하고 특정 골프 도움을 요청하십시오.
FryAmTheEggman

결과적으로 언어 제한이 제거되고 점수 규칙이 변경되었습니다. 나는 여전히 자바 스크립트 항목을보고 싶지만 4-5 자 골프 언어로 살 수 있다고 생각합니다.
TestSubject06

프로그래밍 퍼즐 및 코드 골프에 오신 것을 환영합니다! 코드 골프 챌린지는 기본적으로 바이트 단위 로 점수가 매겨 집니다. 문자 길이로 점수를 매기 는 것이 가능하지만 이와 같은 답변을 얻을 수 있습니다 .
Dennis

오 세상에 바이트 스코어링으로 변경되었습니다.
TestSubject06

답변:


6

파이썬 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

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

테스트 프로그램

두 개의 매개 변수가 필요합니다. 첫 번째는 잘라낼 문자열이고 두 번째는 길이 제한입니다.

#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

하스켈, 36 바이트

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

의 무료 버전 \n s -> concatMap (take n) (group s).


4

자바 스크립트 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
변경하여 1 바이트 면도 (s,n)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 최종 's'가없는 '@@@ bbbcccddeegffsass'를 반환
TestSubject06

@ TestSubject06 지적 해 주셔서 감사합니다.
서버

2

CJam, 12 바이트

{e`\af.e<e~}

온라인으로 사용해보십시오!

설명

e`   e# Run-length encode the input. Gives a list of pair [length character].
\a   e# Swap with maximum and wrap in an array.
f.e< e# For each run, clamp the run-length to the given maximum.
e~   e# Run-length decode.


2

파이썬 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

펄 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

자바 스크립트 ES5, 73

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

Lynn의 정규식을 Python 답변 에서 재사용합니다 .


코드는 n이 0 인 경우를 처리하지 않고 전체 원본 문자열 만 반환합니다.
TestSubject06

예, 파이어 폭스에서, 당신은 괄호와 반환 문을 삭제할 수 있습니다 그 구문은 (슬프게도) 사용되지 않으며 제거됩니다 있지만 (실제로 그들이 다시 가져 실현하지 않았다, 다시 몇 가지 버전을 결석).
Dendrobium

new-4 바이트에 대한 키워드를 삭제할 수도 있습니다 .
Dendrobium

@ TestSubject06 감사합니다. 답변을 편집했으며 지금 테스트 사례를 통과했다고 생각합니다.
FryAmTheEggman

0

펄 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이며 자체 플래그가 지정됩니다. 내가 시도하고 찾을 수있는 메타 게시물이 있지만 지금은 모바일에 있습니다.
Dom Hastings


0

배쉬 46 바이트

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

사용법 : 제한 할 문자 수를 입력하고 Enter 키를 누른 다음 문자열을 입력하십시오. Ctrl+ D종료합니다 sed(EOF 전송).


0

자바 7, 107106 바이트

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

문자열 연결에 대한 이전 대체 인라인 for-loop ( 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

자바 스크립트 (외부 라이브러리 사용) (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이 마지막 요소 값과 같은지 확인합니다. 그렇지 않으면 카운트를 1로 재설정하고 현재 요소를 설정합니다. 현재 요소의 개수가 원하는 길이보다 작거나 같은 경우 반환 문자열에 누적됩니다. 마지막으로 누적 된 문자열 인 속성 b를 반환합니다. 가장 골치 아픈 코드는 아니지만 행복하게 작동하는 솔루션을 얻었습니다.

enter image description here


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 APL , 22 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 인 파일에서 작동 하지 않았으며 한 번에 여러 입력을 읽을 수 없었습니다. 답변에 도전 과제를 게시 한 언어 버전이 필요한 경우 헤더에서 비경쟁 언어로 레이블을 지정해야합니다 . 당신이 할 때 내 downvote를 제거합니다.
Dennis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.