Obcinaj kolejne znaki do n długości

14

Wyzwanie

Biorąc pod uwagę ciąg wejściowy i liczbę całkowitą n - obcina wszelkie serie kolejnych znaków do maksymalnej długości n . Znaki mogą być dowolne, w tym znaki specjalne. Funkcja powinna rozróżniać małe i wielkie litery, a n może wynosić od 0 do nieskończoności.

Przykładowe wejścia / wyjścia:

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

Punktacja

Wynik jest oparty na liczbie użytych bajtów. A zatem

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

będzie 104 punktów.

Miłej gry w golfa!

Edycja: usunęłem ograniczenia językowe, ale nadal chciałbym zobaczyć odpowiedzi w javascript

TestSubject06
źródło
1
Dlaczego nie pozwolić ES6?
TuxCrafting
7
Polecam utratę wymagań językowych. Javascript jest jednym z najpopularniejszych języków tutaj. Odpowiedź na to pytanie prawdopodobnie zachęci ludzi do gry w golfa lub spróbuje pokonać cię innym podejściem. Ponadto, jeśli uzyskasz wystarczającą reputację, możesz dodać nagrodę do pytania, mając na uwadze konkretny język. Jeśli to ci nie odpowiada, możesz zmienić to pytanie w pytanie z poradami i spróbować poprosić o konkretną pomoc w golfa.
FryAmTheEggman
W rezultacie usunięto ograniczenia językowe i zmieniono reguły punktacji. Nadal chciałbym zobaczyć wpisy javascript, ale myślę, że mogę żyć z językami golfowymi o 4-5 znakach.
TestSubject06
Witamy w Programowaniu Puzzle i Code Golf! Wyzwania związane z golfem kodowane są domyślnie według długości w bajtach . Natomiast w skrzydle o długości znaków jest możliwe, jesteś zobowiązany, aby uzyskać kilka odpowiedzi jak ten jeden .
Dennis
O Boże. Zmieniono na ocenę bajtów.
TestSubject06

Odpowiedzi:

6

Python 2, 52 bajty

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

Zapisane jako program (54 bajty):

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

Iteruje przez ciąg wejściowy s, dołączając każdy znak do ciągu wyjściowego, rchyba że ostatnie nznaki rto ten znak.

Myślałem, że to się nie powiedzie, n==0ponieważ r[-0:]nie ma ostatnich 0 znaków (pusty ciąg), ale cały ciąg. Ale działa, ponieważ ciąg znaków pozostaje pusty, więc dopasowuje ciąg znaków 0-znakowych.

Rekursywny lambdadał 56 z powodu powtórzenia

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

Alternatywna strategia polegająca na prowadzeniu licznika ipowtórzeń ostatniej postaci również okazała się dłuższa niż tylko sprawdzenie ostatniejn postaci.

xnor
źródło
6

DO, 81 78

Modyfikuje przychodzący ciąg.

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 testowy

Wymaga dwóch parametrów, pierwszy to łańcuch do obcięcia, drugi to limit długości.

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

Wyjaśnienie:

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.

Działa to, ponieważ wskaźnik źródłowy zawsze będzie równy lub większy niż wskaźnik docelowy, więc możemy pisać nad ciągiem podczas jego analizy.

owacoder
źródło
To niesamowite, możesz to wyjaśnić?
TestSubject06
@ TestSubject06 - Dodano wyjaśnienie.
owacoder,
Czy to działa z przypadkiem n = 0? Nie mogę tego zmusić do kompilacji do przetestowania tutaj.
TestSubject06
Tak. Dodałem program testowy, abyś mógł kompilować.
owacoder
Wspaniale, nie mogłem znaleźć żadnych przeciwnych przykładów. Krótko i to działa!
TestSubject06
5

Haskell, 36 bajtów

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

Wersja bez punktów \n s -> concatMap (take n) (group s).

Lynn
źródło
4

JavaScript ES6, 60 54 55 43 bajtów

-12 bajtów dzięki @ TestSubject06 i @Downgoat

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

Przykładowe przebiegi:

f("aaaaaaabbbccCCCcc"      , 2) -> "aabbccCCcc" 
f("aaabbbc"                , 1) -> "abc"
f("abcdefg"                , 0) -> ""
f("aaaaaaabccccccccCCCCCC@", 4) -> "aaaabccccCCCC@"
f("a"                      , 1) -> "a"
Dendrobium
źródło
f („a”, 1) -> ””
TestSubject06
1
Ponieważ twój RegExp nie jest dynamicznie kontrolowany w żaden sposób, możesz zapisać niektóre bajty za pomocą RegExp („(.) \\ 1 *”, „g”) -> /(.)\1*/g
TestSubject06
1
Konwertuj RegExp("(.)\\1*","g")na/(.)\1*/g
Downgoat
1
Nie widzę, aby zmniejszało się to w JS, chyba że przyjdziemy na to z zupełnie innej perspektywy. Dobra robota @Dendrobium!
TestSubject06
1
Ogolić jeden bajt, zmieniając (s,n)na s=>n, a użycie staje sięf("aaaaaaabbbccCCCcc")(2)
Patrick Roberts
3

MATL, 9 bajtów

Y'i2$X<Y"

Wypróbuj online

Wyjaśnienie

        % 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
Suever
źródło
„@@@@@ bbbbbcccddeegffsassss” 3 zwrócił „@@@ bbbcccddeegffsass”, w którym brakuje ostatnich „s”
TestSubject06
@ TestSubject06 Dziękujemy za zwrócenie na to uwagi.
Suever,
2

CJam, 12 bajtów

{e`\af.e<e~}

Wypróbuj online!

Wyjaśnienie

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.
Martin Ender
źródło
2

Python 2, 56 bajtów

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

gs2, 6 bajtów

Zakodowane w CP437 :

╠c╨<ΘΣ

Jest to anonimowa funkcja (blok), która oczekuje liczby na szczycie stosu i ciągu poniżej.

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

Wypróbuj online. (Kod jest tutaj lines, dump, read number, [the answer], run-block.)

Lynn
źródło
1

Perl 6 ,  38  36 bajtów

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

Wyjaśnienie:

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

Test:

#! /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@"
Brad Gilbert b2gills
źródło
0

JavaScript ES5, 73

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

Ponownie używa wyrażenia regularnego Lynn z jej odpowiedzi w języku Python .

FryAmTheEggman
źródło
Twój kod nie obsługuje przypadku, w którym n wynosi zero, po prostu zwraca cały oryginalny ciąg.
TestSubject06
Tak, w Firefoksie możesz upuścić nawiasy klamrowe i instrukcję return , chociaż ta składnia jest (niestety) przestarzała i zostanie usunięta (faktycznie nie było jej kilka wersji z powrotem, nie zdawałem sobie sprawy, że ją przywróciły).
Dendrobium
Możesz także upuścić newsłowo kluczowe dla -4 bajtów.
Dendrobium
@ TestSubject06 Dzięki, zredagowałem swoją odpowiedź i uważam, że teraz przechodzi ona przez przypadki testowe.
FryAmTheEggman
0

Perl 5, 50 bajtów

Kod 46 bajtów + 3 dla -ii 1 dla-p

Pobiera numer do obcięcia za pośrednictwem -i.

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

Stosowanie

perl -i4 -pe 's!(.)\1+!$&=~s/(.{$^I}).+/$1/r!ge' <<< 'aaaaaaabccccccccCCCCCC@'
aaaabccccCCCC@
Dom Hastings
źródło
Dlaczego jest -ptylko jeden bajt?
someonewithpc
@someonewithpc, gdy można go połączyć z -etymi opcjami, zajmuje tylko 1 bajt. Jeśli skrypt musi zostać uruchomiony z pliku, kosztuje on 3 za miejsce i sam się oflaguje. Próbuję znaleźć meta post, ale jestem teraz na telefonie komórkowym.
Dom Hastings,
0

Bash 46 bajtów

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

Użycie: Wprowadź liczbę znaków do ograniczenia, naciśnij enter i wprowadź ciąg. Ctrl+, Daby wyjść sed(wysłać EOF).

Someonewppc
źródło
0

Java 7, 107 106 bajtów

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

Poprzednia alternatywna pętla for-line dla konkatenacji ciągów (która jest o 1 bajt większa niż String s="";for(int i=-1;++i<j;)s+="$1";niestety):

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

Przypadki bez golfa i testy:

Wypróbuj tutaj.

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

Wynik:

aabbccCCcc
abc

aaaabccccCCCC@
@@@@@bbbbbcccddeegffsassss
Kevin Cruijssen
źródło
0

JavaScript (przy użyciu zewnętrznej biblioteki) (115 bajtów)

(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

Link do lib: https://github.com/mvegh1/Enumerable

Objaśnienie kodu: Załaduj ciąg do biblioteki, która wewnętrznie analizuje jako tablicę znaków. Zastosuj akumulator w sekwencji, przekazując niestandardowy obiekt jako wartość początkową. Właściwość a to bieżący element, b to ciąg znaków zakumulowany, a c to sekwencyjna liczba bieżącego elementu. Akumulator sprawdza, czy bieżąca wartość iteracji, n, jest równa ostatniej wartości elementu, ca Jeśli nie, resetujemy licznik do 1 i ustawiamy bieżący element. Jeśli liczba bieżącego elementu jest mniejsza lub równa pożądanej długości, kumulujemy ją do ciągu zwracanego. Na koniec zwracamy właściwość b, skumulowany ciąg. Nie jest to najbardziej golfowy kod, ale cieszę się, że mam rozwiązanie, które działa ...

enter image description here

applejacks01
źródło
0

J, 31 30 bajtów

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

Grupuje ciąg wejściowy w przebiegi (podłańcuchy) o identycznych znakach i przyjmuje minimalną długość tego przebiegu i maksymalną długość, która została wprowadzona w celu obcięcia łańcucha. Następnie tyle razy kopiuje pierwszy znak każdego uruchomienia.

Stosowanie

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

   4 f 'aaaaaaabccccccccCCCCCC@'
aaaabccccCCCC@

Wyjaśnienie

((<.#@>)#{.@>@])]<;.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
mile
źródło
0

Dyalog APL , 22 20 bajtów

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

Monituje o n i przyjmuje ciąg wejściowy jako argument.

(Funkcja milcząca ...
    spłaszczenia
    ⊢↑¨⍨każdy element argumentu (np każdej partycji) z dokładnością do
    ⎕⌊⍴¨minimum przez numeryczne i aktualnej długości
)[końcowego funkcji milczące] stosuje się do
⊢⊂⍨wejścia podzielono u ᴛʀᴜᴇ s
1, ᴛʀᴜᴇ poprzedzał (The pierwszy znak nie jest równy nieistniejącemu poprzednikowi)
2≠/⊢pary nierównoznaczny znaków na wejściu

Adám
źródło
0

Rubinowy, 32 bajty

->s,n{s.gsub(/(.)\1*/){$&[0,n]}}
Jordania
źródło
-1

TCC, 7 5 bajtów

$~(;)

Dane wejściowe to ciąg i liczba oddzielone spacją.

Wypróbuj online!

       | Printing is implicit
$~     | Limit occurence
  (;   | First part of input
    )  | Second part of input
brianush1
źródło
1
Żadna wersja odpowiedzi nie działała z tcc.luaplikiem ze znacznikiem czasu 16-07-25 16:57 UTC, który nie był w stanie odczytać wielu danych naraz. Jeśli twoja odpowiedź wymaga wersji językowej, która opublikowała wyzwanie, musisz oznaczyć ją w nagłówku jako niekonkurującą . Kiedy to zrobię, usunę moją opinię.
Dennis