* Переписування * міток


23

Якщо ви коли-небудь намагалися додавати мітки в дійсно щільний сюжет, то зрозумієте, що іноді мітки перекриватимуться один одним, що робить їх важким для читання. Ми будемо робити щось подібне, але в 1D.

Введення буде послідовністю (label, x-coordinate)пар, а вихід буде результатом малювання кожної точки і мітки у заданому порядку. Зірочку, що *представляє точку, слід розмістити на заданій координаті x, а мітка повинна слідувати. Будь-які існуючі символи будуть перезаписані.

Наприклад, якщо вхід був

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

Потім слід вивести заключний рядок.

Правила вводу / виводу

  • Введення може складатися з будь-якої кількості пар. Кожна мітка складається лише з малих та малих літер, а довжина мітки - не більше 127 символів. Кожна координата x буде від 0 до 127 включно.

  • Введення може бути у будь-якому зручному списку чи рядковому форматі таким чином, що пари є однозначними, а мітки / x-координати чергуються у введенні. Наприклад, формат на кшталт [("Hello", 0), ("World", 8) ...]або [0 "Hello" 8 "World" ...]добре. Однак ви можете не припускати двох окремих списків міток і x-координат.

  • Функції та повні програми - це нормально.

  • Будь-які плями, не накриті етикеткою, повинні бути представлені пробілом. Однак, не може бути жодного стороннього провідної чи кінцевої пробілів осторонь однієї необов'язкової кінцевої нової лінії.

Приклади

Вхід:

OneLabel   10

Вихід:

          *OneLabel

Вхід:

Heathrow   0
Edinburgh  2
London     4
Liverpool  6
Oxford     8

Вихід:

*H*E*L*L*Oxfordl

Вхід:

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

Вихід:

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

Вхід:

abc  5
d    5
abc  10
ABCDEFGHIJKLMNOPQRSTUVWXYZ 127

Вихід:

     *dbc *abc                                                                                                                 *ABCDEFGHIJKLMNOPQRSTUVWXYZ

Зауважте, що мітки та / або координати x можуть повторюватися.


Якщо координати x - [0,127], а рядки - (0,127]), чи може мітка бігати з правого кінця рядка чи захищена? Тобто, чи закінчується "foo 127" рядок "*" або "* foo"? Просто перевіряємо, чи має струна м'якого чи твердого закінчення.
PotatoOmeletteSandwich

3
@PotatoOmeletteSandwich Мій задум полягав у тому, щоб загальна довжина підходила в межах 255, тому максимальна довжина виходу буде виникати, коли на x-координаті 127 буде мітка довжини 127, остаточний висновок не повинен бути усіченим, окрім видалення пробілу пробілу .
Sp3000

Відповіді:


7

CJam, 24 23 19 байт

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

Це читає вхід як масив CJam пар координат-міток.

Спробуйте цю загадку в інтерпретаторі CJam або перевірити всі тестові випадки одразу.

Дякуємо @ MartinBüttner за допомогу мені зберегти 4 байти!

Як це працює

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
Я щойно додав тестовий випадок і подумав, що залишу коментар, сказавши, що ні, це не порушило це подання - перекладач CJam виводить лише обгортання слів. Про всяк випадок, коли хтось заплутається.
Sp3000

4

Pyth, 20 байт

V.Tmrj" *"d9Qpe+d-Nd

Спробуйте в Інтернеті: Демонстрація або Тестовий набір

Пояснення

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
Це краще, ніж те, що я мав.
isaacg

4

JavaScript ES6, 104 байти

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

Приклад використання

Введення в сумісну консоль:

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

Вихід з останнього твердження:

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

Пояснення

Це створює анонімну функцію від cтрьох виразів, які були логічно-ANDed разом. Перші два твердження завжди є правдоподібними, а правила короткого замикання JS говорять про те, що всякий раз, коли перший є правдоподібним, поверніть все значення з правого боку (без примусу до булевого): тому це формально еквівалентно

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

Перше твердження повинно бути загорнене в дужки вище, оскільки оператор присвоєння =має нижчий пріоритет, ніж оператор логічного AND &&.

..."*"+vЗбірка "параметр відпочинку" також є частиною ES6; він об'єднує ведучий *до рядка, а потім інтерпретує його як список-схожий параметр, розділяючи його на купу аргументів, які надаються Array.prototype.splice, який бере (m, n, ...rest)і змінює свій масив у позиції mдля видалення nелементів, а потім вставляє всі restаргументи. Щоб досягти цього перед ES6, ви використовуєте більш громіздкі:

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

Потім масив об'єднується з порожнім рядком, а пробіли пробілів видаляються.


4

Python 2, 67 байт

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

Приймає введення як [('Heathrow', 0), ('Edinburgh', 2), ('London', 4), ('Liverpool', 6), ('Oxford', 8)]і друкує результат.

Python не дозволяє змінювати рядки, а перетворення до списку та з нього коштує дорого. Отже, це відтворює рядок, який zслід додати до нового слова. Ми беремо bсимволи перед словом, прошиваючи пробілами, якщо потрібно, потім новий текст зірочкою, потім частину zпісля нового слова. Зауважте, що пробіли ніколи не додаються.

reduceВерсія 3 символів більше (70):

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

3

Рубі, 94 81 75 байт

Гольф:

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

Ось код, який не використовується для гольфу:

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

Дякуємо @ w0lf за пропозиції щодо відображення вводу!

Дякую @ w0lf і @Не, що Чарльз за думку про видалення змінної.


Дивіться поради щодо гольфу в Ruby . У цьому випадку ви можете застосувати $ <. Map {| l | ...} коротше, ніж l = отримує; ...; кінцевий наконечник і, ймовірно, замінити puts на $><<(що не потребує додаткового місця).
Крістіан Лупаску

також, я думаю, .chompможна видалити.
Крістіан Лупаску

У цьому випадку, тепер, коли ви це згадуєте, я вважаю, що це, ймовірно, дуже безпечно видалити, оскільки .to_iце вловлює. Гарна думка. Дякую @ w0lf!
PotatoOmeletteSandwich

Ласкаво просимо! Ось коротша версія, в якій я застосував поради, наведені вище, та ще кілька: ideone.com/BiOvV5 . Не соромтеся розмістити його у своїй відповіді, якщо вам це подобається.
Крістіан Лупаску

3
@PotatoOmeletteSandwich Оновіть свій Ruby. 1.8.7 закінчено! також ви повинні мати можливість використовувати s[int, int]форму замість s[range]1 заощадження.
Не те, що Чарльз

3

Javascript 121 символів

Використовуючи нестандартні функції, працює на 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()

Старіша версія: 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
/ +/ має набагато більше сенсу, ніж \sрозчарований, я пропустив це! Чи можете ви зберегти байти, використовуючи x=' '.repeat(255);та уникаючи .join?
Дом Гастінгс

1
@DomHastings: рядки JS незмінні, тому вам доведеться .split('')перетворити їх у структуру даних, що змінюється , але в цей момент Array(255).fill(' ')коротша. У моїй версії більшість моїх заощаджень надходить з (а) за допомогою правила "ви можете надати функцію або програму" для видалення eval(prompt())в обмін на c=> (б), використовуючи вбудований Array.prototype.sliceметод з параметром відпочинку, щоб трохи скоротити логічну частину .
CR Drost

1
@ChrisDrost ну, звичайно ... я забуваю, що це просто аксесуар! Ганьба [].map.call(s[0],не врятує жодного ...
Дом Гастінгс

2

Пітон, 85 байт

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

Спробуйте в Інтернеті


1
Ви повинні мати можливість робити 'z'[2::5](зворотні посилання замість апостроф) замість того, ''.join(z)щоб зберегти один байт, а перехід z=[' ']*256до параметрів повинен зберегти інший. Крім того , я думаю , що ви можете змінити returnв print.
Кейд

Я думаю, що ви можете зберегти символи, записавши програму з p=input()(Python 2), а не функцію, що дозволяє уникнути відступу. Також, b+len(a)+1може бутиb-~len(a)
xnor

1
Насправді програма просто дозволяє вам це робити for a,b in input():.
xnor

2

Perl, 66 байт

63 байти сценарій + 3 байти для -p

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

Нічого особливого, використовуючи змінні $`і $'які не є «перед матчем» і «після матчу» відповідно, замість поділу стрічки. Я використовував $}для струнної змінної, так як спочатку це економило мені байт, але вже не!

Приклад виконання:

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

Perl, 65 байт

62 байти сценарій + 3 байти для -p

Ще одна версія, яка друкує кожен рядок (на один менший байт!) (Так, я зробив це, тому що я неправильно не прочитав питання ...)

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

Приклад виконання:

$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 байти

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

Для позиціонування курсору використовуються коди аварійних відбітків ANSI ( \x1b[XGіз символом Escape і X є координатою на основі 1), а *потім вводиться рядок введення для цього рядка. Приймає введення в командному рядку форми:

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

Приймає записи з кількома словами, якщо вони є в лапках, оскільки вони є аргументами командного рядка.


1

C ++ 11, 95 байт

Чому ні?

Як функцію, прийміть введення як map<int, string>ім'я, vщо містить позицію та рядок.

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

Використання

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

Перевірте, чи працює тут

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.