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


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.


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.


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


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"

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

„@@@@@ 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.


2

Python 2, 56 bajtów

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

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


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@"

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 .


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@

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


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

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


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

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



-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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.