Memotong karakter berturut-turut berjalan hingga n panjang


14

Tantangan

Diberikan string input, dan bilangan bulat n - memotong setiap berjalan karakter berturut-turut hingga maksimum n panjang. Karakter dapat berupa apa saja, termasuk karakter khusus. Fungsi harus peka huruf besar kecil, dan n dapat berkisar dari 0 hingga tak terbatas.

Contoh input / output:

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

Mencetak gol

Penilaian didasarkan pada jumlah byte yang digunakan. Jadi

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

akan menjadi 104 poin.

Selamat bermain golf!

Sunting: pembatasan bahasa yang dihapus, tetapi saya masih ingin melihat jawaban javascript


1
Mengapa tidak mengizinkan ES6?
TuxCrafting

7
Saya akan merekomendasikan kehilangan persyaratan bahasa. Javascript adalah salah satu bahasa yang paling umum di sini. Menjawab sendiri dengan apa yang Anda dapatkan mungkin akan mengundang orang untuk membantu Anda bermain golf, atau mencoba untuk mengalahkan Anda dengan pendekatan lain. Selanjutnya, jika Anda mendapatkan reputasi yang cukup, Anda dapat menambahkan hadiah untuk pertanyaan dengan bahasa tertentu. Jika itu tidak cocok dengan Anda, Anda dapat mengubah pertanyaan ini menjadi pertanyaan tip dan mencoba untuk meminta bantuan golf tertentu.
FryAmTheEggman

Pembatasan bahasa dihapus dan mengubah aturan penilaian sebagai hasilnya. Saya masih ingin melihat entri javascript, tapi saya rasa saya bisa hidup dengan beberapa bahasa golf 4-5 karakter.
TestSubject06

Selamat Datang di Programming Puzzles & Code Golf! Tantangan golf kode ditentukan oleh panjangnya dalam byte secara default. Meskipun mencetak berdasarkan panjang karakter dimungkinkan, Anda pasti mendapatkan beberapa jawaban seperti ini .
Dennis

Ya Tuhan. Diubah menjadi skor byte.
TestSubject06

Jawaban:


6

Python 2, 52 byte

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

Ditulis sebagai sebuah program (54 byte):

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

Iterasi melalui string input s, tambahkan setiap karakter ke string output rkecuali nkarakter terakhir radalah karakter itu.

Saya pikir ini akan gagal n==0karena r[-0:]bukan 0 karakter terakhir (string kosong), tetapi seluruh string. Tapi, ini berfungsi karena string tetap kosong, jadi senada dengan senar 0 karakter.

Rekursif lambdamemberi 56 karena pengulangan

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

Strategi alternatif untuk menjaga counter ipengulangan karakter terakhir juga ternyata lebih lama dari sekadar memeriksa nkarakter terakhir secara langsung.


6

C, 81 78

Memodifikasi string yang masuk.

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

Program Tes

Membutuhkan dua parameter, yang pertama adalah string untuk memotong, yang kedua adalah batas panjang.

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

Penjelasan:

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.

Ini berfungsi karena pointer sumber akan selalu sama dengan atau lebih besar dari pointer tujuan, jadi kita bisa menulis di atas string saat kita menguraikannya.


Ini luar biasa, bisakah Anda menjelaskannya?
TestSubject06

@ TestSubject06 - Menambahkan penjelasan.
owacoder

Apakah ini bekerja dengan case n = 0? Saya tidak bisa membuatnya untuk dikompilasi untuk diuji di sini.
TestSubject06

Ya, benar. Saya menambahkan program uji sehingga Anda dapat mengkompilasi.
owacoder

Luar biasa, tidak dapat menemukan contoh penghitung. Pendek dan berhasil!
TestSubject06

5

Haskell, 36 byte

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

Versi point-free dari \n s -> concatMap (take n) (group s).


4

Javascript ES6, 60 54 55 43 byte

-12 byte terima kasih kepada @ TestSubject06 dan @Downgoat

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

Contoh berjalan:

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

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

1
Karena RegExp Anda tidak dikontrol secara dinamis dengan cara apa pun, Anda dapat menyimpan beberapa byte dengan RegExp ("(.) \\ 1 *", "g") -> /(.)\1*/g
TestSubject06

1
Konversikan RegExp("(.)\\1*","g")ke/(.)\1*/g
Downgoat

1
Saya tidak melihat ini semakin kecil di JS kecuali kita datang dari sudut yang sama sekali berbeda. Kerja bagus @Dendrobium!
TestSubject06

1
Cukur satu byte dengan mengubah (s,n)ke s=>n, dan penggunaannya menjadif("aaaaaaabbbccCCCcc")(2)
Patrick Roberts

3

MATL, 9 byte

Y'i2$X<Y"

Cobalah secara Online

Penjelasan

        % 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

'@@@@@bbbbcccddeegffsassss' 3 kembali '@@@bbcccddeegffsass' yang tidak ada di final '
TestSubject06

@ TestSubject06 Terima kasih telah menunjukkan itu.
Suever

2

CJam, 12 byte

{e`\af.e<e~}

Cobalah online!

Penjelasan

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

Disandikan dalam CP437 :

╠c╨<ΘΣ

Ini adalah fungsi anonim (blok) yang mengharapkan angka di atas tumpukan dan string di bawahnya.

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

Cobalah online. (Kode di sini adalah 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}/}

Penjelasan:

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

Uji:

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

Menggunakan kembali regex Lynn dari jawaban Python- nya .


Kode Anda tidak menangani case di mana n adalah nol, itu hanya mengembalikan seluruh string asli.
TestSubject06

Ya, di Firefox, Anda dapat melepaskan kawat gigi dan mengembalikan pernyataan , meskipun sintaksnya (sayangnya) sudah tidak digunakan lagi dan akan dihapus (sebenarnya tidak ada beberapa versi di belakang, tidak sadar mereka mengembalikannya).
Dendrobium

Anda juga dapat menjatuhkan newkata kunci untuk -4 byte.
Dendrobium

@ TestSubject06 Terima kasih, saya telah mengedit jawaban saya dan saya yakin itu lolos dari kasus uji sekarang.
FryAmTheEggman

0

Perl 5, 50 byte

46 byte kode + 3 untuk -idan 1 untuk-p

Membawa nomor yang akan dipotong melalui -i.

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

Pemakaian

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

Mengapa -phanya satu byte?
someonewithpc

@someonewithpc ketika dapat dikombinasikan dengan -eopsi-opsi ini hanya mengkonsumsi 1 byte. Jika skrip harus dijalankan dari file biayanya 3 untuk ruang dan ia menandai sendiri. Ada postingan meta yang akan saya coba dan temukan tetapi saya sedang di ponsel sekarang.
Dom Hastings


0

Bash 46 byte

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

Penggunaan: Masukkan jumlah karakter untuk dibatasi, tekan enter dan masukkan string. Ctrl+ Duntuk keluar sed(mengirim 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);}

Alternatif inline for-loop alternatif sebelumnya untuk String concatenation (yang 1 byte lebih banyak dari String s="";for(int i=-1;++i<j;)s+="$1";sayangnya):

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

Kasus yang tidak disatukan & uji:

Coba di sini.

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

Keluaran:

aabbccCCcc
abc

aaaabccccCCCC@
@@@@@bbbbbcccddeegffsassss

0

Javascript (menggunakan perpustakaan eksternal) (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

Tautan ke lib: https://github.com/mvegh1/Enumerable

Penjelasan kode: Muat string ke pustaka, yang secara internal mem-parsing sebagai char array. Menerapkan akumulator pada urutan, meneruskan objek kustom sebagai nilai seed. Properti a adalah elemen saat ini, b adalah string terakumulasi, dan c adalah jumlah berurutan dari elemen saat ini. Akumulator memeriksa apakah nilai iterasi saat ini, n, sama dengan nilai elemen terakhir, ca Jika tidak, kami mereset hitungan ke 1 dan mengatur elemen saat ini. Jika jumlah elemen saat ini kurang dari atau sama dengan panjang yang diinginkan, kami mengakumulasikannya ke string kembali. Akhirnya, kita mengembalikan properti b, string terakumulasi. Bukan kode golf, tapi senang saya mendapat solusi yang berfungsi ...

masukkan deskripsi gambar di sini


0

J, 31 30 byte

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

Mengelompokkan string input ke dalam run (substring) karakter yang identik, dan mengambil minimum dari panjang run itu dan panjang maks yang dimasukkan untuk memotong string. Kemudian salin karakter pertama dari setiap proses yang berulang kali.

Pemakaian

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

   4 f 'aaaaaaabccccccccCCCCCC@'
aaaabccccCCCC@

Penjelasan

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

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

Meminta n dan mengambil string input sebagai argumen.

(fungsi tacit ...
    ratakan
    ⊢↑¨⍨setiap elemen argumen (yaitu setiap partisi) terpotong ke
    ⎕⌊⍴¨minimum input numerik dan panjang saat ini
)[akhir fungsi tacit] diterapkan
⊢⊂⍨pada input yang dipartisi pada ᴛʀᴜᴇ s dari
1, epend yang ditambahkan ke ( karakter pertama tidak sama dengan pendahulunya yang tidak ada)
2≠/⊢pasangan-bijaksana tidak-sama dari karakter dalam input



-1

TCC, 7 5 byte

$~(;)

Input adalah string dan angka, dipisahkan oleh spasi.

Cobalah online!

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

1
Revisi jawaban Anda tidak berfungsi dengan tcc.luafile dengan stempel waktu 16-07-25 16:57 UTC, yang tidak memiliki kemampuan untuk membaca beberapa input sekaligus. Jika jawaban Anda memerlukan versi bahasa yang mengunggah tantangan, Anda harus menandainya sebagai tidak bersaing di header. Saya akan menghapus downvote saya ketika Anda melakukannya.
Dennis
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.