Remplir les espaces vides

14

Contribution

Un entier non négatif net une chaîne non vide scontenant uniquement des caractères alphanumériques et des traits de soulignement _. Le premier caractère de sn'est pas _. Les traits de soulignement de ssont interprétés comme des espaces vides qui peuvent être remplis avec d'autres caractères.

Nous définissons une séquence infinie de "chaînes infinies" comme suit. La chaîne est juste répétée infiniment de fois. Pour tous , la chaîne est obtenue en remplissant ses espaces vides avec les caractères de , de sorte que le premier de soit remplacé par , le second de , etc. Puisque la première lettre de n'est pas , chaque espace vide est finalement rempli, et nous désignons la chaîne infinie où chacun a été remplacé par sa valeur éventuelle.s1 = s s s...sk > 1sk+1sks1_sks1[0]s1[1]s_s_

Production

Les premiers ncaractères d' une chaîne.s

Exemple

Considérez les entrées n = 30et s = ab_c_. Nous avons

s1 = ab_c_ab_c_ab_c_ab_c_ab_c_ab_c_ab_c_...

Remplaçant les blancs de , nous avonss1s1

s2 = abacbab_ccab_caabbc_abcc_abacbab_cc...

Nous remplaçons à nouveau les blancs, ce qui se traduit pars1

s3 = abacbabaccabbcaabbc_abcccabacbab_cc...

Encore une substitution:

s4 = abacbabaccabbcaabbcaabcccabacbabbcc...

On peut déjà en déduire les 30 premiers caractères de , qui sonts

abacbabaccabbcaabbcaabcccabacb

Ceci est la sortie correcte.

Règles

Vous pouvez écrire un programme complet ou une fonction. Le nombre d'octets le plus bas gagne et les failles standard sont interdites. Un plantage sur une entrée incorrecte est acceptable.

Cas de test

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
la source
Pouvons-nous prendre des entrées dans l'ordre inverse (dans les langues où l'ordre est important)?
Martin Ender
@ MartinBüttner Bien sûr, je le permettrai.
Zgarb

Réponses:

4

Pyth, 17

<ussC,cG\_GUQ*zQQ

L'entrée doit être donnée avec la chaîne sur la première ligne, et la longueur sur la seconde, sur STDIN. Par exemple:

abc____
50

Essayez-le ici.

Explication:

                             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
la source
7

APL 29 28

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

il est utilisé comme ceci:

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

Explication:

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
la source
⍣≡est une idée astucieuse. Je devrais peut-être essayer de porter cela sur J ...
FUZxxl
7

CJam, 26 24 20 octets

4 octets économisés grâce à Peter.

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

Testez-le ici. Prend la chaîne en premier et en ndeuxième sur STDIN.

Vous pouvez exécuter tous les cas de test en les collant dans l’entrée tels quels (inclure le -> output si vous le souhaitez) et en utilisant le faisceau de test suivant (qui inverse l'ordre du code):

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

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

]oNo}/

Explication

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.";

Le résultat est imprimé automatiquement à la fin du programme.

Une note sur [\]: En principe, se [souvient de la taille actuelle de la pile et ]collecte tout jusqu'à la dernière taille mémorisée dans un tableau. Cependant, si la taille du tableau tombe en dessous de la taille mémorisée entre les deux, le début du tableau est ajusté en conséquence. Maintenant, vous pourriez penser que l'échange des deux premiers éléments du tableau n'affecte pas du tout la taille du tableau, mais \fait apparaître deux valeurs, puis les pousse dans l'ordre inverse. C'est ce qui pousse le début du tableau vers le bas de deux. Par conséquent, [\]c'est le moyen le plus court pour encapsuler les deux premiers éléments de pile dans un tableau. Parfois, l'effet secondaire de les collecter dans l'ordre inverse est assez ennuyeux, mais dans ce cas, c'est exactement ce dont j'ai besoin.

Martin Ender
la source
Je pense que vous pourriez remplacer _'_#) gpar I*. Fonctionne pour moi dans GolfScript.
Peter Taylor
@PeterTaylor oh, très bonne idée, merci!
Martin Ender
6

Python 3, 110 octets

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

A besoin d'un peu plus de golf, mais voici une folie pure. Lit nensuites partir de STDIN.

La partie amusante est, dans l'affectation de la boucle que nous copions b, puis commençons à sauter bpendant une compréhension de la liste . Si l'affectation était l'inverse, cela ne fonctionnerait pas!

Sp3000
la source
4

k, 30

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

Java - 162 174

Ce n'est pas tous les jours que j'utilise une boucle do / while lorsque je joue au golf en Java: D

Cela réitère et remplit les blancs au fur et à mesure. Cela continue jusqu'à ce qu'il n'y en ait plus _dans le résultat.

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

Avec des sauts de ligne:

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;
}
Géobits
la source
Je
n'allais
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);}

Moins golfé:

(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
la source
3

Rubis, 60

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

Se concatène sà lui-même nfois, puis génère des ncopies de code qui remplacent sles ntraits de soulignement , évalue ces copies et renvoie les premiers caractères du résultat. Puisqu'au moins un trait de soulignement est supprimé dans chaque boucle, cela nous garantit de nous donner ndes caractères sans trait de soulignement.

histocrate
la source
Quelle est la bonne syntaxe pour exécuter cela? Quand je l' appelle fet l' exécution puts f[10,"ab_"], je reçois l'erreur suivante: in 'eval': undefined method 'next' for #<Array:.... Cela semble fonctionner quand il n'y a pas de soulignement dans la chaîne.
Théophile
Oh, intéressant, cela ressemble au comportement de String#charschangé entre Ruby 1.9.3 et Ruby 2.0; dans Ruby 1, il renvoie un énumérateur lorsqu'il n'y a pas de bloc, dans Ruby 2 un tableau. Il peut être rendu insensible à la version en changeant charsen each_char, au prix de 4 octets nets supplémentaires de code.
histocrate
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]

Cela attend une entrée comme (30,"ab_c_").

En Python, les chaînes ne permettent pas l'attribution. Il est donc difficile de remplacer les blancs par le caractère souhaité. On peut contourner cela en convertissant en une liste et inversement, mais je l'ai trouvé plus court pour générer simplement la chaîne de sortie à partir de zéro, en ajoutant les caractères souhaités un à la fois.

La sortie en cours de construction est S, qui commence vide. Nous parcourons les caractères de l'entrée scopiée plusieurs fois pour simuler un cercle. Nous vérifions s'il s'agit d'un blanc via le booléen b. Nous vérifions l'égalitéx=='_' plutôt que la comparaison car le trait de soulignement se situe entre les majuscules et les minuscules.

Si le caractère n'est pas un blanc, nous l'ajoutons juste dessus S. S'il est vide, nous ajoutons la prochaine lettre inutilisée de la sortie jusqu'à présent S. Nous suivons les lettres utilisées par un pointeur d'index cqui commence à 0 et est incrémenté chaque fois que nous rencontrons un blanc.

À la fin, nous imprimons les premiers ncaractères de la chaîne résultante S.

Nous devons utiliser S[c:c+b]à la place du plus court, b*S[c]car ce dernier donne une erreur hors limites lorsque Scommence vide et cvaut 0. Cela n'a jamais d'importance car nous sommes garantis que le premier caractère de sn'est pas vide, donc ce S[c]n'est jamais nécessaire, mais le code ne le sait pas. Inverser le orcourt-circuit pourrait également résoudre ce problème, mais coûte plus de caractères.


Python 2, 83

Un port Pyth-to-Python de la solution d' isaacg , qui utilise splitet zipeffectue le remplacement:

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

Cela s'est avéré plus long car, surprise, les méthodes nommées sont longues en python. Mais il peut peut-être être amélioré en rayonnant set s.split('_')ensemble de manière plus courte.

xnor
la source
Agréable! Je ne m'attendais pas à ce que la reconstruction de la chaîne soit tellement plus courte!
Sp3000
3

Haskell (93) 67

Je n'ai pas écrit de Haskell depuis un moment, donc cela peut probablement être beaucoup raccourci. mais c'était tellement bon, nous avons dû le raccourcir et le rendre meilleur!

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

Usage:

*Main> f 50 "ab_a_cc"
"abaabccabaaaccabbacccabcaaccabbaaccabaaaccabcaccca"
marinus
la source
2

Lot - 425

Dois-je perdre?

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

Le lot a des limites - j'accepte cela. Par exemple; J'ai dû utiliser une boucle for pour obtenir une seule variable dans un format utilisable en raison des limitations de la syntaxe d'analyse des variables. for %%b in (!c!)do... existe juste pour que je puisse utiliser %%bau lieu de !c!pour que je puisse réellement faire la manipulation de chaîne !s:~%%b,1!et avoir les variables se développer au bon moment.

Il y a quelques choses assez basiques que je pourrais faire pour jouer au golf plus loin, mais probablement pas en dessous de 400 octets. J'aurai bientôt un autre crack.

dégrader
la source
3
À moins que quelqu'un ne poste une meilleure réponse par lot, je n'appellerais pas cela une perte :)
Sp3000
@ Sp3000 Si seulement quelqu'un le pouvait.
unclemeat
2

ECMAScript 6, 78

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

Commence par une chaîne vide et pour chaque occurrence de trait de soulignement, la remplace par le caractère à l'index suivant de la chaîne actuelle.

cPu1
la source
1

Python 2 - 99 97 octets


Parce que 4 soumissions basées sur python ne suffisent pas ...

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]

Exemple:

$ python2 t.py 
(50, "ab_a_cc")
abaabccabaaaccabbacccabcaaccabbaaccabaaaccabcaccca
matsjoyce
la source
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}

Rasé 2 caractères de la première version.

(n,s)=>{x="_".repeat(n);while(/_/.test(x)){n=0,x=x.replace(/_/g,a=>s[n++%s.length])}return x}
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
la source
0

C # - 162

J'ai volé la solution Geobits et l'ai changé en C #

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 de mieux, donc vous pouvez améliorer les géobits;)

mike m
la source