* Overwrit * этикетки


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 19.10.15

3
@PotatoOmeletteSandwich Мое намерение состояло в том, чтобы общая длина подходила в пределах 255, поэтому максимальная выходная длина будет иметь место, когда есть метка длины 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
Это намного лучше, чем у меня было.
Исаак

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трех выражений, которые были логически объединены. Первые два утверждения всегда верны, и правила короткого замыкания 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
})

Первый оператор должен быть заключен в скобках выше , потому что оператор присваивания =имеет более низкий приоритет , чем логический И-оператор &&.

Сборка «Параметр отдыха» ..."*"+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 байт

Golfed:

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 и @ Не, что Чарльз за мысль об удалении переменной.


Смотрите советы по игре в гольф . В этом случае вы можете применить $ <. Map {| l | ...} короче, чем в то время, как l = gets; ...; end tip и, возможно, заменить puts на $><<(что не требует дополнительного пробела).
Кристиан Лупаску

Кроме того, я думаю, .chompмогут быть удалены.
Кристиан Лупаску

В этом случае, теперь, когда вы упомянули это, я думаю, что это, вероятно, очень безопасно удалить, поскольку .to_iпоймает это. Хорошая мысль. Спасибо @ w0lf!
картофельный омлет сэндвич

Пожалуйста! Вот более короткая версия, в которой я применил приведенные выше советы, и еще несколько: 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метода с параметром rest, чтобы немного сократить логическую часть ,
CR Drost

1
@ChrisDrost ну конечно ... я забыл, что это просто аксессуар! Стыд [].map.call(s[0],тоже не спасает ...
Дом Гастингс

2

Python, 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.