* * Overwrit etichette


23

Se hai mai provato ad aggiungere etichette a una trama davvero densa, ti renderai conto che a volte le etichette si sovrappongono, rendendole difficili da leggere. Faremo qualcosa di simile ma in 1D.

L'input sarà una sequenza di (label, x-coordinate)coppie e l'output sarà il risultato del disegno di ogni punto ed etichetta, nell'ordine dato. Un asterisco che *rappresenta il punto deve essere posizionato sulla coordinata x indicata e l'etichetta deve seguire. Tutti i personaggi esistenti verranno sovrascritti.

Ad esempio, se l'input fosse

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

Quindi succederebbe quanto segue:

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

La riga finale dovrebbe quindi essere emessa.

Regole I / O

  • L'input può consistere in qualsiasi numero di coppie. Ogni etichetta sarà composta solo da lettere maiuscole e minuscole e la lunghezza dell'etichetta sarà al massimo di 127 caratteri. Ogni coordinata x sarà compresa tra 0 e 127 inclusi.

  • L'input può essere in qualsiasi elenco o formato di stringa conveniente in modo tale che le coppie siano inequivocabili e le etichette / coordinate x si alternino nell'input. Ad esempio, un formato simile [("Hello", 0), ("World", 8) ...]o [0 "Hello" 8 "World" ...]va bene. Tuttavia, non puoi assumere due distinti elenchi di etichette e coordinate x.

  • Funzioni e programmi completi sono entrambi a posto.

  • Tutti i punti non coperti da un'etichetta devono essere rappresentati con uno spazio. Tuttavia, potrebbe non esserci spazio bianco iniziale o finale estraneo a parte una singola nuova riga finale opzionale.

Esempi

Ingresso:

OneLabel   10

Produzione:

          *OneLabel

Ingresso:

Heathrow   0
Edinburgh  2
London     4
Liverpool  6
Oxford     8

Produzione:

*H*E*L*L*Oxfordl

Ingresso:

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

Produzione:

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

Ingresso:

abc  5
d    5
abc  10
ABCDEFGHIJKLMNOPQRSTUVWXYZ 127

Produzione:

     *dbc *abc                                                                                                                 *ABCDEFGHIJKLMNOPQRSTUVWXYZ

Si noti che le etichette e / o le coordinate x possono essere ripetute.


Se le corde x sono [0,127] e le stringhe sono (0,127], un'etichetta può scappare dall'estrema destra della linea o è protetta? Cioè, "pippo 127" termina la linea con "*" o "* foo"?
Sto

3
@PotatoOmeletteSandwich La mia intenzione era di far sì che la lunghezza totale corrispondesse a 255, quindi la lunghezza massima dell'output si verificherà quando è presente un'etichetta di lunghezza 127 nella coordinata x 127. L'output finale non deve essere troncato in alcun modo, tranne per rimuovere gli spazi bianchi finali .
Sp3000,

Risposte:


7

CJam, 24 23 19 byte

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

Questo legge l'input come una matrice CJam di coppie coordinate-etichette.

Prova questo violino nell'interprete CJam o verifica tutti i casi di test contemporaneamente.

Grazie a @ MartinBüttner per avermi aiutato a salvare 4 byte!

Come funziona

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

2
Ho appena aggiunto un caso di prova e ho pensato di lasciare un commento dicendo che no, non ha infranto questa affermazione: l'output dell'interprete di CJam è solo un ritorno a capo automatico. Nel caso in cui qualcuno venga confuso.
Sp3000,

4

Pyth, 20 byte

V.Tmrj" *"d9Qpe+d-Nd

Provalo online: Dimostrazione o Test Suite

Spiegazione

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)

1
Questo è molto meglio di quello che avevo.
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(/ +$/,"")

Esempio di utilizzo

Input in una console conforme:

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

Uscita dall'ultima affermazione:

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

Spiegazione

Questo crea una funzione anonima da ctre espressioni che sono state logicamente ANDed insieme. Le prime due affermazioni sono sempre veritiere, e le regole di corto circuito di JS dicono che ogni volta che la prima è veritiera, restituisce l'intero valore sul lato destro (senza forzare il valore booleano): quindi questo è formalmente equivalente a

(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 prima istruzione deve essere racchiusa tra parentesi perché l'operatore di assegnazione =ha una precedenza inferiore rispetto all'operatore AND logico &&.

Anche l'assembly "parametro rest" ..."*"+vfa parte di ES6; concatena un lead *alla stringa e quindi lo interpreta come un parametro simile a un elenco, suddividendolo in un gruppo di argomenti forniti Array.prototype.splice, che accetta (m, n, ...rest)e modifica il suo array in posizione mper rimuovere nelementi e quindi inserire tutti gli restargomenti. Per ottenere questo risultato prima di ES6 dovresti usare il più ingombrante:

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

L'array viene quindi concatenato con la stringa vuota e lo spazio vuoto finale viene eliminato.


4

Python 2, 67 byte

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

Accetta input [('Heathrow', 0), ('Edinburgh', 2), ('London', 4), ('Liverpool', 6), ('Oxford', 8)]e stampa il risultato.

Python non consente di modificare le stringhe e la conversione da e verso un elenco è costosa. Quindi, questo ricrea la stringa zda aggiungere in una nuova parola. Prendiamo i bcaratteri prima della parola, riempiendo gli spazi se necessario, quindi il nuovo testo con un asterisco, quindi la parte zdopo la nuova parola. Si noti che gli spazi finali non vengono mai aggiunti.

La reduceversione è più lunga di 3 caratteri (70):

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

3

Rubino, 94 81 75 byte

golfed:

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

Ecco il codice non salvato:

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

Grazie @ w0lf per i suggerimenti sulla mappatura dell'input!

Grazie @ w0lf e @Non che Charles per aver pensato di rimuovere una variabile.


Vedi i consigli sul golf di Ruby . In questo caso è possibile applicare $ <. Map {| l | ...} è più breve di mentre l = ottiene; ...; end tip e probabilmente sostituirlo puts con $><<(che non richiede lo spazio extra).
Cristian Lupascu,

inoltre, penso che .chomppossa essere rimosso.
Cristian Lupascu,

In questo caso, ora che me lo dici, penso che sia molto sicuro rimuoverlo, come .to_ilo capiremo. Buon pensiero. Grazie @ w0lf!
PotatoOmeletteSandwich

Prego! Ecco una versione più breve in cui ho applicato i suggerimenti sopra e alcuni altri: ideone.com/BiOvV5 . Sentiti libero di pubblicarlo nella tua risposta se ti piace.
Cristian Lupascu,

3
@PotatoOmeletteSandwich Aggiorna il tuo Ruby. 1.8.7 è fuori uso! inoltre, dovresti essere in grado di utilizzare il s[int, int]modulo anziché s[range]per un risparmio di 1 carattere.
Non che Charles il

3

Javascript 121 caratteri

Utilizzando funzionalità non standard, funziona su 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()

Versione precedente: 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

1
/ +/ ha molto più senso che \sdeluso, l'ho perso! Potresti salvare byte usando x=' '.repeat(255);ed evitando il .join?
Dom Hastings,

1
@DomHastings: le stringhe JS sono immutabili, quindi dovresti .split('')inserirle in una struttura di dati mutabile, ma a quel punto Array(255).fill(' ')è più breve. Nella mia versione la maggior parte dei miei risparmi proviene da (a) usando la regola "puoi dare una funzione o un programma" da eliminare eval(prompt())in cambio di c=> (b) usando il Array.prototype.slicemetodo incorporato con un parametro di riposo per accorciare un po 'la parte logica .
CR Drost,

1
@ChrisDrost ah ovviamente ... dimentico che è solo un accessor! La vergogna [].map.call(s[0],non salva neanche ...
Dom Hastings,

2

Python, 85 byte

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

Provalo online


1
Dovresti essere in grado di fare 'z'[2::5](backtick invece di apostrofi) invece di ''.join(z)salvare un byte e passare z=[' ']*256ai parametri dovrebbe salvarne un altro. Inoltre, penso che tu possa cambiare returnin print.
Kade,

Penso che puoi salvare i caratteri scrivendo un programma con p=input()(Python 2) piuttosto che una funzione, che evita il rientro. Inoltre, b+len(a)+1può essereb-~len(a)
xnor

1
In realtà, un programma ti consente di farlo for a,b in input():.
xnor

2

Perl, 66 byte

63 byte di script + 3 byte per -p

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

Niente di troppo speciale, utilizzando le variabili $`e $'che sono rispettivamente "prima della corrispondenza" e "dopo la corrispondenza", anziché dividere la stringa. Ho usato a $}per la variabile stringa poiché inizialmente mi stava risparmiando un byte, ma non lo è più!

Esempio di esecuzione:

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

Perl, 65 byte

62 byte di script + 3 byte per -p

Un'altra versione che stampa ogni riga (per un byte in meno!). (Sì, l'ho fatto perché non ho letto correttamente la domanda ...)

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

Esempio di esecuzione:

$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

2

PHP - 84 byte

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

Utilizza i codici di escape ANSI per posizionare il cursore ( \x1b[XG, con il carattere Escape e X come coordinata basata su 1), seguito *dall'allora stringa di input per quella riga. Accetta input dalla riga di comando del modulo:

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

Accetta le voci composte da più parole tra virgolette, poiché sono argomenti della riga di comando.


1

C ++ 11, 95 byte

Perchè no?

Come funzione, ricevi l'input come un map<int, string>nome vcontenente la posizione e la stringa.

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

uso

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

Controlla in esecuzione qui

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.