* Overwrit * etykiety

23

Jeśli kiedykolwiek próbowałeś dodać etykiety do naprawdę gęstej działki, zdasz sobie sprawę, że czasami etykiety nakładają się na siebie, co utrudnia ich czytanie. Zrobimy coś podobnego, ale w 1D.

Dane wejściowe będą sekwencją (label, x-coordinate)par, a dane wyjściowe będą wynikiem losowania każdego punktu i etykiety w podanej kolejności. Gwiazdka *reprezentująca punkt powinna być umieszczona na danej współrzędnej x, a etykieta powinna następować. Wszelkie istniejące postacie zostaną zastąpione.

Na przykład, jeśli dane wejściowe były

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

Wtedy miałyby miejsce następujące zdarzenia:

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

Ostateczny wiersz powinien być następnie wyprowadzony.

Zasady we / wy

  • Dane wejściowe mogą składać się z dowolnej liczby par. Każda etykieta będzie składać się wyłącznie z wielkich i małych liter, a długość etykiety będzie wynosić maksymalnie 127 znaków. Każda współrzędna x będzie zawierać się między 0 a 127 włącznie.

  • Dane wejściowe mogą być w dowolnym dogodnym formacie listy lub ciągu, tak że pary są jednoznaczne, a etykiety / współrzędne x zmieniają się na wejściu. Na przykład format podobny do [("Hello", 0), ("World", 8) ...]lub [0 "Hello" 8 "World" ...]jest w porządku. Nie można jednak zakładać dwóch osobnych list etykiet i współrzędnych x.

  • Funkcje i pełne programy są w porządku.

  • Wszelkie miejsca nie pokryte etykietą powinny być reprezentowane spacją. Jednak nie może istnieć żadna obca wiodąca lub końcowa biała spacja oprócz pojedynczej opcjonalnej końcowej nowej linii.

Przykłady

Wkład:

OneLabel   10

Wydajność:

          *OneLabel

Wkład:

Heathrow   0
Edinburgh  2
London     4
Liverpool  6
Oxford     8

Wydajność:

*H*E*L*L*Oxfordl

Wkład:

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

Wydajność:

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

Wkład:

abc  5
d    5
abc  10
ABCDEFGHIJKLMNOPQRSTUVWXYZ 127

Wydajność:

     *dbc *abc                                                                                                                 *ABCDEFGHIJKLMNOPQRSTUVWXYZ

Pamiętaj, że etykiety i / lub współrzędne X mogą się powtarzać.

Sp3000
źródło
Jeśli x współrzędnych wynosi [0,127], a ciągi znaków (0,127], czy etykieta może spływać z prawego końca linii, czy też jest chroniona? Czy to znaczy, że „foo 127” kończy linię z „*” lub „* foo”? Sprawdzam tylko, czy struna powinna mieć miękkie czy twarde zakończenie.
PotatoOmeletteSandwich,
3
@PotatoOmeletteSandwich Moim zamiarem było, aby całkowita długość mieściła się w przedziale 255, więc maksymalna długość wyjściowa wystąpi, gdy etykieta długości 127 będzie miała współrzędną x 127. Końcowe wyjście nie powinno być w żaden sposób obcinane, z wyjątkiem usunięcia spacji końcowych .
Sp3000,

Odpowiedzi:

7

CJam, 24 23 19 bajtów

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

Odczytuje to dane wejściowe jako tablicę CJam par etykiet współrzędnych.

Wypróbuj to skrzypce w interpretatorze CJam lub zweryfikuj wszystkie przypadki testowe jednocześnie.

Dzięki @ MartinBüttner za pomoc w oszczędzaniu 4 bajtów!

Jak to działa

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
źródło
2
Właśnie dodałem przypadek testowy i pomyślałem, że zostawię komentarz z informacją, że nie, to nie złamało tego przesłania - wyniki interpretera CJam po prostu zawijają słowa. Na wypadek, gdyby ktoś się zdezorientował.
Sp3000,
4

Pyth, 20 bajtów

V.Tmrj" *"d9Qpe+d-Nd

Wypróbuj online: pakiet demonstracyjny lub testowy

Wyjaśnienie

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
źródło
1
To jest o wiele lepsze niż to, co miałem.
isaacg,
4

JavaScript ES6, 104 bajty

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

Przykładowe użycie

Dane wejściowe do zgodnej konsoli:

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

Dane wyjściowe z ostatniej instrukcji:

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

Wyjaśnienie

Tworzy to anonimową funkcję od ctrzech wyrażeń, które zostały logicznie połączone AND. Pierwsze dwa stwierdzenia są zawsze prawdziwe, a reguły zwarcia JS mówią, że gdy pierwsze jest prawdziwe, zwracaj całą wartość po prawej stronie (bez zmuszania do logicznej wartości): więc jest to formalnie równoważne z

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

Pierwsza instrukcja musi być owinięta w nawiasy powyżej, ponieważ operator przypisania =ma niższy priorytet niż operator logiczny AND &&.

Zespół „parametru odpoczynku” ..."*"+vjest również częścią ES6; konkatenuje odprowadzenie *do łańcucha, a następnie interpretuje go jako parametr podobny do listy, dzieląc go na kilka argumentów, które są dostarczane Array.prototype.splice, które pobierają (m, n, ...rest)i modyfikują jego tablicę w pozycjim celu usunięcia nelementów, a następnie wstawia wszystkie restargumenty. Aby to zrobić przed ES6, użyłbyś bardziej kłopotliwej:

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

Tablica jest następnie łączona z pustym ciągiem, a końcowe białe znaki są usuwane.

CR Drost
źródło
4

Python 2, 67 bajtów

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

Przyjmuje dane wejściowe jak [('Heathrow', 0), ('Edinburgh', 2), ('London', 4), ('Liverpool', 6), ('Oxford', 8)] i drukuje wynik.

Python nie zezwala na modyfikowanie ciągów, a konwersja do i z listy jest kosztowna. To odtwarza ciąg, zaby dodać nowe słowo. Bierzemy bznaki przed słowem, dopełniając w razie potrzeby spacjami, następnie nowy tekst z gwiazdką, a następnie część zpo nowym słowie. Pamiętaj, że końcowe spacje nigdy nie są dodawane.

reduceWersja 3 znaków dłużej (70):

lambda I:reduce(lambda z,(a,b):(z+' '*b)[:b]+'*'+a+z[len(a)-~b:],I,"")
xnor
źródło
3

Ruby, 94 81 75 bajtów

Gra w golfa:

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

Oto nielepszy kod:

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

Dzięki @ w0lf za sugestie dotyczące mapowania danych wejściowych!

Dzięki @ w0lf i @Nie że Charles za myśl o usunięciu zmiennej.

Ziemniak Arbuz Kanapka
źródło
Zobacz Ruby wskazówki golfowe . W takim przypadku możesz zastosować $ <. Mapa {| l | ...} jest krótsza niż gdy l = dostaje; ...; końcówka końcowa i prawdopodobnie zastąp puts $><<(co nie wymaga dodatkowej przestrzeni).
Cristian Lupascu,
myślę też, że .chompmożna go usunąć.
Cristian Lupascu,
W tym przypadku, skoro już o tym wspominasz, myślę, że usunięcie go może być bardzo bezpieczne, jak to się .to_istanie. Dobra myśl. Dzięki @ w0lf!
PotatoOmeletteSandwich
Nie ma za co! Oto krótsza wersja, w której zastosowałem powyższe wskazówki i kilka innych: ideone.com/BiOvV5 . Jeśli chcesz, możesz opublikować go w swojej odpowiedzi.
Cristian Lupascu,
3
@PotatoOmeletteSandwich Uaktualnij swój Ruby. 1.8.7 jest na wyczerpaniu! Ponadto powinieneś być w stanie skorzystać z s[int, int]formularza zamiast s[range]1 oszczędności char.
Nie, że Charles
3

JavaScript 121 znaków

Korzystanie z niestandardowych funkcji działa w przeglądarce 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()

Starsza wersja: 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
źródło
1
/ +/ ma o wiele większy sens niż \srozczarowanie, że za tym tęskniłem! Czy możesz zaoszczędzić bajty przy użyciu x=' '.repeat(255);i unikaniu .join?
Dom Hastings,
1
@DomHastings: Ciągi JS są niezmienne, więc trzeba by .split('')było stworzyć zmienną strukturę danych, ale w tym momencie Array(255).fill(' ')jest ono krótsze. W mojej wersji większość moich oszczędności pochodzi z (a) użycia reguły „możesz podać funkcję lub program” do usunięcia eval(prompt())w zamian c=> i (b) za pomocą wbudowanej Array.prototype.slicemetody z parametrem rest, aby nieco skrócić część logiczną .
CR Drost,
1
@ChrisDrost ah oczywiście ... Zapomniałem, że to tylko akcesorium! Wstyd [].map.call(s[0],nie oszczędza też ...
Dom Hastings,
2

Python, 85 bajtów

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

Wypróbuj online

Mego
źródło
1
Powinieneś być w stanie zrobić 'z'[2::5](backsticks zamiast apostrofów) zamiast ''.join(z)zapisywać jeden bajt, a przejście z=[' ']*256do parametrów powinno uratować inny. Także myślę, że można zmienić returnna print.
Kade,
Myślę, że możesz zapisać znaki, pisząc program za pomocą p=input()(Python 2) zamiast funkcji, co pozwala uniknąć wcięć. Ponadto b+len(a)+1może byćb-~len(a)
xnor
1
W rzeczywistości program po prostu na to pozwala for a,b in input():.
xnor
2

Perl, 66 bajtów

63 bajty skryptu + 3 bajty na -p

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

Nic specjalnego, wykorzystującego zmienne $` i $'które są „przed meczem” i „po meczu”, odpowiednio, zamiast dzielenia ciąg. Użyłem $}zmiennej dla ciągu, ponieważ początkowo oszczędzał mi bajt, ale już nie!

Przykładowy przebieg:

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

Perl, 65 bajtów

62 bajty skryptu + 3 bajty na -p

Kolejna wersja, która wypisuje każdą linię (o jeden bajt mniej!). (Tak, zrobiłem to, ponieważ nie przeczytałem poprawnie pytania ...)

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

Przykładowy przebieg:

$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
źródło
2

PHP - 84 bajty

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

Używa kodów specjalnych ANSI do pozycjonowania kursora ( \x1b[XGzawierającego znak Escape, a X jest współrzędną 1), a *następnie łańcuch wejściowy dla tego wiersza. Akceptuje dane wejściowe w wierszu polecenia formularza:

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

Akceptuje wpisy zawierające wiele słów, jeśli są w cudzysłowach, ponieważ są to argumenty wiersza poleceń.

Niet the Dark Absol
źródło
1

C ++ 11, 95 bajtów

Dlaczego nie?

Jako funkcję odbieraj dane wejściowe jako map<int, string>nazwane vzawierające pozycję i ciąg znaków.

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

Stosowanie

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

Sprawdź, czy działa tutaj

wendelbsilva
źródło