Перекрывающиеся струнные блоки


22

Вызов:

Получив список многострочных строк, наложите их (слева вверху) и выведите результат.

Пример:

Вход: ["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]
Выход:

cbaa
bbaa
bbaa
aaaa

Правила соревнований:

  • Формат ввода гибкий. Вам разрешено получать входные данные в виде двухмерного списка строк (т.е. [["aaaa","aaaa","aaaa","aaaa"],["bb","bb","bb"],["c"]]) или трехмерного списка символов (т.е. [[["a","a","a","a"],["a","a","a","a"],["a","a","a","a"],["a","a","a","a"]],[["b","b"],["b","b"],["b","b"]],[["c"]]]). Вам разрешено принимать все входы один за другим через STDIN. И т.п.
  • Формат вывода строгий. Вы можете распечатать или вернуть многострочную строку. (Если на вашем языке нет строк, вывод в виде 2D-списка символов допускается в качестве альтернативы. Но только если на вашем языке вообще нет строк.)
  • Порядок ввода-списка, конечно, важен (но вы можете принимать входные данные в обратном порядке, если захотите).
  • Входы будут содержать только ASCII для печати в диапазоне Unicode [33,126] ( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~).
  • Входные данные будут только прямоугольниками (поэтому никаких странных форм). Выходные данные не являются необходимыми прямоугольниками, хотя.
  • Конечные пробелы и один завершающий перевод строки разрешены. Ведущие пробелы и / или переводы строк не.

Основные правила:

  • Это , поэтому выигрывает самый короткий ответ в байтах.
    Не позволяйте языкам кода-гольфа отговаривать вас от публикации ответов на языках, не относящихся к кодексу. Попробуйте придумать как можно более короткий ответ для «любого» языка программирования.
  • Стандартные правила применяются к вашему ответу с правилами ввода / вывода по умолчанию , поэтому вам разрешено использовать STDIN / STDOUT, функции / метод с правильными параметрами и типом возврата, полные программы. Ваш звонок.
  • По умолчанию лазейки запрещены.
  • Если возможно, добавьте ссылку с тестом для вашего кода (например, TIO ).
  • Кроме того, добавление объяснения для вашего ответа настоятельно рекомендуется.

Тестовые случаи:

Вход: ["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]
Выход:

cbaa
bbaa
bbaa
aaaa

Вход: ["12345\n54321","00\n00\n00\n00","001\n011\n012"]
Выход:

00145
01121
012
00

Вход: ["sm\noo\nmr\nee\nt!\nh_\ni_\nn_\ng_","!@#$%^\n&*()_+\nqwerty\nuiopas","this\nis_a\ntest"]
Выход:

this%^
is_a_+
testty
uiopas
t!
h_
i_
n_
g_

Разрешены ли конечные переводы строки? Или, более конкретно, разрешено ли произвольное количество конечных строк?
JAD

@JAD Да, конечно, почему бы и нет. Пока остальное выводится без пробелов / переносов. Конечные символы новой строки / пробелы на самом деле не важны, поэтому их можно добавить.
Кевин Круйссен

Ответы:


6

Желе , 3 байта

a/Y

Попробуйте онлайн!

Давно не пользовался желе, но я думал, что вызов в комментариях можно преодолеть. Очень напрямую использует логические и ( a) для выполнения операции стекирования между каждым элементом ввода ( /). Yиспользуется для печати в требуемом формате.


Ах, хорошо! Я плохо себя чувствую с Jelly TBH. Мое готовое решение было ḷ""/Yс обратным списком ввода. Даже не знал о a..
Кевин Круйссен

11

JavaScript (Node.js) , 24 байта

Сохранено 2 байта благодаря @Grimy

Предполагается, что возвращенная строка печатается на терминале, который поддерживает управляющие коды ANSI . Содержит непечатный символ ESC, который экранирован (без каламбура), как \x1Bпоказано ниже.

a=>`\x1B[2J\x1B[H`+a.join`\x1B[H`

Это не работает на TIO, но вы можете попробовать это онлайн! чтобы увидеть сырой выход вместо этого.

Как?

Используемые последовательности CSI :

  • ED (Стереть на дисплее):

    ESC[2J

    где 2 означает «очистить весь экран»

  • CUP (Положение курсора):

    ESC[H

    что означает «перемещает курсор в строку n , столбец m », где n и m опущены и неявно установлены в 1 (левый верхний угол экрана).

Пример вывода

выход


Предполагая, что терминал совместим с ECMA-48, вы можете опустить оба ;. Кроме того, я думаю, что это должен быть «JavaScript + терминал» или что-то подобное, что не конкурирует с чистым JavaScript.
Grimmy

@ Грими Спасибо! (Для тех, кто заинтересован, вот спецификация ECMA-48 - но я не нашел, где упоминается, что точка с запятой может быть опущена - если она вообще упоминается.)
Арно

1
5.4.2.h несколько смутно сформулированный, но интересные бит: if the last parameter sub-string(s) is empty, the separator preceding it may be omitted. Поскольку есть только две подстроки, разделитель, предшествующий последней подстроке, является единственным, и его можно опустить.
Grimmy

Я не знаю ANSI, но \x1B[Hнужен ли первый +? Разве это не начинается с верхнего левого угла по умолчанию, и вам нужно только сбросить его после каждого ввода (что делает объединение)? Или он изначально запускается где-то еще по умолчанию, и вы должны явно позволить ему начать с той позиции курсора, чтобы он успешно вернулся в эту позицию в соединении?
Кевин Круйссен

1
@Arnauld Поскольку при выполнении этой функции у вас, вероятно, всегда будет что-то еще на терминале, я думаю, что первоначальный сброс все-таки требуется. Что касается ommitting печати, я думаю , f=a=>print(`\x1B[H`+a.join`\x1B[H`)с f(input_here)будет производить тот же результат , как print(f(input_here))? Так что я не понимаю, почему вы не можете опустить printи просто вернуть строку.
Кевин Круйссен

7

р , 120 , 111 110 107 байтов

function(x,`!`=ncol,M=array('',Reduce(pmax,Map(dim,x)))){for(m in x)M[1:!t(m),1:!m]=m
write(t(M),1,!M,,'')}

Попробуйте онлайн!

Функция, принимающая список матрицы символов (допускается ввод 3D).

(как вы можете заметить по количеству байтов, это не очень легко сделать в R ...)

  • -9 байт благодаря @Giuseppe
  • -4 байта благодаря @RobinRyder

4
Я действительно ожидал 200+ байтовое решение! Я получу эту милую награду, когда этот вопрос станет вознаграждением
Джузеппе

@Giuseppe: все еще намного дольше, чем другие языки ... :(
digEmAll

2
111 байтов использую arrayвместо matrix!
Джузеппе

@ Джузеппе: аккуратно!
digEmAll

3
107 с псевдонимом для ncol(вы можете транспонировать, чтобы получить nrow).
Робин Райдер

5

Python 2 , 88 байт

n,f=None,filter
for l in map(n,*input()):print''.join(f(n,x)[-1]for x in map(n,*f(n,l)))

Попробуйте онлайн!


Пояснение (с примером):

Принимает 2D-список в качестве входных данных.

Input: [["12345","54321"],["00","00","00","00"],["001","011","012"]]

Сначала входной список архивируется, чтобы получить строки каждого входного прямоугольника ( map(None,l)это же самое длиннее zip):

map(n,*input())   gives:

('12345', '00', '001')
('54321', '00', '011')
(None, '00', '012')
(None, '00', None)

Каждая из этих строк затем фильтруется для удаления Nones и снова архивируется:

map(None,*filter(None,l))

filter(None,l) for each l gives:

('12345', '00', '001')
('54321', '00', '011')
('00', '012')
('00',)

map*... gives:

[('1', '0', '0'), ('2', '0', '0'), ('3', None, '1'), ('4', None, None), ('5', None, None)]
[('5', '0', '0'), ('4', '0', '1'), ('3', None, '1'), ('2', None, None), ('1', None, None)]
[('0', '0'), ('0', '1'), (None, '2')]
['0', '0']

Какой список символов для каждой позиции желаемого результата. Эти списки снова фильтруются, и последний берется:

filter(None,x)   gives:

[('1', '0', '0'), ('2', '0', '0'), ('3', '1'), ('4',), ('5',)]
[('5', '0', '0'), ('4', '0', '1'), ('3', '1'), ('2',), ('1',)]
[('0', '0'), ('0', '1'), ('2',)]
['0', '0']

and with [-1]:

['0', '0', '1', '4', '5']
['0', '1', '1', '2', '1']
['0', '1', '2']
['0', '0']

Наконец, полученные списки объединяются и печатаются:

print''.join(..)

00145
01121
012
00

RE «Возвращает список строк», правила гласят: «Формат вывода строгий. Вы можете распечатать или вернуть многострочную строку. Двух- или трехмерные списки в качестве выходных данных не допускаются». 88-байтная полная программа выглядит неплохо
Джонатан Аллан

@JonathanAllan, привет, я неправильно прочитал строгий вывод (или забыл?: P)
TFeld

5

R 107 97 байт

function(x)for(i in 1:max(lengths(x))){for(m in x)if(i<=length(m))cat(m[i],'\r',sep='');cat('
')}

Похоже, не работает на TIO, что может быть связано с использованием \r символа возврата каретки. Это работает на моей локальной установке R.

Принимает ввод как список, содержащий вектор строк:

x <- list(c("aaaa","aaaa","aaaa","aaaa"),c("bb","bb","bb"),c("c"))

Зацикливает строки каждого прямоугольника, печатая возврат каретки после каждого, перезапуская строку.

Если мы немного растянем правила, мы можем покончить с проверкой длины ввода и просто зацикливаться бесконечно, печатая огромное количество новых строк:

R 85 байт

function(x)for(i in 1:8e8){for(m in x)if(i<=length(m))cat(m[i],'\r',sep='');cat('
')}

106 байт Приятно видеть, что вы играете в гольф здесь и там!
Джузеппе

Возможно 97 байт ; неясно, работает ли это на самом деле, так как я тестирую только в TIO
Джузеппе

@ Джузеппе Привет! Ваше предложение работает для меня. Если нам разрешено печатать завершающие символы новой строки, то вместо этого можно просто использовать произвольно большой цикл for, но я полагаю, что это расширяет границы проблемы.
JAD

@JAD: отличная идея \r, и добро пожаловать обратно! Просто заметьте, я думаю, что это работает только в интерактивных R сессиях (когда interactive()возвращает true)
digEmAll

@digEmAll Это работает на моей машине, используя rscriptиз командной строки. Я подозреваю, что это вещь Windows / Linux, так как Windows использует \r\nдля перевода строки и Linux \n.
JAD

4

APL (Dyalog Unicode) , 22 байта SBCS

Функция анонимного неявного префикса, принимающая список двумерных массивов символов в качестве аргумента. Печать.

(⊃{⍺@(⍳⍴⍺)⊢⍵}/)⌽,∘⊂1⌷↑

Попробуйте онлайн!

Это работает, создавая холст, затем добавляя его в список блоков, и уменьшая (сворачивая) с помощью функции, которая помещает блоки в угол.

 смешайте 2D-блок, чтобы создать ортогональный 3D-блок, заполняя их пробелами по мере необходимости

1⌷ взять первый слой

 заключите это,
 затем
⌽, добавьте обратный список блоков

() Применить следующую молчаливую функцию:

{}/ Уменьшить, используя следующую анонимную лямбду:

  ⊢⍵ с правильным аргументом как холст ...

  ⍺@(… Дополнить ) элементами левого аргумента, расположенными по следующим индексам:

   ⍴⍺ форма левого аргумента

    в ɩ ndices массива этой формы

 раскрыть (потому что сокращение прилагается, чтобы снизить ранг)


4

Haskell, 66 байт

unlines.foldl((const?)?)[]
(g?(a:b))(c:d)=g a c:(g?b)d;(_?a)b=a++b

Входные данные принимаются в виде списка строк в обратном порядке, например, для первого теста: [["c"],["bb","bb","bb"],["aaaa","aaaa","aaaa","aaaa"]] .

Попробуйте онлайн!


3

05AB1E , 12 байтов

Решение Python для порта TFeld
2 байта сэкономлено благодаря Грими

ζεðKζðδK€θJ,

Попробуйте онлайн!

объяснение

ζ             # transpose input with space as filler
 ε            # apply to each
  ðK          # remove spaces
    ζ         # transpose with space as filler
     ðδK      # deep remove spaces
        €θ    # get the tail of each
          J   # join each
           ,  # print

Альтернативная 14-байтовая версия

õζεÅ»DŠg.$J}θ,

Попробуйте онлайн!

объяснение

õζ              # zip with empty string as filler
  ε             # apply to each
   Å»      }    # cumulative reduce by
     D          # duplicate second input
      Š         # move down twice on stack
       g.$      # remove len(other_copy) elements from the other input
          J     # join with other copy
            θ,  # print the last element

1
О, нужно помнить, что --no-lazyэто исправление, чтобы по-прежнему использовать карту / фильтр с печатью для неявного y, чтобы сохранить байт по сравнению с vy...,:) Я знал, что это работало в устаревшей версии, но в новой версии это также вывело бы [...], Не знал, что это из-за отсутствия --no-lazy. ;) Что касается самого ответа, очень приятно! Я знал, что кумулятивное снижение было необходимо, но не мог действительно решить это, когда я попробовал это сам. Вы делаете это выглядит так просто ..
Кевин Круйссен

Я упомянул это в правилах, но забыл применить его к контрольным случаям ..., но пробелы не будут во входных данных. Таким образом, вы, вероятно, можете сохранить некоторые байты там, поскольку zip-заполнитель по умолчанию является пробелом. (Не уверен, что в первом ответе что-то сохраняется, но в порту это возможно.)
Кевин Круйссен,

2
õζεõKможет быть ζεðK, õζõδKможет быть ζðδK.
Grimmy

@Grimy: О да, пробелы больше не могут быть на входе. Благодарность!
Эминья



2

PowerShell 6 , только консоль, 20 байт

основываясь на ответе Арно . Это работает только с консолью и не работает на TIO.

cls
$args-join"`e[H"

Попробуйте онлайн!


PowerShell , 103 байта

$args|%{$l=$_-split'
';$r=&{$r+($l|%{''})|%{($x=$l[$j++])+($_-replace"^.{0,$("$x"|% Le*)}")}|?{$_}}}
$r

Попробуйте онлайн!

раскатали:

$args|%{
    $l=$_-split"`n"
    $r=&{                           # run this scriptblock in a new scope
        $r+($l|%{''})|%{
            $x=$l[$j++]             # a new line or $null
            $w="$x"|% Length
            $y=$_-replace"^.{0,$w}" # remove first chars from the current line
            $x+$y                   # output the new line plus tail of the overlapped line
        }|?{$_}                     # filter out not empty lines only
    }                               # close the scope and remove all variables created in the scope
}
$r


1

Рубин , 67 байт

Ввод - это список строк. Создает список строк и выполняет перезапись при прохождении через входы, а затем соединяет их с новой строкой (представленной переменной $/) в конце, чтобы соответствовать строгому выводу.

->i,*r{i.map{|e|j=-1;e.map{|l|r[j+=1]||='';r[j][0,l.size]=l}};r*$/}

Попробуйте онлайн!


1

C (GCC, MinGW) 138 байтов

Предполагается, что CR помещает курсор в начало текущей строки.

d,i,l;f(S,n,p,t)char**S,*p,*t;{for(d=i=0;i<n;d+=l)p=strchr(t=S[i],10),printf("\n%.*s\r"+!!i,l=p?p-t:strlen(t),t),S[i++]+=l+!!p;d&&f(S,n);}

Протестировано с:

int main()
{
    char *test1[] = {"aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"};
    char *test2[] = {"12345\n54321","00\n00\n00\n00","001\n011\n012"};
    char *test3[] = {"sm\noo\nmr\nee\nt!\nh_\ni_\nn_\ng_","!@#$%^\n&*()_+\nqwerty\nuiopas","this\nis_a\ntest"};

    f(test1, 3);
    f(test2, 3);
    f(test3, 3);
}


1

Javascript (браузер) , 216 208 204 байта

Моя попытка в этом. Я не в восторге от размера, и наверняка должно быть что-то еще для улучшения, но я не настолько опытен в игре в гольф.

var n='\n',x=s=>s.split``.reverse().join``,i,j,f=a=>a.map(s=>s.split(n).map(y=>x(y))).reduce((a,b)=>{for(i=0;i<b.length;i++){j=a[i];if(!j)j=b[i];a[i]=b[i].padStart(j.length,j)}return a}).map(s=>x(s)).join(n)

В любом случае, то, что он делает, это сначала разбивает все строки, затем переворачивает все строки, а затем выполняет цикл в операции сокращения. переворачивает padStart. все все строки вместе. Затем снова переверните все строки, а затем соедините их с помощью новых строк.

Отдельное спасибо Кевину Круйссену за напоминание о том, что последняя часть цикла for происходит в конце, и общая экономия байтов составляет 8 байтов.

var n='\n',x=s=>s.split``.reverse().join``,i,j,f=a=>a.map(s=>s.split(n).map(y=>x(y))).reduce((a,b)=>{for(i=0;i<b.length;a[i]=b[i++].padStart(j.length,j))if(!(j=a[i]))j=b[i];return a}).map(s=>x(s)).join(n)

console.log(f(["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]));
console.log(f(["12345\n54321","00\n00\n00\n00","001\n011\n012"]));
console.log(f(["sm\noo\nmr\nee\nt!\nh_\ni_\nn_\ng_","!@#$%^\n&*()_+\nqwerty\nuiopas","this\nis_a\ntest"]));


1
Оба ('')могут быть два `, чтобы сохранить четыре байта :)
Кевин Круйссен

1
Кроме того , вы можете заменить for(i=0;i<b.length;i++){j=a[i];if(!j)j=b[i];a[i]=b[i].padStart(j.length,j)}с for(i=0;i<b.length;a[i]=b[i++].padStart(j.length,j))if(!(j=a[i]))j=b[i];.
Кевин Круйссен

1
jСначала присваивается (j=a[i]), то если-заявление сделано с if(!...)j=b[i];(где... это (j=a[i]), так обновленной стоимости j), и затем ;a[i]=b[i++].padStart(j.length,j))выполняется в конце итерации для цикла .. Не знаете , где проблема, и это похоже на работу?
Кевин Круйссен

1
ооооооооооооооооо ... * большие глаза * что-то
открыли

1
Кстати, если вы еще не видели их, советы по игре в гольф на <все языки> и советы по игре в гольф на JavaScript могут быть интересными для чтения. :)
Кевин Круйссен

1

C (gcc) , 51 47 байтов

f(char**s){for(;*s;printf("\e[s%s\e[u",*s++));}

Попробуйте онлайн!

-4 байта благодаря потолку.

Использует последовательности CSI для сохранения / восстановления позиции курсора. Просто перебирает переданный массив строк (в том же формате, что и argv) и печатает<save position>string<restore position> для каждого.

При этом курсор остается в левом верхнем углу, поэтому при работе на терминале важно оставить после себя достаточно новых строк, чтобы подсказка не загромождала ввод.


1

Japt -P , 7 байт

Принимает ввод как массив многострочных строк, выводит одну многострочную строку.

ú y_¸¬Ì

Попытайся

ú y_¸¬Ì     :Implicit input of array
ú           :Right pad each line of each element with spaces to the length of the longest
  y         :Transpose
   _        :Map
    ¸       :  Split on spaces
     ¬      :  Join
      Ì     :  Last character
            :Implicitly join and output

1

T-SQL запрос, 297 295 байт

Использование ¶ в качестве разделителя и табличной переменной в качестве ввода.

DECLARE @ table(a varchar(max),k int identity(1,1))
INSERT @ values('aaaa¶aaaa¶aaaa¶aaaa'),('bb¶bv¶bb'),('c');

WITH c as(SELECT k,row_number()over(partition
by k order by k)s,value v FROM @ CROSS APPLY
string_split(a,'¶')s),m(i,l,e)as(SELECT*FROM c
WHERE k=1UNION ALL
SELECT k,s,STUFF(e,1,len(v),v)FROM m
JOIN c ON-~i=k and s=l)SELECT
top 1with ties e FROM m
ORDER BY rank()over(partition by l order by-i)

Попробуйте онлайн


1

Javascript (браузер), 129 124 байта

Моя первая попытка игры в гольф. Я читаю ссылки, приведенные в правилах (лазейки, стандартные правила ...), поэтому надеюсь, что сделал что-то не так!


Я сохранил входные данные, как они есть в первом посте (форма плоского массива).

_=o=>{o=o.map(i=>i.split`\n`),r=o.shift();for(a of o)for(l in a)b=a[l],r[l]=r[l]?b+r[l].slice(b.length):b;return r.join`\n`}

Спасибо Кевину Круйссену за сохранение 5 байтов.


тесты:


1
Добро пожаловать в PPCG! Хороший первый ответ, +1 от меня. Некоторые мелочи в гольф: for(a of o){for(l in a){b=a[l],r[l]=(r[l])?b+r[l].slice(b.length):b}}может быть for(a of o)for(l in a)b=a[l],r[l]=r[l]?b+r[l].slice(b.length):b;:)
Кевин Круйссен

1
@KevinCruijssen - Спасибо, я обновил свой пост! Я прочитал эти два руководства перед публикацией, они оба были полезны. Но я, возможно, пропускаю некоторые трюки, которые могли бы улучшить мою попытку!
Кевин Биболле

1
Еще одна вещь из моего первого комментария, которую вы пропустили, - это круглые скобки, =(r[l])?которые можно удалить =r[l]?:)
Кевин Круйссен,

1
@ KévinBibollet, это нужно для того, чтобы вернуть окончательный результат r. Без этого результат сопоставления был бы возвращен вместо этого.
лохматый

1
Если вы хотите сохранить формат ввода-вывода, используемый в тестовых примерах, вы все равно можете уменьшить размер до 85 байт, но вам следует помнить, что ввод-вывод является гибким.
лохматый

1

Pyth , 18 байт

L.tb0VyQsme #dy #N

Попробуйте онлайн!(примечание: сам код оценивает только один блок, режим набора тестов интерпретатора запускает программу один раз для каждой строки ввода)

На основе решения TFeld's Python 2 .

Объяснение:

L.tb0         # define a lambda function called y which does a transpose, padding with integer 0's
VyQ           # loop over transposed first input line (Q = eval(input()) ) (loop index = N)
   s          # concatenate array of strings (implicitly printed)
    m         # map over
         y #N # transpose of non-falsy values of N
     e        # for each item: last element of array
       #d     # relevant space at the start! filter with identity function, removes falsy values

для объяснения того, почему сам алгоритм работает, см. ответ TFeld.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.