* Remplacer les étiquettes *

23

Si vous avez déjà essayé d'ajouter des étiquettes à un tracé très dense, vous vous rendrez compte que parfois les étiquettes se chevauchent, ce qui les rend difficiles à lire. Nous allons faire quelque chose de similaire mais en 1D.

L'entrée sera une séquence de (label, x-coordinate)paires et la sortie sera le résultat du dessin de chaque point et étiquette, dans l'ordre donné. Un astérisque *représentant le point doit être placé à la coordonnée x donnée et l'étiquette doit suivre. Tous les caractères existants seront remplacés.

Par exemple, si l'entrée était

Hello  0
World  8
Fizz   3
Buzz   5
PPCG   16
X      9

Ensuite, ce qui se passerait:

*Hello
*Hello  *World
*He*Fizz*World
*He*F*Buzzorld
*He*F*Buzzorld  *PPCG  
*He*F*Buz*Xrld  *PPCG

La ligne finale doit ensuite être sortie.

Règles d'E / S

  • L'entrée peut être constituée de n'importe quel nombre de paires. Chaque étiquette se composera uniquement de lettres majuscules et minuscules, et les longueurs d'étiquette seront au plus 127 caractères. Chaque coordonnée x sera comprise entre 0 et 127 inclus.

  • L'entrée peut être dans n'importe quel format de liste ou de chaîne pratique de sorte que les paires soient sans ambiguïté et que les étiquettes / coordonnées x alternent dans l'entrée. Par exemple, un format comme [("Hello", 0), ("World", 8) ...]ou [0 "Hello" 8 "World" ...]est très bien. Cependant, vous ne pouvez pas supposer deux listes distinctes d'étiquettes et de coordonnées x.

  • Les fonctions et les programmes complets sont tous deux corrects.

  • Tout point non couvert par une étiquette doit être représenté par un espace. Cependant, il peut ne pas y avoir d'espaces extérieurs de début ou de fin en dehors d'une seule nouvelle ligne de fin facultative.

Exemples

Contribution:

OneLabel   10

Sortie:

          *OneLabel

Contribution:

Heathrow   0
Edinburgh  2
London     4
Liverpool  6
Oxford     8

Sortie:

*H*E*L*L*Oxfordl

Contribution:

alpha     20
beta       4
gamma     57
delta      3
epsilon   22
zeta      32
eta       53
theta     27

Sortie:

   *delta           *a*epsi*thetazeta                *eta*gamma

Contribution:

abc  5
d    5
abc  10
ABCDEFGHIJKLMNOPQRSTUVWXYZ 127

Sortie:

     *dbc *abc                                                                                                                 *ABCDEFGHIJKLMNOPQRSTUVWXYZ

Notez que les étiquettes et / ou les coordonnées x peuvent être répétées.

Sp3000
la source
Si les x coords sont [0,127] et les chaînes sont (0,127], une étiquette peut-elle courir à l'extrémité droite de la ligne, ou est-elle protégée? Autrement dit, "foo 127" termine-t-il la ligne par "*" ou "* foo"? Je vérifie simplement si la chaîne doit avoir une fin douce ou dure.
PotatoOmeletteSandwich
3
@PotatoOmeletteSandwich Mon intention était de faire en sorte que la longueur totale se situe à l'intérieur de 255, de sorte que la longueur de sortie maximale se produise lorsqu'il y a une étiquette de longueur 127 à la coordonnée x 127. La sortie finale ne devrait pas être tronquée de quelque façon que ce soit, sauf pour supprimer les espaces de fin. .
Sp3000

Réponses:

7

CJam, 24 23 19 octets

l~Sf.*'*f*:.{S^+1=}

Cela lit l'entrée comme un tableau CJam de paires d'étiquettes de coordonnées.

Essayez ce violon dans l'interpréteur CJam ou vérifiez tous les cas de test à la fois.

Merci à @ MartinBüttner de m'avoir aidé à économiser 4 octets!

Comment ça marche

l~                   Read a line from STDIN and evaluate it.
  Sf                 For each pair, push the pair and " "; then:
    .*                 Perform vectorized repetition.
                         [X "label"] " " .* -> [(X spaces) "label"]
      '*f*           Join each resulting pair, using '*' as separator.
          :.{     }  Reduce by the following vectorized operator:
                       Push two characters (A and B).
             S^        Compute the symmetric difference of B and " ".
                       This pushes "B " for a non-space B and "" otherwise.
                +1=    Append and select the second character (with wrap).
                       This selects B for "AB " and A for "A".
Dennis
la source
2
Je viens d'ajouter un cas de test et j'ai pensé laisser un commentaire disant que non, cela n'a pas cassé cette soumission - la sortie de l'interpréteur de CJam ne fait que boucler les mots. Juste au cas où quelqu'un serait confus.
Sp3000
4

Pyth, 20 octets

V.Tmrj" *"d9Qpe+d-Nd

Essayez-le en ligne: démonstration ou suite de tests

Explication

V.Tmrj" *"d9Qpe+d-Nd
   m        Q         map each pair d of the input to:
     j" *"d             join d by the string " *"
    r      9            range-length encode 
                        (this gives x-coordinate spaces, a star and the label)
 .T                   transpose this table 
V                     for N in ^:
                 -Nd    remove spaces from N
               +d       add a space at the beginning
              e         take the last character
             p          and print it (without newline)
Jakube
la source
1
C'est bien mieux que ce que j'avais.
isaacg
4

JavaScript ES6, 104 octets

c=>(a=Array(255).fill(" "))&&c.map(([u,v])=>a.splice(u,v.length+1,..."*"+v))&&a.join``.replace(/ +$/,"")

Exemple d'utilisation

Entrée dans une console compatible:

t = [[0,"Hello"],[8,"World"],[3,"Fizz"],[5,"Buzz"],[16,"PPCG"],[9,"X"]];
(c=>(a=Array(255).fill(" "))&&c.map(([u,v])=>a.splice(u,v.length+1,..."*"+v))&&a.join``.replace(/ +$/,""))(t);

Sortie de la dernière instruction:

"*He*F*Buz*Xrld  *PPCG"

Explication

Cela crée une fonction anonyme de cà trois expressions qui ont été logiquement ET combinées. Les deux premières déclarations sont toujours véridiques, et les règles de court-circuit JS disent que chaque fois que la première est véridique, retourne la valeur entière sur le côté droit (sans forcer à booléen): c'est donc formellement équivalent à

(function (c) {
    a = Array(255).fill(" ");                    // global variable `a` overwritten
    c.map(function (x) {                         // only side-effects are used here.
       var u = x[0], v = x[1];                   // ES6 destructuring
       a.splice(u, v.length + 1, ..."*" + v));   // main logic
    });
    return a.join("").replace(/ +$/, "");        // postprocessing and trim
})

La première instruction doit être placée entre parenthèses ci-dessus car l'opérateur d'affectation =a une priorité inférieure à l'opérateur logique ET &&.

L'assemblage "paramètre de repos" ..."*"+vfait également partie d'ES6; il concatène un début *à la chaîne, puis l'interprète comme un paramètre de type liste, le divisant en un groupe d'arguments fournis Array.prototype.splice, qui prend (m, n, ...rest)et modifie son tableau en position mpour supprimer des néléments, puis insère tous les restarguments. Pour ce faire avant ES6, vous utiliseriez le plus lourd:

[].slice.apply(a, [u, v.length + 1].concat(("*" + v).split("")))

Le tableau est ensuite concaténé avec la chaîne vide et les espaces de fin sont supprimés.

CR Drost
la source
4

Python 2, 67 octets

z=''
for a,b in input():z=(z+' '*b)[:b]+'*'+a+z[len(a)-~b:]
print z

Prend l'entrée comme [('Heathrow', 0), ('Edinburgh', 2), ('London', 4), ('Liverpool', 6), ('Oxford', 8)]et imprime le résultat.

Python n'autorise pas la modification des chaînes, et la conversion vers et depuis une liste coûte cher. Ainsi, cela recrée la chaîne zà ajouter dans un nouveau mot. Nous prenons les bcaractères avant le mot, en remplissant les espaces si nécessaire, puis le nouveau texte avec un astérisque, puis la partie zaprès le nouveau mot. Notez que les espaces de fin ne sont jamais ajoutés.

La reduceversion est plus longue de 3 caractères (70):

lambda I:reduce(lambda z,(a,b):(z+' '*b)[:b]+'*'+a+z[len(a)-~b:],I,"")
xnor
la source
3

Rubis, 94 81 75 octets

Golfé:

s=" "*128;$<.map{|l|w,p=l.split;p=p.to_i;s[p..w.size+p]="*"+w};$><<s.rstrip

Voici le code non golfé:

s = " "*128
$<.map{|l|                 # for each line entered via stdin, ctrl+D to stop
  w,p = l.split            # had to move the chomp down here
  p = p.to_i               # there's no 'to_i!'...
  s[p..w.size+p] = "*"+w   # in the range of *foobar, replace the string
}
$><<s.rstrip               # output suggested by w0lf

Merci @ w0lf pour les suggestions sur le mappage de l'entrée!

Merci @ w0lf et @Not que Charles pour la réflexion sur la suppression d'une variable.

Pomme De TerreOmeletteSandwich
la source
Voir les conseils de golf Ruby . Dans ce cas, vous pouvez appliquer le $ <. Map {| l | ...} est plus court que tandis que l = gets; ...; end tip et probablement le remplacer puts par $><<(ce qui ne nécessite pas d'espace supplémentaire).
Cristian Lupascu
aussi, je pense que .chomppeut être supprimé.
Cristian Lupascu
Dans ce cas, maintenant que vous le mentionnez, je pense qu'il est probablement très sûr de l'enlever, comme cela .to_iva l'attraper. Bonne pensée. Merci @ w0lf!
PotatoOmeletteSandwich
Vous êtes les bienvenus! Voici une version plus courte dans laquelle j'ai appliqué les conseils ci-dessus et quelques autres: ideone.com/BiOvV5 . N'hésitez pas à le poster dans votre réponse si vous l'aimez.
Cristian Lupascu
3
@PotatoOmeletteSandwich Mettez à niveau votre Ruby. 1.8.7 est en fin de vie! vous devriez également pouvoir utiliser le s[int, int]formulaire au lieu de s[range]pour 1 épargne.
Pas que Charles
3

Javascript 121 caractères

En utilisant des fonctionnalités non standard, fonctionne sur Firefox.
x=Array(255).fill(" ");eval(prompt()).map(s=>{s[0].split``.map((n,i)=>x[s[1]+i+1]=n);x[s[1]]="*"});x=x.join``.trimRight()

Ancienne version: x=Array(255).fill(" ");eval(prompt()).map(s=>{s[0].split``.map((n,i)=>x[s[1]+i+1]=n);x[s[1]]="*"});x=x.join``.replace(/ +$/,"")

x=Array(255).fill(" ");      //Creates an array with spaces
eval(prompt())               //Gets some input, has to look like [["Hello",4],["Hi",14],["Oi",0]]
.map(s=>{s[0].split``.map((n,i)=>x[s[1]+i+1]=n);x[s[1]]="*"}); //Main "logic"
x=x.join``.replace(/ +$/,"") //Gets rid of the trailing spaces
Stefnotch
la source
1
/ +/ est beaucoup plus logique que \sdéçu, j'ai raté ça! Pourriez-vous enregistrer des octets en utilisant x=' '.repeat(255);et en évitant le .join?
Dom Hastings
1
@DomHastings: les chaînes JS sont immuables, vous devrez donc les intégrer .split('')dans une structure de données mutable, mais à ce stade, elle Array(255).fill(' ')est plus courte. Dans ma version, la plupart de mes économies proviennent de (a) l'utilisation de la règle "vous pouvez donner une fonction ou un programme" à supprimer eval(prompt())en échange de c=> et (b) en utilisant la Array.prototype.sliceméthode intégrée avec un paramètre de repos pour raccourcir un peu la partie logique .
CR Drost
1
@ChrisDrost ah bien sûr ... j'oublie que c'est juste un accesseur! La honte [].map.call(s[0],n'en sauve pas non plus ...
Dom Hastings
2

Python, 85 octets

def g(p):
 z=[' ']*256
 for a,b in p:z[b:b+len(a)+1]='*'+a
 return''.join(z).rstrip()

Essayez-le en ligne

Mego
la source
1
Vous devriez être capable de faire 'z'[2::5](backticks au lieu d'apostrophes) au lieu d' ''.join(z)enregistrer un octet, et le déplacement z=[' ']*256vers les paramètres devrait en enregistrer un autre. De plus, je pense que vous pouvez changer returnpour print.
Kade
Je pense que vous pouvez enregistrer des caractères en écrivant un programme avec p=input()(Python 2) plutôt qu'une fonction, ce qui évite l'indentation. En outre, b+len(a)+1peut êtreb-~len(a)
xnor
1
En fait, un programme vous permet de le faire for a,b in input():.
xnor
2

Perl, 66 octets

Script de 63 octets + 3 octets pour -p

$}||=$"x128;/\s+/,substr$},$',1+length$`,"*$`"}{$_=$};s/\s+$/
/

Rien de trop spécial, en utilisant les variables $`et $'qui sont «avant la correspondance» et «après la correspondance» respectivement, au lieu de diviser la chaîne. J'ai utilisé un $}pour la variable chaîne car à l'origine il me faisait économiser un octet, mais ce n'est plus le cas!

Exemple d'exécution:

$perl -p overwritlabels.pl <<< 'Hello  0
World  8
Fizz   3
Buzz   5
PPCG   16
X      9'
*He*F*Buz*Xrld  *PPCG

Perl, 65 octets

Script de 62 octets + 3 octets pour -p

Une autre version qui imprime chaque ligne (pour un octet de moins!). (Oui, je l'ai fait parce que je n'ai pas bien lu la question ...)

$}||=$"x128;/\s+/;substr$},$',1+length$`,"*$`";$_=$};s/\s+$/
/

Exemple d'exécution:

$perl -p overwritlabels.pl <<< 'Hello  0
World  8
Fizz   3
Buzz   5
PPCG   16
X      9'
*Hello
*Hello  *World
*He*Fizz*World
*He*F*Buzzorld
*He*F*Buzzorld  *PPCG
*He*F*Buz*Xrld  *PPCG
Dom Hastings
la source
2

PHP - 84 octets

<? foreach(array_chunk(array_slice($argv,1),2) as $p) echo "␣[".($p[1]+1)."G*$p[0]";
                                                            ^ ESC character (\x1b)

Utilise les codes d'échappement ANSI pour positionner le curseur ( \x1b[XG, avec le caractère d'échappement et X étant la coordonnée basée sur 1), suivi de la *chaîne d'entrée de cette ligne. Accepte la saisie sur la ligne de commande du formulaire:

php filename.php Heathrow 0 Edinburgh 2 London 4 Liverpool 6 Oxford 8
php filename.php abc 5 d 5 abc 10 ABCDEFGHIJKLMNOPQRSTUVWXYZ 127

Accepte les entrées de plusieurs mots si elles sont entre guillemets, car ce sont des arguments de ligne de commande.

Niet l'Absolu Noir
la source
1

C ++ 11, 95 octets

Pourquoi pas?

En tant que fonction, recevez l'entrée en tant que map<int, string>nom vcontenant la position et la chaîne.

string t(255,' ');for(auto&m:v){int i=m.first;t[i++]='*';for(auto&c:m.second)t[i++]=c;}cout<<t;

Usage

#include <iostream>
#include <map>
using namespace std;
int main(){
    map<int,string> v{{0,"Heathrow"},{2,"Edinburgh"},{4,"London"},{6,"Liverpool"},{8,"Oxford"}};
    string t(255,' ');for(auto&m:v){int i=m.first;t[i++]='*';for(auto&c:m.second)t[i++]=c;}cout<<t;
}

Vérifiez-le en cours d'exécution ici

wendelbsilva
la source