Fülle die Lücken aus

14

Eingang

Eine nicht negative Ganzzahl nund eine nicht leere Zeichenfolge, sdie nur alphanumerische Zeichen und Unterstriche enthält _. Das erste Zeichen von sist nicht _. Die Unterstriche von swerden als Leerzeichen interpretiert, die mit anderen Zeichen gefüllt werden können.

Wir definieren eine unendliche Folge von "unendlichen Strings" wie folgt. Die Saite wird nur unendlich oft wiederholt. Für alle wird die Zeichenfolge erhalten, indem die Leerzeichen mit den Zeichen von gefüllt werden , sodass das erste von durch , das zweite von durch usw. ersetzt wird. Da der erste Buchstabe von nicht ist , wird schließlich jedes Leerzeichen gefüllt, und wir bezeichnen durch die unendliche Zeichenfolge, in der jedes durch seinen endgültigen Wert ersetzt wurde.s1 = s s s...sk > 1sk+1sks1_sks1[0]s1[1]s_s_

Ausgabe

Die ersten nZeichen als Zeichenfolge.s

Beispiel

Betrachten Sie die Eingänge n = 30und s = ab_c_. Wir haben

s1 = ab_c_ab_c_ab_c_ab_c_ab_c_ab_c_ab_c_...

Wir ersetzen die Lücken vons1s1

s2 = abacbab_ccab_caabbc_abcc_abacbab_cc...

Wir ersetzen wieder die Leerzeichen, was zur Folge hats1

s3 = abacbabaccabbcaabbc_abcccabacbab_cc...

Eine weitere Substitution:

s4 = abacbabaccabbcaabbcaabcccabacbabbcc...

Daraus können wir bereits die ersten 30 Zeichen ableiten , von denen sinds

abacbabaccabbcaabbcaabcccabacb

Dies ist die richtige Ausgabe.

Regeln

Sie können ein vollständiges Programm oder eine Funktion schreiben. Die niedrigste Byteanzahl gewinnt, und Standardlücken sind nicht zulässig. Absturz bei falscher Eingabe ist akzeptabel.

Testfälle

0  "ab__"    -> ""
1  "ab__"    -> "a"
3  "ab__"    -> "aba"
20 "ab"      -> "abababababababababab"
20 "ab__"    -> "abababababababababab"
20 "ab_"     -> "abaabbabaabaabbabbab"
30 "ab_c_"   -> "abacbabaccabbcaabbcaabcccabacb"
50 "ab_a_cc" -> "abaabccabaaaccabbacccabcaaccabbaaccabaaaccabcaccca"
50 "abc____" -> "abcabcaabcbcaaabcbcbcabcaaababccbcbabccabcabcaaaba"
Zgarb
quelle
Können wir Eingaben in umgekehrter Reihenfolge vornehmen (in Sprachen, in denen die Reihenfolge wichtig ist)?
Martin Ender
@ MartinBüttner Klar, das werde ich zulassen.
Zgarb

Antworten:

4

Pyth, 17

<ussC,cG\_GUQ*zQQ

Die Eingabe sollte mit der Zeichenfolge in der ersten Zeile und der Länge in der zweiten Zeile in STDIN erfolgen. Beispielsweise:

abc____
50

Probieren Sie es hier aus.

Erläuterung:

                             Implicit:
                             z = input()              z is the string.
                             Q = eval(input())        Q is the length.

<               Q            First Q characters of
 u         UQ*zQ             Reduce, with an initial value of z repeated Q times, 
                             on the list range(len(Q)).
                             Since the reduce function doesn't use the sequence variable H
                             this function amounts to applying the inner code Q times to
                             the initial value, where the working variable is G.
  ss                         Sum from list of tuples of strings, to tuple of strings,
                             to string.
    C,                       Zip together
      cG\_                   G split on underscores
          G                  with G.
                             This inserts a character of G between every underscore
                             separated group of G, which amounts to replacing the
                             underscores with characters of G, after summation.
isaacg
quelle
7

APL 29 28

{a⊣(b/a)←a↑⍨+/b←'_'=a←⍺⍴⍵}⍣≡

es wird wie folgt verwendet:

fun←{a⊣(b/a)←a↑⍨+/b←'_'=a←⍺⍴⍵}⍣≡
20 fun 'ab_c_'
abacbabaccabbcaabbca

Erläuterung:

a←⍺⍴⍵           makes vector long as left argument using repeated chars in right argument
a↑⍨+/b←'_'=a   takes a string from the beginning of string a (a↑⍨), long as the number of _'s in a (+/b←'_'=a)
(b/a)←          puts those chars in place of the _'s in the original vector
a⊣             and returns a
{}⍣≡            repeats function ( {} ) until results doesn't change anymore

Tryapl.org

Moris Zucca
quelle
⍣≡ist eine gute Idee. Vielleicht sollte ich versuchen, dies auf J zu portieren ...
FUZxxl
7

CJam, 26 24 20 Bytes

4 Bytes gespart dank Peter.

l~:I*{_'_/[\]zsI<}I*

Teste es hier. Nimmt die Zeichenfolge an erster und nzweiter Stelle von STDIN.

Sie können alle Testfälle ausführen, indem Sie sie unverändert in die Eingabe -> outputeinfügen (einschließlich der, wenn Sie möchten) und das folgende Testkabel verwenden (wodurch die Reihenfolge für den Code umgekehrt wird):

qN/{"->"/0=S/W%S*

~:I*{_'_/[\]zsI<}I*

]oNo}/

Erläuterung

l~:I*{_'_/[\]zsI<}I*
l~                       "Read the input and evaluate.";
  :I                     "Store n in I for future use.";
    *                    "Repeat s n times to ensure it's long enough for the output.";
     {           }I*     "Repeat this block n times. This will always be enough passes.";
      _                  "Duplicate the string.";
       '_/               "Split the string on underscores.";
          [\]            "Swap with the other copy, putting both in an array.";
             z           "Zip the two arrays together, interleaving substrings from the split
                          copy with characters from the unsplit copy. Extraneous
                          characters from the unsplit copy just go at the end and
                          can be ignored.";
              s          "Convert the result into a string, flattening the array in the
                          process. This basically joins the two interleaved strings together.";
               I<        "Truncate to n characters.";

Das Ergebnis wird am Ende des Programms automatisch ausgedruckt.

Ein Hinweis zu [\]:[ Erinnert sich im Prinzip an die aktuelle Größe des Stapels und ]sammelt alles bis zur letzten gespeicherten Größe in einem Array. Wenn die Größe des Arrays jedoch die zwischenzeitlich gespeicherte Größe unterschreitet, wird der Start des Arrays entsprechend angepasst. Jetzt könnten Sie denken, dass das Vertauschen der beiden obersten Array-Elemente die Array-Größe überhaupt nicht beeinflusst, aber \tatsächlich zwei Werte aufnimmt und sie dann in umgekehrter Reihenfolge verschiebt. Dies ist es, was den Start des Arrays um zwei nach unten drückt. Dies [\]ist der kürzeste Weg, um die beiden obersten Stapelelemente in ein Array einzubinden. Manchmal ist es ziemlich ärgerlich, sie in umgekehrter Reihenfolge zu sammeln, aber in diesem Fall ist es genau das, was ich brauche.

Martin Ender
quelle
Ich denke , man könnte ersetzen _'_#) gmit I*. Funktioniert für mich in GolfScript.
Peter Taylor
@ PeterTaylor oh, sehr gute Idee, danke!
Martin Ender
6

Python 3, 110 Bytes

n=int(input())
*b,=input()*n
a=b[:n]
while"_"in a:b,a=b[:],[x*(x!="_")or b.pop(0)for x in a]
print("".join(a))

Benötigt ein bisschen mehr Golf, aber hier ist ein bisschen Wahnsinn. Liest ndann sSTDIN ein.

Der spaßige Teil besteht darin, in der Zuweisung der Schleife, die wir kopieren b, zu beginnen, bwährend eines Listenverständnisses zu blättern . Wenn die Aufgabe umgekehrt wäre, würde es nicht funktionieren!

Sp3000
quelle
4

k, 30

{{@[x;i;:;(#i:&"_"=x)#x]}/x#y}
tmartin
quelle
4

Java - 162 174

Es kommt nicht jeden Tag vor, dass ich beim Golfen in Java eine do / while-Schleife benutze: D

Dies iteriert nur und füllt Leerzeichen aus, wenn sie kommen. Es geht einfach so lange weiter, bis nichts mehr _im Ergebnis ist.

char[]a(int n,char[]s){char[]o=new char[n];if(n>0)do for(int i=0,j=0;i<n;i++)if(o[i]==95|o[i]<1)o[i]=s[j++%s.length];while(new String(o).contains("_"));return o;}

Mit Zeilenumbrüchen:

char[]a(int n,char[]s){
    char[]o=new char[n];
    if(n>0)
        do
            for(int i=0,j=0;i<n;i++)
                if(o[i]==95|o[i]<1)
                    o[i]=s[j++%s.length];
        while(new String(o).contains("_"));
    return o;
}
Geobits
quelle
Ich wollte das nicht beantworten, aber die andere Java-Antwort war zu lang, um sie stehen zu lassen;)
Geobits
3

Java 8, 238

(n,s)->{int i=0,j=0;for(s=String.join("",java.util.Collections.nCopies(n,new String(s))).toCharArray();j<1;){for(i=0;i<n;i++){for(;s[++j]!=95&j<n;);if(j<n)s[j]=s[i];}for(j=1,i=0;i<n;)j=s[++i]==95?0:1;}return java.util.Arrays.copyOf(s,n);}

Weniger golfen:

(Integer n, char[] s) -> {
    int i = 0, j = 0;
    for (s = String.join("", java.util.Collections.nCopies(n, new String(s))).toCharArray(); j < 1;) {
        for (i = 0; i < n; i++) {
            for (; s[j] != 95 & j < n; j++);
            if (j < n) {
                s[j] = s[i];
            }
        }
        for (j = 1, i = 0; i < n;) {
            j = s[++i] == 95 ? 0 : 1;
        }
    }
    return java.util.Arrays.copyOf(s, n);
}
Ypnypn
quelle
3

Rubin, 60

->n,s{eval"r=%1$p.chars;s.gsub!(?_){r.next};"*n%s*=n;s[0,n]}

Verkettet ssich selbst nmal und generiert dann nKopien des Codes, der die Unterstriche ersetzt s, wertet diese Kopien aus und gibt die ersten nZeichen des Ergebnisses zurück. Da in jeder Schleife mindestens ein Unterstrich entfernt wird, erhalten wir garantiert nunterstrichfreie Zeichen.

Histokrat
quelle
Was ist die richtige Syntax, um dies auszuführen? Als ich es nennen fund läuft puts f[10,"ab_"], bekomme ich folgende Fehlermeldung: in 'eval': undefined method 'next' for #<Array:.... Es scheint jedoch zu funktionieren, wenn die Zeichenfolge keine Unterstriche enthält.
Théophile
Oh, interessant, es sieht so aus, als hätte sich das Verhalten String#charszwischen Ruby 1.9.3 und Ruby 2.0 geändert. In Ruby 1 wird ein Enumerator zurückgegeben, wenn kein Block vorhanden ist, in Ruby 2 ein Array. Sie kann versionsunempfindlich gemacht werden, indem charsauf each_char4 weitere Nettobytes Code umgestellt wird.
Histokrat
3

Python 2, 75

n,s=input()
S='';c=0
for x in s*n:b=x=='_';S+=S[c:c+b]or x;c+=b
print S[:n]

Das erwartet Eingaben wie (30,"ab_c_").

In Python erlauben Strings keine Zuweisung. Das Ersetzen der Leerzeichen durch das gewünschte Zeichen ist daher schwierig. Man kann dies umgehen, indem man in eine Liste konvertiert und zurück, aber ich fand es kürzer, nur die Ausgabezeichenfolge von Grund auf neu zu generieren und die gewünschten Zeichen nacheinander hinzuzufügen.

Die Ausgabe, die erstellt wird S, beginnt leer. Wir durchlaufen die smehrfach kopierten Zeichen der Eingabe , um einen Kreis zu simulieren. Wir prüfen über den Booleschen Wert, ob es sich um ein Leerzeichen handelt b. Wir prüfen die Gleichheit x=='_'und nicht den Vergleich, da der Unterstrich zwischen Groß- und Kleinbuchstaben liegt.

Wenn das Zeichen kein Leerzeichen ist, fügen wir es einfach hinzu S. Wenn es leer ist, fügen wir den nächsten unbenutzten Buchstaben der bisherigen Ausgabe hinzu S. Wir verfolgen verbrauchte Buchstaben anhand eines Indexzeigers c, der bei 0 beginnt und jedes Mal inkrementiert wird, wenn wir auf ein Leerzeichen stoßen.

Am Ende drucken wir die ersten nZeichen der resultierenden Zeichenfolge S.

Wir müssen S[c:c+b]anstelle des kürzeren verwenden, b*S[c]da letzteres einen Fehler außerhalb der Grenzen ausgibt, wenn es Sleer beginnt und c0 ist. Es spielt keine Rolle, da garantiert ist, dass das erste Zeichen von snicht leer ist. Dies S[c]wird also niemals benötigt. aber der Code weiß es nicht. Das Umdrehen des orKurzschlusses könnte das auch lösen, kostet aber mehr Zeichen.


Python 2, 83

Ein Pyth-zu-Python-Port der isaacg-Lösung , der das Ersetzen verwendet splitund zipdurchführt:

n,s=input()
s*=n
exec"s=''.join(a+b for a,b in zip(s.split('_'),s));"*n
print s[:n]

Es stellte sich heraus, dass benannte Methoden in Python überraschenderweise sehr lang sind. Aber es kann vielleicht verbessert werden, indem man zusammen sund s.split('_')in kürzerer Weise riffelt .

xnor
quelle
Nett! Ich hätte nicht gedacht, dass die Rekonstruktion der Saite so viel kürzer sein würde!
Sp3000,
3

Haskell (93) 67

Ich habe seit einiger Zeit keine Haskell mehr geschrieben, daher kann dies wahrscheinlich um ein Vielfaches verkürzt werden. aber es war so gut, dass wir es kürzen und verbessern mussten!

('_':b)&(d:e)=d:b&e;(a:b)&c=a:b&c
f n s=take n$q where q=cycle s&q

Verwendung:

*Main> f 50 "ab_a_cc"
"abaabccabaaaccabbacccabcaaccabbaaccabaaaccabcaccca"
Marinus
quelle
2

Charge - 425

Verliere ich

@echo off&setLocal enableDelayedExpansion&set s=%2
if "%3"=="" (for /l %%a in (1,1,%1)do set o=!o!%s%)else set o=%3
set o=!o:~0,%1!&set l=0
:c
if defined s set/al+=1&set "s=%s:~1%"&goto c
set s=%2&set/ap=%1-1
set y=&set c=0&for /l %%a in (0,1,%p%)do set x=!o:~%%a,1!&if !x!==_ (for %%b in (!c!)do set y=!y!!s:~%%b,1!&set/ac+=1)else (set y=!y!!x!)&if !c!==%l% set c=0
if "!y:_=!"=="!y!" echo !y!&goto :EOF
%0 %1 %2 !y!

Batch hat Einschränkungen - das akzeptiere ich. Beispielsweise; Ich musste eine for-Schleife verwenden, um eine einzelne Variable in einem verwendbaren Format zu erhalten, da die Syntax der Variablenanalyse eingeschränkt war. for %%b in (!c!)do... existiert nur, damit ich verwenden kann%%b!c! die Zeichenfolge bearbeiten anstatt sie zu verwenden!s:~%%b,1! , und haben die Variablen zur richtigen Zeit erweitern.

Es gibt ein paar ziemlich grundlegende Dinge, die ich tun könnte, um weiter Golf zu spielen, aber wahrscheinlich nicht unter 400 Bytes. Ich werde bald einen weiteren Riss haben.

unclemeat
quelle
3
Wenn nicht jemand anderes eine bessere Batch-Antwort veröffentlicht, würde ich das nicht als Verlieren bezeichnen :)
Sp3000
@ Sp3000 Wenn nur jemand würde.
Unclemeat
2

ECMAScript 6, 78

f=(s,n,i=0)=>[...s.repeat(n)].reduce((s,x)=>s+(x=='_'?s[i++]:x),'').slice(0,n)

Beginnt mit einer leeren Zeichenfolge und ersetzt sie bei jedem Auftreten eines Unterstrichs durch das Zeichen im nächsten Index der aktuellen Zeichenfolge.

cPu1
quelle
1

Python 2 - 99 97 Bytes


Da 4 Python-basierte Einsendungen nicht ausreichen ...

n,s=input();S=s=s*n
while"_"in S:x=iter(s);S="".join(j>"_"and j or next(x)for j in S)
print S[:n]

Beispiel:

$ python2 t.py 
(50, "ab_a_cc")
abaabccabaaaccabbacccabcaaccabbaaccabaaaccabcaccca
Matsjoyce
quelle
0

ECMAScript 6, 93 91

(n,s)=>{for(x="_".repeat(n);n=0,/_/.test(x);)x=x.replace(/_/g,a=>s[n++%s.length]);return x}

2 Zeichen aus der ersten Version rasiert.

(n,s)=>{x="_".repeat(n);while(/_/.test(x)){n=0,x=x.replace(/_/g,a=>s[n++%s.length])}return x}
n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳
quelle
0

C # - 162

Ich habe die Geobits-Lösung gestohlen und in C # geändert

char[]p(int n,string s){var r=new char[n];if(n>0)do for(int i=0,j=0;i<n;i++)if(r[i]=='_'||r[i]<1)r[i]=s[j++%s.Length];while(r.ToList().IndexOf('_')>=0);return r;}

1 char besser, damit du Geobits verbessern kannst;)

mike m
quelle