Cắt ngắn ký tự liên tiếp chạy đến n chiều dài


14

Các thách thức

Cho một chuỗi đầu vào và một số nguyên n - cắt bất kỳ lần chạy nào của các ký tự liên tiếp đến tối đa n chiều dài. Các nhân vật có thể là bất cứ điều gì, bao gồm các nhân vật đặc biệt. Hàm phải phân biệt chữ hoa chữ thường và n có thể nằm trong khoảng từ 0 đến vô cùng.

Ví dụ đầu vào / đầu ra:

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

Chấm điểm

Việc tính điểm dựa trên số byte được sử dụng. Như vậy

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

sẽ là 104 điểm.

Chúc bạn chơi golf vui vẻ!

Chỉnh sửa: đã loại bỏ giới hạn ngôn ngữ, nhưng tôi vẫn rất thích xem các câu trả lời javascript


1
Tại sao không cho phép ES6?
Thiền vào

7
Tôi khuyên bạn nên mất yêu cầu ngôn ngữ. Javascript là một trong những ngôn ngữ phổ biến nhất ở đây. Tự trả lời với những gì bạn nhận được có thể sẽ mời mọi người giúp bạn chơi gôn hoặc cố gắng đánh bại bạn bằng một cách tiếp cận khác. Hơn nữa, nếu bạn có đủ danh tiếng, bạn có thể thêm một tiền thưởng cho câu hỏi với một ngôn ngữ cụ thể trong tâm trí. Nếu điều đó không phù hợp với bạn, bạn có thể sửa đổi câu hỏi này thành một câu hỏi mẹo và cố gắng yêu cầu trợ giúp chơi gôn cụ thể.
FryAmTheEggman

Đã loại bỏ hạn chế ngôn ngữ và thay đổi quy tắc chấm điểm. Tôi vẫn thích xem các mục javascript, nhưng tôi đoán tôi có thể sống với một số ngôn ngữ golf 4-5 ký tự.
TestSubject06

Chào mừng bạn đến với Câu đố lập trình & Code Golf! Các thử thách golf mã được ghi theo độ dài theo byte theo mặc định. Mặc dù việc ghi điểm theo độ dài bằng các ký tự là có thể, bạn nhất định sẽ nhận được một số câu trả lời như thế này .
Dennis

Ôi Chúa ơi. Thay đổi thành điểm byte.
TestSubject06

Câu trả lời:


6

Python 2, 52 byte

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

Viết ra dưới dạng một chương trình (54 byte):

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

Lặp lại thông qua chuỗi đầu vào s, nối thêm từng ký tự vào chuỗi đầu ra rtrừ khi các nký tự cuối cùng rlà ký tự đó.

Tôi mặc dù điều này sẽ thất bại n==0r[-0:]không phải là 0 ký tự cuối cùng (chuỗi trống), mà là toàn bộ chuỗi. Nhưng, nó hoạt động vì chuỗi vẫn trống, vì vậy nó tiếp tục khớp với chuỗi 0 ký tự.

Một đệ quy lambdađã cho 56 vì sự lặp lại

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

Một chiến lược thay thế để giữ một bộ đếm ilặp lại của nhân vật cuối cùng cũng bật ra lâu hơn là chỉ kiểm tra ntrực tiếp các ký tự cuối cùng .


6

C, 81 78

Sửa đổi chuỗi đến.

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

Chương trình kiểm tra

Yêu cầu hai tham số, đầu tiên là chuỗi để cắt, thứ hai là giới hạn độ dài.

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

Giải trình:

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.

Điều này hoạt động vì con trỏ nguồn sẽ luôn bằng hoặc lớn hơn con trỏ đích, vì vậy chúng ta có thể viết qua chuỗi khi chúng ta phân tích cú pháp.


Điều này thật tuyệt vời, bạn có thể giải thích nó?
TestSubject06

@ TestSubject06 - Đã thêm một lời giải thích.
owacoder

Cái này có hoạt động với trường hợp n = 0 không? Tôi không thể lấy nó để biên dịch để kiểm tra ở đây.
TestSubject06

Vâng, nó làm. Tôi đã thêm một chương trình thử nghiệm để bạn có thể biên dịch.
owacoder

Tuyệt vời, không thể tìm thấy bất kỳ ví dụ truy cập. Ngắn và nó hoạt động!
TestSubject06

5

Haskell, 36 byte

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

Phiên bản miễn phí của \n s -> concatMap (take n) (group s).


4

Javascript ES6, 60 54 55 43 byte

-12 byte nhờ @ TestSubject06 và @Downgoat

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

Ví dụ chạy:

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

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

1
Vì RegExp của bạn không được điều khiển động theo bất kỳ cách nào bạn có thể lưu một số byte bằng RegExp ("(.) \\ 1 *", "g") -> /(.)\1*/g
TestSubject06

1
Chuyển đổi RegExp("(.)\\1*","g")sang/(.)\1*/g
Downgoat

1
Tôi không thấy điều này trở nên nhỏ hơn trong JS trừ khi chúng ta nhìn nó từ một góc độ hoàn toàn khác. Làm tốt lắm @Dendrobium!
TestSubject06

1
Cạo một byte bằng cách thay đổi (s,n)thành s=>n, và việc sử dụng trở thànhf("aaaaaaabbbccCCCcc")(2)
Patrick Roberts

3

MATL, 9 byte

Y'i2$X<Y"

Dùng thử trực tuyến

Giải trình

        % 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 đã trả lại '@@@ bbbcccddeegffsass' đang thiếu 's' cuối cùng
TestSubject06

@ TestSubject06 Cảm ơn bạn đã chỉ ra điều đó.
Suever

2

CJam, 12 byte

{e`\af.e<e~}

Hãy thử trực tuyến!

Giải trình

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

Python 2, 56 byte

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

2

gs2, 6 byte

Được mã hóa trong CP437 :

╠c╨<ΘΣ

Đây là một hàm ẩn danh (khối) mong đợi một số ở trên cùng của ngăn xếp và một chuỗi bên dưới nó.

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

Hãy thử trực tuyến. (Mã ở đây là lines, dump, read number, [the answer], run-block.)


1

Perl 6 ,  38  36 byte

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

Giải trình:

-> $_, \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
  }/
}

Kiểm tra:

#! /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")}

Sử dụng lại regex của Lynn từ câu trả lời Python của cô ấy .


Mã của bạn không xử lý trường hợp n bằng 0, nó chỉ trả về toàn bộ chuỗi gốc.
TestSubject06

Có, trong Firefox, bạn có thể bỏ dấu ngoặc nhọn và trả về câu trả lời , mặc dù cú pháp đó (đáng buồn) không được dùng nữa và sẽ bị xóa (nó thực sự vắng mặt một vài phiên bản, không nhận ra họ đã mang nó trở lại).
Dendrobium

Bạn cũng có thể thả newtừ khóa cho -4 byte.
Dendrobium

@ TestSubject06 Cảm ơn, tôi đã chỉnh sửa câu trả lời của mình và tôi tin rằng nó đã vượt qua các trường hợp thử nghiệm ngay bây giờ.
FryAmTheEggman

0

Perl 5, 50 byte

46 byte mã + 3 cho -ivà 1 cho-p

Lấy số để cắt ngắn thông qua -i.

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

Sử dụng

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

Tại sao -pchỉ có một byte?
someonewithpc

@someonewithpc khi có thể kết hợp với -ecác tùy chọn này chỉ tiêu tốn 1 byte. Nếu tập lệnh phải được chạy từ một tập tin, nó có giá 3 cho khoảng trống và anh ta tự gắn cờ. Có một bài đăng meta tôi sẽ thử và tìm nhưng tôi đang sử dụng điện thoại di động ngay bây giờ.
Dom Hastings


0

Bash 46 byte

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

Cách sử dụng: Nhập số lượng ký tự cần giới hạn, nhấn enter và nhập chuỗi. Ctrl+ Dđể thoát sed(gửi EOF).


0

Java 7, 107 106 byte

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

Vòng lặp nội tuyến thay thế trước đó cho nối chuỗi ( String s="";for(int i=-1;++i<j;)s+="$1";không may hơn 1 byte ):

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

Các trường hợp bất khả kháng & thử nghiệm:

Hãy thử nó ở đây.

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

Đầu ra:

aabbccCCcc
abc

aaaabccccCCCC@
@@@@@bbbbbcccddeegffsassss

0

Javascript (sử dụng thư viện bên ngoài) (115 byte)

(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

Liên kết đến lib: https://github.com/mvegh1/Enumerable

Giải thích mã: Tải chuỗi vào thư viện, phân tích nội bộ dưới dạng mảng char. Áp dụng một bộ tích lũy trên chuỗi, chuyển vào một đối tượng tùy chỉnh làm giá trị hạt giống. Thuộc tính a là phần tử hiện tại, b là chuỗi tích lũy và c là số đếm liên tiếp của phần tử hiện tại. Bộ tích lũy kiểm tra xem giá trị lặp hiện tại, n, có bằng giá trị phần tử cuối cùng không, nếu không, chúng ta đặt lại số đếm thành 1 và đặt phần tử hiện tại. Nếu số lượng của phần tử hiện tại nhỏ hơn hoặc bằng độ dài mong muốn, chúng tôi tích lũy nó vào chuỗi trả về. Cuối cùng, chúng ta trả lại thuộc tính b, chuỗi tích lũy. Không phải mã golf, nhưng tôi rất vui khi có một giải pháp hiệu quả ...

nhập mô tả hình ảnh ở đây


0

J, 31 30 byte

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

Nhóm chuỗi đầu vào thành các lần chạy (chuỗi con) của các ký tự giống hệt nhau và lấy tối thiểu độ dài của lần chạy đó và độ dài tối đa được nhập để cắt chuỗi. Sau đó sao chép ký tự đầu tiên của mỗi lần chạy đó nhiều lần.

Sử dụng

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

   4 f 'aaaaaaabccccccccCCCCCC@'
aaaabccccCCCC@

Giải trình

((<.#@>)#{.@>@])]<;.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

APL Dyalog , 22 20 byte

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

Nhắc cho n và lấy chuỗi đầu vào làm đối số.

(chức năng ngầm ...
    flatten
    ⊢↑¨⍨mỗi phần tử của đối số (tức là mỗi phân vùng) cắt ngắn để
    ⎕⌊⍴¨tối thiểu của đầu vào số và chiều dài hiện tại
)[cuối chức năng ngầm] áp dụng cho
⊢⊂⍨đầu vào phân vùng tại ᴛʀᴜᴇ s của
1, ᴛʀᴜᴇ thêm vào phía trước (các ký tự đầu tiên không bằng với tiền thân không tồn tại của nó)
2≠/⊢cặp ký tự không bằng nhau của các ký tự trong đầu vào



-1

TCC, 7 5 byte

$~(;)

Đầu vào là một chuỗi và một số, được phân tách bằng dấu cách.

Hãy thử trực tuyến!

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

1
Cả bản sửa đổi câu trả lời của bạn đều không hoạt động với tcc.luatệp có dấu thời gian 16-07-25 16:57 UTC, không có khả năng đọc nhiều đầu vào cùng một lúc. Nếu câu trả lời của bạn yêu cầu một phiên bản ngôn ngữ hoãn thử thách, bạn phải gắn nhãn đó là không cạnh tranh trong tiêu đề. Tôi sẽ loại bỏ downvote của tôi khi bạn làm.
Dennis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.