重叠的字符串块


22

挑战:

给定多行字符串的列表,将它们重叠(在左上角)并输出结果。

例:

输入:["aaaa\naaaa\naaaa\naaaa","bb\nbb\nbb","c"]
输出:

cbaa
bbaa
bbaa
aaaa

挑战规则:

  • 输入格式灵活。允许您以2D行列表(即[["aaaa","aaaa","aaaa","aaaa"],["bb","bb","bb"],["c"]])或3D字符列表(即)获得输入[[["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字符列表。但前提是您的语言完全没有字符串。)
  • 输入列表的顺序当然很重要(但是,如果选择这样做,则可以反向输入)。
  • 输入将只包含在Unicode范围可打印ASCII [33,126]!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)。
  • 输入将仅是矩形(因此没有奇怪的形状)。不过,输出不是必需的矩形。
  • 尾随空格和单个尾随换行符是允许的。前导空格和/或换行符不行。

一般规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您发布使用非代码高尔夫球语言的答案。尝试针对“任何”编程语言提出尽可能简短的答案。
  • 标准规则适用于具有默认I / O规则的答案,因此允许您使用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是的,为什么不呢。只要输出的其余部分没有任何前导空格/换行符。尾随的换行符/空格并不是很重要,因此可以选择添加。
凯文·克鲁伊森

Answers:


6

果冻,3个字节

a/Y

在线尝试!

一段时间没有使用Jelly,但我认为评论中的挑战是可战胜的。非常直接地使用逻辑和(a)在输入(/)的每个元素之间执行堆栈操作。Y用于以所需的格式打印。


很好!我对果冻汤很不好。我准备的解决方案是ḷ""/Y使用反向输入列表。甚至都不知道a..
Kevin Cruijssen

11

JavaScript(Node.js),24字节

@Grimy节省了2个字节

假定返回的字符串打印在支持ANSI转义码的终端上。包含不可打印的字符ESC\x1B如下所示进行了转义(无双关)。

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

这不适用于TIO,但您可以在线尝试!而是查看原始输出。

怎么样?

使用的CSI序列为:

  • ED(显示擦除):

    ESC[2J

    其中2表示“清除整个屏幕”

  • CUP(光标位置):

    ESC[H

    这意味着“将光标移动到第n行,第m列”,其中nm均被省略,并隐式设置为1(屏幕的左上角)。

输出示例

输出


假设符合ECMA-48的终端,您都可以省略;。另外,我认为这应该是“ JavaScript +终端”或与纯JavaScript不竞争的类似内容。
6

@肮脏的谢谢!(对于任何有兴趣的人,这里是ECMA-48规范 -但我没有发现在哪里提到可以省略分号-如果完全提到的话。)
Arnauld

1
5.4.2.h的措词有些混乱,但有趣的是:if the last parameter sub-string(s) is empty, the separator preceding it may be omitted。由于只有两个子字符串,因此最后一个子字符串之前的分隔符是唯一的,可以省略。
6

我不知道ANSI,但是第一个\x1B[H+是必需的吗?它不是默认情况下从左上角开始,您只需要在每次输入后重置它(这就是联接的作用)吗?还是默认情况下它最初是从其他地方开始,并且您必须显式地使其从该光标位置开始才能成功重置为联接中的那个位置?
凯文·克鲁伊森

1
@Arnauld因为执行此功能时终端上可能总会有其他东西,所以我想毕竟需要初始重置。至于省略打印,我猜测f=a=>print(`\x1B[H`+a.join`\x1B[H`)with f(input_here)会产生与print(f(input_here))?相同的输出。因此,我不明白为什么不允许您省略print和仅返回一个字符串。
凯文·克鲁伊森

7

[R 120111个 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
朱塞佩

@Giuseppe:整齐!
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)

然后将这些行中的每一行过滤到Noneremove,并再次压缩:

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“返回字符串列表”,规则状态为“输出格式严格。您可以选择打印或返回多行字符串。不允许使用2D或3D列表作为输出。”。88字节的完整程序似乎很好
乔纳森·艾伦

@JonathanAllan,亲爱的,我看错了严格的输出(或忘记了?:p)
TF场

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中进行测试
Giuseppe

@Giuseppe嗨!你的建议对我有用。如果允许我们打印尾随的换行符,也可以只使用任意大的for循环来代替,但是我想这正挑战着极限。
JAD

@JAD:使用的好主意\r,欢迎回来!请注意,我认为这仅在交互式R会话中有效(当interactive()返回true时)
digEmAll

@digEmAll从命令行在我的机器上工作rscript。我怀疑这是Windows / Linux,因为Windows \r\n用于换行符和Linux \n
JAD

4

APL(Dyalog Unicode),22 字节SBCS

以2D字符数组列表为参数的匿名默认前缀函数。印刷品。

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

在线尝试!

通过创建画布,然后将其附加到块列表中,并使用将块放置在角落的功能进行缩小(折叠),可以实现此目的。

 混合2D块以创建正交3D块,并根据需要用空格填充

1⌷ 拿第一层

 围起来,
 然后
⌽, 在反向块列表之前

() 应用以下默认功能:

{}/ 减少使用以下匿名lambda:

  ⊢⍵ 以正确的论点作为画布…

  ⍺@(...... ) 与左说法,放置的内容修改以下指标:

   ⍴⍺ 左参数的形状

   那个形状的数组 的基数

 披露(因为附带的减少数降低了等级)


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个字节

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的解决方案是仍然使用带print的map / filter作为隐式y,相比于vy...,:) 节省一个字节:)我知道这在旧版本中有效,但是在新版本中它也会输出[...]。不知道那是由于缺少--no-lazy。;)至于答案本身,非常好!我知道有必要进行累计减少,但是当我自己尝试时无法真正解决。你使它看起来那么容易..
凯文Cruijssen

我在规则中提到了它,但是忘记将其应用于测试用例..但是输入中不会包含空格。因此,由于zip-filler默认为空格,因此您可能会在其中保存一些字节。(不确定是否可以在您的第一个答案中保存任何内容,但可以在端口中保存它。)
Kevin Cruijssen

2
õζεõK可以ζεðKõζõδK可以ζðδK
Grimmy

@Grimy:哦,是的,输入中不能再有空格。谢谢!
Emigna



2

PowerShell 6(仅控制台),20字节

根据Arnauld的答案。该功能仅适用于控制台,不适用于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

Ruby,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)

无论如何,它要做的是先拆分所有字符串,然后反转所有字符串,然后循环进入reduce操作面板将所有字符串一起启动。然后再次反转所有字符串,然后使用换行符将它们重新连接在一起。

特别感谢Kevin Cruijssen提醒我,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
两者都('')可以是两个`,以保存四个字节:)
Kevin Cruijssen

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语句if(!...)j=b[i];(,...(j=a[i]),因此为的更新值j),然后;a[i]=b[i++].padStart(j.length,j))在for循环迭代的末尾完成。似乎有效?
凯文·克鲁伊森

1
ooohhh ...... *大眼睛*解锁了某些东西
Tschallacka

1
顺便说一句,如果您还没有看到它们,那么<all language> 打高尔夫的技巧JavaScript打高尔夫的技巧可能都很有趣。:)
Kevin Cruijssen

1

C(gcc)51 47字节

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

在线尝试!

--4个字节,感谢ceilingcat。

使用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查询,297295字节

使用¶作为分隔符,并使用表变量作为输入。

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`}

感谢Kevin Cruijssen节省了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-谢谢,我更新了我的帖子!发布前,我阅读了这两个指南,它们都很有用。但我可能会错过一些技巧,这些技巧可能会进一步改善我的尝试!
凯文Bibollet

1
我想念的第=(r[l])?=r[l]?
一句话中还有

1
@KévinBibollet,需要它来返回的最终结果r。如果没有它,则将返回映射结果。
毛茸茸的

1
但是,如果您保留测试用例中使用的I / O格式,则仍然可以减少到85个字节,但应注意I / O是灵活的。
毛茸茸的

1

Pyth,18个字节

L.tb0VyQsme #dy #N

在线尝试!(注意:代码本身仅评估一个块,解释器的测试套件模式为输入的每一行运行一次程序)

基于TFeld的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的答案。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.