* Beschriftungen überschreiben *

23

Wenn Sie jemals versucht haben, einem wirklich dichten Plot Beschriftungen hinzuzufügen, werden Sie feststellen, dass sich Beschriftungen manchmal überlappen und daher schwer lesbar sind. Wir werden etwas Ähnliches machen, aber in 1D.

Die Eingabe ist eine Folge von (label, x-coordinate)Paaren, und die Ausgabe ist das Ergebnis des Zeichnens der einzelnen Punkte und Beschriftungen in der angegebenen Reihenfolge. Ein Sternchen, *das den Punkt darstellt, sollte an der angegebenen x-Koordinate platziert werden und die Beschriftung sollte folgen. Eventuell vorhandene Zeichen werden überschrieben.

Zum Beispiel, wenn die Eingabe war

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

Dann würde folgendes passieren:

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

Die letzte Zeile sollte dann ausgegeben werden.

I / O-Regeln

  • Die Eingabe kann aus beliebig vielen Paaren bestehen. Jedes Etikett besteht nur aus Groß- und Kleinbuchstaben, und die Etikettenlänge beträgt höchstens 127 Zeichen. Jede x-Koordinate liegt zwischen 0 und 127 einschließlich.

  • Die Eingabe kann in einem beliebigen geeigneten Listen- oder Zeichenfolgeformat erfolgen, sodass die Paare eindeutig sind und sich die Bezeichnungen / x-Koordinaten in der Eingabe abwechseln. Zum Beispiel ist ein Format wie [("Hello", 0), ("World", 8) ...]oder [0 "Hello" 8 "World" ...]in Ordnung. Es ist jedoch nicht zulässig, zwei separate Listen mit Beschriftungen und x-Koordinaten zu verwenden.

  • Funktionen und Vollprogramme sind beide in Ordnung.

  • Alle Stellen, die nicht durch ein Etikett abgedeckt sind, sollten mit einem Leerzeichen dargestellt werden. Abgesehen von einer einzelnen optionalen abschließenden Newline darf es jedoch keine zusätzlichen führenden oder abschließenden Whitespaces geben.

Beispiele

Eingang:

OneLabel   10

Ausgabe:

          *OneLabel

Eingang:

Heathrow   0
Edinburgh  2
London     4
Liverpool  6
Oxford     8

Ausgabe:

*H*E*L*L*Oxfordl

Eingang:

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

Ausgabe:

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

Eingang:

abc  5
d    5
abc  10
ABCDEFGHIJKLMNOPQRSTUVWXYZ 127

Ausgabe:

     *dbc *abc                                                                                                                 *ABCDEFGHIJKLMNOPQRSTUVWXYZ

Beachten Sie, dass Beschriftungen und / oder x-Koordinaten wiederholt werden können.

Sp3000
quelle
Wenn die x-Koordinaten [0,127] und die Zeichenfolgen (0,127] sind, kann ein Label am rechten Ende der Zeile ablaufen oder ist es geschützt? Das heißt, endet "foo 127" die Zeile mit "*" oder "* foo"?
Ich
3
@PotatoOmeletteSandwich Meine Absicht war, dass die Gesamtlänge in 255 passt, sodass die maximale Ausgabelänge auftritt, wenn an der x-Koordinate 127 eine Länge von 127 angegeben ist. Die endgültige Ausgabe sollte in keiner Weise abgeschnitten werden, außer um nachfolgende Leerzeichen zu entfernen .
Sp3000

Antworten:

7

CJam, 24 23 19 Bytes

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

Dies liest die Eingabe als ein CJam-Array von Koordinaten-Label-Paaren.

Probieren Sie diese Geige im CJam-Interpreter aus oder überprüfen Sie alle Testfälle auf einmal.

Vielen Dank an @ MartinBüttner, der mir geholfen hat, 4 Bytes zu sparen!

Wie es funktioniert

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
quelle
2
Ich habe gerade einen Testfall hinzugefügt und dachte, ich würde einen Kommentar hinterlassen, der besagt, dass dies nicht zu einer Unterbrechung dieser Übermittlung führt - CJams Interpreter-Ausgabe besteht nur aus Zeilenumbrüchen. Nur für den Fall, dass jemand verwirrt wird.
Sp3000
4

Pyth, 20 Bytes

V.Tmrj" *"d9Qpe+d-Nd

Probieren Sie es online aus: Demo oder Test Suite

Erläuterung

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
quelle
1
Das ist viel besser als das, was ich hatte.
isaacg
4

JavaScript ES6, 104 Byte

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

Beispielanwendung

Eingabe in eine kompatible Konsole:

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

Ausgabe der letzten Anweisung:

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

Erläuterung

Dadurch wird eine anonyme Funktion aus cdrei Ausdrücken erstellt, die logisch UND-verknüpft wurden. Die ersten beiden Aussagen sind immer wahr, und die JS-Kurzschlussregeln besagen, dass immer dann, wenn die erste wahr ist, der gesamte Wert auf der rechten Seite zurückgegeben wird (ohne auf boolesch zu zwingen): Dies ist also formal äquivalent zu

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

Die erste Anweisung muss oben in Klammern gesetzt werden, da der Zuweisungsoperator =eine niedrigere Priorität als der logische AND-Operator hat &&.

Die Assembly "rest parameter" ..."*"+vist ebenfalls Teil von ES6. Es verkettet einen Verweis *auf die Zeichenfolge und interpretiert ihn dann als einen listenähnlichen Parameter. Dabei wird er in eine Reihe von Argumenten aufgeteilt, die zur Verfügung gestellt werden. Dabei Array.prototype.splicewird das (m, n, ...rest)Array an der Position übernommen und geändert m, um nElemente zu entfernen und anschließend alle restArgumente einzufügen . Um dies vor ES6 zu erreichen, würden Sie das umständlichere verwenden:

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

Das Array wird dann mit der leeren Zeichenfolge verkettet und das nachfolgende Leerzeichen wird gelöscht.

CR Drost
quelle
4

Python 2, 67 Bytes

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

Nimmt Eingaben wie [('Heathrow', 0), ('Edinburgh', 2), ('London', 4), ('Liverpool', 6), ('Oxford', 8)]und druckt das Ergebnis.

In Python können Zeichenfolgen nicht geändert werden, und das Konvertieren in und aus einer Liste ist teuer. Dadurch wird die Zeichenfolge neu erstellt z, um ein neues Wort hinzuzufügen. Wir nehmen die bZeichen vor dem Wort, füllen sie bei Bedarf mit Leerzeichen auf, dann den neuen Text mit einem Stern und den Teil znach dem neuen Wort. Beachten Sie, dass nachgestellte Leerzeichen niemals hinzugefügt werden.

Die reduceVersion ist 3 Zeichen länger (70):

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

Ruby, 94 81 75 Bytes

Golf gespielt:

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

Hier ist der ungolfed Code:

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

Vielen Dank an @ w0lf für die Vorschläge zur Zuordnung der Eingabe!

Vielen Dank an @ w0lf und @Not that Charles für den Gedanken, eine Variable zu entfernen.

PotatoOmeletteSandwich
quelle
Lesen Sie die Ruby-Golftipps . In diesem Fall könnten Sie die Anwendung $ <Karte {| l | ...} kürzer als während l = wird;. ...; Ende Spitze und wahrscheinlich ersetzen puts mit $><<(was nicht den zusätzlichen Platz benötigt).
Cristian Lupascu
auch denke ich .chompkann entfernt werden.
Cristian Lupascu
In diesem Fall, jetzt wo Sie es erwähnen, denke ich, dass es sehr sicher ist, es zu entfernen, da dies der Fall sein .to_iwird. Guter Gedanke. Danke @ w0lf!
PotatoOmeletteSandwich
Bitte! Hier ist eine kürzere Version, in der ich die obigen Tipps und einige weitere angewendet habe : ideone.com/BiOvV5 . Fühlen Sie sich frei, es in Ihrer Antwort zu posten, wenn Sie es mögen.
Cristian Lupascu
3
@PotatoOmeletteSandwich Rüsten Sie Ihren Ruby auf. 1.8.7 ist abgelaufen! Sie sollten auch in der Lage sein, das s[int, int]Formular zu verwenden, s[range]um 1 Zeichen zu sparen.
Nicht dass Charles
3

Javascript 121 Zeichen

Funktioniert mit Firefox, wenn keine Standardfunktionen verwendet werden.
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()

Ältere 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
quelle
1
/ +/ Sinnvoller als \senttäuscht habe ich das verpasst! Könnten Sie Bytes sparen, indem Sie das verwenden x=' '.repeat(255);und vermeiden .join?
Dom Hastings
1
@DomHastings: JS-Strings sind unveränderlich, daher müssten Sie .split('')sie in eine veränderbare Datenstruktur einfügen , aber an diesem Punkt Array(255).fill(' ')ist sie kürzer. In meiner Version resultieren die meisten Einsparungen aus (a) der Verwendung der Regel "Sie können entweder eine Funktion oder ein Programm angeben ", die eval(prompt())im Austausch für gelöscht werden soll , c=>und (b) der Verwendung der eingebauten Array.prototype.sliceMethode mit einem Rest-Parameter, um den Logikteil ein wenig zu verkürzen .
CR Drost
1
@ ChrisDrost ah natürlich ... Ich vergesse, es ist nur ein Accessor! Schande [].map.call(s[0],rettet auch keine ...
Dom Hastings
2

Python, 85 Bytes

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

Probieren Sie es online aus

Mego
quelle
1
Sie sollten in der Lage sein 'z'[2::5](Backticks anstelle von Apostrophen), anstatt ''.join(z)ein Byte zu speichern, und z=[' ']*256wenn Sie zu den Parametern wechseln , sollte ein anderes Byte gespeichert werden . Auch ich denke , man kann ändern returnzu print.
Kade
Ich denke, Sie können Zeichen sparen, indem Sie ein Programm mit p=input()(Python 2) schreiben und nicht mit einer Funktion, die Einrückungen vermeidet. Auch b+len(a)+1kannb-~len(a)
xnor
1
Tatsächlich lässt ein Programm Sie gerade tun for a,b in input():.
Xnor
2

Perl, 66 Bytes

63 Bytes Skript + 3 Bytes für -p

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

Nichts Besonderes, die Variablen verwendet $`und $'welche sind ‚vor dem Spiel‘ und ‚nach dem Spiel‘ jeweils statt Spaltung des String. Ich habe $}für die String-Variable a verwendet, da sie mir ursprünglich ein Byte erspart hat, aber nicht mehr!

Beispiellauf:

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

Perl, 65 Bytes

62 Bytes Skript + 3 Bytes für -p

Eine andere Version, die jede Zeile druckt (für ein Byte weniger!). (Ja, ich habe das gemacht, weil ich die Frage nicht richtig gelesen habe ...)

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

Beispiellauf:

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

PHP - 84 Bytes

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

Verwendet ANSI-Escape-Codes, um den Cursor zu positionieren ( \x1b[XGmit dem Escape-Zeichen und X als 1-basierter Koordinate), gefolgt von *der Eingabezeichenfolge für diese Zeile. Akzeptiert Eingaben in der Befehlszeile des Formulars:

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

Akzeptiert Mehrworteinträge in Anführungszeichen, da sie Befehlszeilenargumente sind.

Niet the Dark Absol
quelle
1

C ++ 11, 95 Bytes

Warum nicht?

Empfangen Sie als eine Funktion Eingabe als ein map<int, string>Name v, der die Position und die Zeichenfolge enthält.

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

Verwendung

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

Überprüfen Sie es hier ausgeführt

Wendelbsilva
quelle