Aufeinanderfolgende Zeichen werden auf n Länge gekürzt

14

Die Herausforderung

Wenn Sie eine Eingabezeichenfolge und eine Ganzzahl n angeben, kürzen Sie alle aufeinander folgenden Zeichenfolgen auf ein Maximum von n Zeichen . Die Zeichen können alles sein, auch Sonderzeichen. Die Funktion sollte zwischen Groß- und Kleinschreibung unterscheiden und n kann von 0 bis unendlich reichen.

Beispiel Ein- / Ausgänge:

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

Wertung

Die Bewertung basiert auf der Anzahl der verwendeten Bytes. Somit

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

wäre 104 Punkte.

Viel Spaß beim Golfen!

Bearbeiten: Spracheinschränkung entfernt, aber ich würde immer noch gerne Javascript-Antworten sehen

Testobjekt06
quelle
1
Warum nicht ES6 zulassen?
TuxCrafting
7
Ich würde empfehlen, die Sprachanforderungen zu verlieren. Javascript ist hier eine der gebräuchlichsten Sprachen. Selbstantworten mit dem, was Sie haben, würden wahrscheinlich Leute einladen, Ihnen beim Golfen zu helfen oder Sie mit einem anderen Ansatz zu schlagen. Wenn Sie genug Reputation haben, können Sie der Frage eine Prämie hinzufügen, die einer bestimmten Sprache entspricht. Wenn Ihnen das nicht zusagt, können Sie diese Frage in eine Frage mit Tipps umwandeln und versuchen, eine spezifische Golfhilfe anzufordern.
FryAmTheEggman
Spracheinschränkungen wurden entfernt und die Bewertungsregeln geändert. Ich würde immer noch gerne Javascript-Einträge sehen, aber ich glaube, ich kann mit einigen 4-5-stelligen Golfsprachen leben.
TestSubject06
Willkommen bei Programming Puzzles & Code Golf! Code Golf Challenges werden standardmäßig nach Länge in Bytes gewertet . Während es möglich ist, nach Länge in Zeichen zu punkten , müssen Sie einige Antworten wie diese erhalten .
Dennis
Oh Gott. Änderung der Byte-Bewertung.
TestSubject06

Antworten:

6

Python 2, 52 Bytes

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

Als Programm geschrieben (54 Bytes):

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

Durchläuft die Eingabezeichenfolge und hängt sjedes Zeichen an die Ausgabezeichenfolge an, es rsei denn, die letzten nZeichen von rsind dieses Zeichen.

Ich dachte, dies würde scheitern, n==0weil r[-0:]nicht die letzten 0 Zeichen (leere Zeichenfolge), sondern die gesamte Zeichenfolge. Dies funktioniert jedoch, da die Zeichenfolge leer bleibt und daher weiterhin mit der Zeichenfolge mit 0 Zeichen übereinstimmt.

Ein rekursiver lambdagab 56 wegen der Wiederholung

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

Eine alternative Strategie, um einen Zähler ifür die Wiederholungen des letzten Zeichens zu erstellen, hat sich auch als länger herausgestellt, als nur die letzten nZeichen direkt zu überprüfen .

xnor
quelle
6

C 81, 78

Ändert die eingehende Zeichenfolge.

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

Testprogramm

Erfordert zwei Parameter, der erste ist die Zeichenfolge zum Abschneiden, der zweite ist die Längenbeschränkung.

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

Erläuterung:

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.

Dies funktioniert, weil der Quellzeiger immer gleich oder größer als der Zielzeiger ist, sodass wir den String beim Parsen überschreiben können.

owacoder
quelle
Das ist erstaunlich, kannst du es erklären?
TestSubject06
@ TestSubject06 - Erklärung hinzugefügt.
Owacoder
Funktioniert dies mit dem Fall n = 0? Ich kann es nicht kompilieren, um es hier zu testen.
TestSubject06
Ja tut es. Ich habe ein Testprogramm hinzugefügt, damit Sie kompilieren können.
Owacoder
Genial, konnte keine Gegenbeispiele finden. Kurz und es funktioniert!
TestSubject06
5

Haskell, 36 Bytes

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

Punktefreie Version von \n s -> concatMap (take n) (group s).

Lynn
quelle
4

Javascript ES6, 60 54 55 43 Bytes

-12 Bytes dank @ TestSubject06 und @Downgoat

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

Beispiel läuft:

f("aaaaaaabbbccCCCcc"      , 2) -> "aabbccCCcc" 
f("aaabbbc"                , 1) -> "abc"
f("abcdefg"                , 0) -> ""
f("aaaaaaabccccccccCCCCCC@", 4) -> "aaaabccccCCCC@"
f("a"                      , 1) -> "a"
Dendrobium
quelle
f ("a", 1) -> ""
TestSubject06
1
Da Ihr RegExp in keiner Weise dynamisch gesteuert wird, können Sie mit RegExp ("(.) \\ 1 *", "g") -> /(.)\1*/g
TestSubject06
1
Konvertieren RegExp("(.)\\1*","g")zu/(.)\1*/g
Downgoat
1
Ich sehe, dass dies in JS nicht kleiner wird, wenn wir es nicht aus einem ganz anderen Blickwinkel betrachten. Gute Arbeit @ Dendrobium!
TestSubject06
1
Shave ein Byte durch Änderung (s,n)zu s=>nund die Nutzung wirdf("aaaaaaabbbccCCCcc")(2)
Patrick Robert
3

MATL, 9 Bytes

Y'i2$X<Y"

Probieren Sie es online

Erläuterung

        % 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
quelle
'@@@@@ bbbbbcccddeegffsassss' 3 hat '@@@ bbbcccddeegffsass' zurückgegeben, bei dem das Finale fehlt 's'
TestSubject06
@ TestSubject06 Danke für den Hinweis.
Suever
2

CJam, 12 Bytes

{e`\af.e<e~}

Probieren Sie es online!

Erläuterung

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
quelle
2

Python 2, 56 Bytes

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

gs2, 6 bytes

In CP437 codiert :

╠c╨<ΘΣ

Dies ist eine anonyme Funktion (Block), die eine Zahl oben auf dem Stapel und eine Zeichenfolge darunter erwartet.

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

Probieren Sie es online aus. (Der Code hier ist lines, dump, read number, [the answer], run-block.)

Lynn
quelle
1

Perl 6 ,  38  36 Bytes

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

Erläuterung:

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

Prüfung:

#! /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
quelle
0

Javascript ES5, 73

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

Verwendet Lynns Regex aus ihrer Python-Antwort erneut .

FryAmTheEggman
quelle
Ihr Code behandelt nicht den Fall, in dem n Null ist, sondern gibt nur die gesamte ursprüngliche Zeichenfolge zurück.
TestSubject06
Ja, in Firefox können Sie die geschweiften Klammern und die return-Anweisung löschen , obwohl diese Syntax (leider) veraltet ist und entfernt wird (es fehlten tatsächlich ein paar Versionen, aber sie haben nicht gemerkt, dass sie zurückgebracht wurden).
Dendrobium
Sie können das newSchlüsselwort auch für -4 Bytes löschen.
Dendrobium
@ TestSubject06 Danke, ich habe meine Antwort bearbeitet und glaube, dass sie jetzt die Testfälle besteht.
FryAmTheEggman
0

Perl 5, 50 Bytes

46 Byte Code + 3 für -iund 1 für-p

Nimmt die Nummer, auf die über gekürzt werden soll -i.

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

Verwendung

perl -i4 -pe 's!(.)\1+!$&=~s/(.{$^I}).+/$1/r!ge' <<< 'aaaaaaabccccccccCCCCCC@'
aaaabccccCCCC@
Dom Hastings
quelle
Warum ist -pnur ein Byte?
Someonewithpc
@someonewithpc, wenn es mit -ediesen Optionen kombiniert werden kann, verbrauchen nur 1 Byte. Wenn das Skript aus einer Datei ausgeführt werden muss, kostet es 3 für den Speicherplatz und er kennzeichnet sich selbst. Ich werde versuchen, einen Meta-Post zu finden, aber ich bin gerade auf dem Handy.
Dom Hastings
0

Bash 46 Bytes

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

Verwendung: Geben Sie die Anzahl der Zeichen ein, die begrenzt werden sollen, drücken Sie die Eingabetaste und geben Sie die Zeichenfolge ein. Ctrl+ Dzum Beenden sed(EOF senden).

jemandemmitpc
quelle
0

Java 7, 107 106 Bytes

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

Vorherige alternative Inline-for-Schleife für die String-Verkettung (das ist 1 Byte mehr als String s="";for(int i=-1;++i<j;)s+="$1";unglücklicherweise):

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

Ungolfed & Testfälle:

Probieren Sie es hier aus.

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

Ausgabe:

aabbccCCcc
abc

aaaabccccCCCC@
@@@@@bbbbbcccddeegffsassss
Kevin Cruijssen
quelle
0

Javascript (mit externer Bibliothek) (115 Bytes)

(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 zur Bibliothek: https://github.com/mvegh1/Enumerable

Codeerklärung: Laden Sie den String in die Bibliothek, die intern als char-Array analysiert. Wenden Sie einen Akkumulator auf die Sequenz an und übergeben Sie ein benutzerdefiniertes Objekt als Startwert. Eigenschaft a ist das aktuelle Element, b ist die akkumulierte Zeichenfolge und c ist die fortlaufende Anzahl des aktuellen Elements. Der Akkumulator prüft, ob der aktuelle Iterationswert n gleich dem letzten Elementwert ist. Wenn nicht, setzen wir den Zähler auf 1 zurück und setzen das aktuelle Element. Wenn die Anzahl des aktuellen Elements kleiner oder gleich der gewünschten Länge ist, addieren wir sie zur Rückgabezeichenfolge. Schließlich geben wir die Eigenschaft b zurück, die akkumulierte Zeichenfolge. Nicht der Golf-Code, aber glücklich, dass ich eine Lösung gefunden habe, die funktioniert ...

Bildbeschreibung hier eingeben

applejacks01
quelle
0

J, 31-30 Bytes

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

Gruppiert die Eingabezeichenfolge in Läufe (Teilzeichenfolgen) mit identischen Zeichen und verwendet die minimale Länge dieser Läufe und die maximale Länge, die zum Abschneiden der Zeichenfolge eingegeben wurde. Kopiert dann das erste Zeichen jedes Laufs so oft.

Verwendung

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

   4 f 'aaaaaaabccccccccCCCCCC@'
aaaabccccCCCC@

Erläuterung

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

Dyalog APL , 22 20 Bytes

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

Eingabeaufforderungen für n Eingabe von und verwendet die Eingabezeichenfolge als Argument.

(Die implizite Funktion ...
    Reduziert
    ⊢↑¨⍨jedes Element des Arguments (dh jede Partition) auf
    ⎕⌊⍴¨das Minimum der numerischen Eingabe und die aktuelle Länge
)[Ende der impliziten Funktion], die auf
⊢⊂⍨die Eingabe angewendet wird, die an den vorangestellten ᴛʀᴜᴇ s von
1, ᴛʀᴜᴇ partitioniert ist erstes Zeichen ist nicht gleich dem nicht existierenden Vorgänger
2≠/⊢ das paarweise ungleiche Zeichen in der Eingabe)

Adam
quelle
0

Ruby, 32 Bytes

->s,n{s.gsub(/(.)\1*/){$&[0,n]}}
Jordan
quelle
-1

TCC, 7 5 Bytes

$~(;)

Die Eingabe ist eine durch Leerzeichen getrennte Zeichenfolge und Zahl.

Probieren Sie es online!

       | Printing is implicit
$~     | Limit occurence
  (;   | First part of input
    )  | Second part of input
brianush1
quelle
1
Weder die Überarbeitung Ihrer Antwort funktionierte mit der tcc.luaDatei mit dem Zeitstempel 16-07-25 16:57 UTC, bei der nicht mehrere Eingaben gleichzeitig gelesen werden konnten. Wenn für Ihre Antwort eine Version der Sprache erforderlich ist, in der die Herausforderung nachgestellt ist, müssen Sie sie im Header als nicht konkurrierend kennzeichnen. Ich werde meine Ablehnung entfernen, wenn Sie dies tun.
Dennis