塑形的艺术


21

塑形的艺术

给定一个二进制矩阵和一个字母字符串,用该字符串的字母从左到右替换矩阵中的所有1。一旦字母形成矩阵的形状,就打印矩阵,用空格替换0。仅举一两个例子可能会更容易。


案例:基本案例...

输入一:

[0,0,1,0,0]
[0,1,0,1,0]
[1,0,0,0,1]
[0,1,0,1,0]
[0,0,1,0,0]

"PPCGPPCG"

输出一:

  P    
 P C  
G   P
 P C 
  G  

情况:如果输入字符串长于一个字符串...

输入二:

[1,0,0]
[0,1,0]
[1,0,1]

lambda

输出二:

l  
 a 
m b

情况:如果输入字符串短于一个数字...

输入三:

[1,1,1]
[1,0,1]
[1,1,1]

PPCG

输出三:

PPC
G P
PCG

可用假设

  • 您可能会假设输入字符串永远不会为空。
  • 您可能会假设矩阵永远不会为空。
  • 您可能不会假定二进制矩阵永远不会全为零。

规则

  • 如果字符串短于一个,则重复该字符串;否则,请重复该字符串。所有的都必须更换。
  • 如果字符串长于一个,则仅使用所需的字符串。
  • 您可以使用True / False代替整数/位作为输入。
  • 需要尾随空格,必须全部替换为零为空格。
  • 一条尾随的换行符是可以接受的。
  • 这是代码高尔夫球,最低字节数获胜。

是否必须将矩阵作为数组输入,或者我可以使用多行字符串?
泰特斯

@Titus很好,Martin Ender已经做到了。
魔术章鱼缸

基本情况不是从左到右。您是说从上到下,然后从左到右?
edc65 '16

1
例如,如果矩阵是一个2x2的零网格,那么我们应该输出一个空格还是2x2的网格?
人工

@ pieman2201清除了测试用例4,以使其更好。
魔术章鱼缸

Answers:


3

MATL,11个字节

yz:)1Gg!(c!

输入是一个数字矩阵(带有;行分隔符)和一个字符串。

在线尝试!或验证测试案例: 1 2 3

y       % Take the two inputs implicitly. Duplicate the first
        % STACK: [1,0,0; 0,1,0; 1,0,1], 'lambda', [1,0,0; 0,1,0; 1,0,1]
z       % Number of nonzeros
        % STACK: [1,0,0; 0,1,0; 1,0,1], 'lambda', 4
:       % Range
        % STACK: [1,0,0; 0,1,0; 1,0,1], 'lambda', [1 2 3 4]
)       % Reference indexing (select values)
        % STACK: [1,0,0; 0,1,0; 1,0,1], 'lamb'
1Gg     % Push first input as a logical matrix; will be used as index
        % STACK: [1,0,0; 0,1,0; 1,0,1], 'lamb', [1,0,0; 0,1,0; 1,0,1]
!       % Transpose. This is necessary because MATL uses column-major order
        % (down, then accross)
(       % Assignment indexing (fill with values). Since the original matrix
        % is numeric, the new values are introduced as their ASCII codes
        % STACK: [108, 0, 109; 0, 97, 0; 1, 0, 98]
c       % Convert to char
        % STACK: ['l m'; ' a '; '  b']
!       % Transpose back. Implicitly display
        % STACK: ['l  '; ' a '; 'm b']

MATL基本上重新定义了我一直看过的收藏的方式...
Magic Octopus Urn

@carusocomputing像在Matlab中一样,主要数据类型是“矩形”数组:矩阵或其n维类似物。它们可以包含数字,字符或布尔值。还有一些单元格数组,可以包含任意内容,例如Python的列表
Luis Mendo

打开2周后选择最佳答案。
魔术章鱼缸

8

Vim,44 42字节

qqy$P0xjf1"_xP{@qq@q:s/0/ /g^M:s/,/^V^M/g^M{D

@DjMcMoylex节省了2个字节

在这里,^M是文字换行,并且^VCTRL-V

接受以下格式的输入:

PPCG
00100,01010,10001,01010,00100

免责声明:如果字符串的长度超过〜40个字符,则您的计算机可能用完了ram。

说明:

qq             @qq@q                            # Start recording a recursive macro.
  y$P0x                                         # Duplicate the string and cut out the first character
       jf1"_xP{                                 # Find the first 1, and replace it with the cut character from the string.
                                                # Now we have replaced all the 1's with their respective character, but we still have the array in the original format, and we have the string massivly duplicated at the first line, so we need to clean it up:
                    :s/0/ /g^M                  # Replace all 0's with a space
                              :s/,/^V^M/g^M     # Replace all ,'s with a newline. The ^V acts like a backslash, it escapes the newline so that the command isn't run too soon
                                           {D   # Delete the first line

这是我“运行”“程序”的一个gif图像:

Me typing the keys


1
哈哈哈,爱的免责声明。
魔术章鱼缸

您可以使用{来代替gg一对。
DJMcMayhem

好的,gif确实很整洁,但是您认为可以仅通过链接将其包括在内吗?每当我尝试滚动浏览时,它就会落后于我的浏览器:(
wnnmaw

6

视网膜41 33字节

0

+1`(.)(.*)(\D+)1
$2$1$3$1
A1`

在线尝试!

输入字符串在输入的第一行给出,后跟矩阵。由于Retina没有列表(或字符串以外的任何东西)的概念,因此二进制矩阵中没有分隔符,除了用于分隔行的换行符。

说明

0

将零变成空格。

+1`(.)(.*)(\D+)1
$2$1$3$1

重复用1输入字符串的第一个字符替换第一个字符,同时还将该字符旋转到输入字符串的末尾。这要注意以下情况:1输入字符串中的s大于字符。

A1`

丢弃第一行,即输入字符串。


2
(.)(.*)-Teehee ...
魔术八达通

6

JavaScript的ES6,67 53 50 49字节

@ETHproductions节省了3个字节@Neil节省了1个字节

(a,b,i)=>a.replace(/./g,c=>+c?b[++i]||b[i=0]:' ')

f=
(a,b,i)=>a.replace(/./g,c=>+c?b[++i]||b[i=0]:' ')

G=_=>h.innerHTML = f(`00100
01010
10001
01010
00100`,z.value)
h.innerHTML = G()
<input id=z oninput="G()" value="PPCG"></input>
<pre id=h>

在我知道字符串矩阵是有效的输入格式之前的旧代码:

(a,b)=>a.map(c=>c.map(d=>d?b[i++%b.length]:' ').join``,i=0).join`
`


我建议c=>' '[c]||b[i++%b.length],但可悲的是它要长一个字节...
ETHproductions's

1
但是,还有另一种节省3个字节的方式:(a,b,i)=>a.replace(/\d/g,c=>+c?b[++i]||b[i=0]:' ')
ETHproductions

我认为这将从字符串的第二个字符开始。摘要更新会很好。
泰特斯

1
@Titus起初iundefined,这样++i的回报NaN。由于b没有NaN属性,因此b[++i]返回undefined,并且||运算符运行其右侧参数,设置i0并返回中的第一个字符b
ETHproductions 2016年

1
你为什么要测试\d?当然.就足够了,因为你只需要对付0S和1S(.不匹配换行符)。
尼尔

5

Perl,40个字节

36个字节的代码+ -i -p标志。

@F=$^I=~/./g;s/1/$F[$i++%@F]/g;y;0; 

(请注意最后的空格和缺少最后的换行符)。

要运行它,请在-iflag 之后写入输入字符串,并在输入中提供矩阵:

perl -iPPCGPPCG -pe '@F=$^I=~/./g;s/1/$F[$i++%@F]/g;y;0; ' <<< "00100
01010
10001
01010
00100"

如果您的Perl有点旧,则可能需要添加最后一个分号(在空格之后)。


5

Python 2,114 71字节

原来我是在重新发明轮子,对多行字符串进行简单的双替换效果很好。字符串还有一个额外的好处,就是可以直接对零进行计数,而不必s*len(L)*len(L[0])为嵌套列表做真正的丑陋操作

lambda S,s:S.replace("0"," ").replace("1","{}").format(*s*S.count('0'))

旧解决方案:

lambda s,L:"\n".join(["".join(map(lambda n:chr(n+32),l)).replace("!","{}")for l in L]).format(*s*len(L)*len(L[0]))

首先,我们将所有+ 32转换为chr(所有零都变为空格),然后替换所有!with {}以允许使用该format函数。

如果NULL可以算作一个空格如果我决定作弊并使用它NULL代替空格,则可以跳过添加32来节省12个字节。(print显示'\x00'为空格)

lambda s,L:"\n".join(["".join(map(chr,l)).replace('\x01','{}')for l in L]).format(*s*len(L)*len(L[0]))

使用NULL,并在最后用空格替换它们会不会更短?
nedla2004 '16

@ nedla2004,您如何建议我这样做?只需.replace('\x00',' ')在末尾添加a即可添加20个字节
wnnmaw

但是,我认为您可以摆脱这种情况:map(lambda n:chr(n + 32),l)
nedla2004 16-11-15

第二种解决方案始终使用NULL,这可以节省12个字节,最后交换到空格将花费我更多的

我以为您可以删除的数量超出实际数量。
nedla2004 '16

3

APL,18个字节

{(⍴⍺)⍴X\⍵⍴⍨+/X←,⍺}

该函数将布尔矩阵作为左参数,将字符串作为右参数。

      (↑(1 0 0)(0 1 0)(1 0 1)) {(⍴⍺)⍴X\⍵⍴⍨+/X←,⍺}'lambda'
l  
 a 
m b

说明:

APL具有一个内置功能,可以执行以下操作\(扩展)。但是,它仅适用于矢量,并且需要实际使用每个字符。

  • X←,⍺:展平矩阵并将结果存储在X中。
  • ⍵⍴⍨+/X:调整字符向量的形状,使其具有所需数量的元素(如果需要,还可以通过重复字符来延长字符串的长度)。
  • X\:取的字符的每个中的一个1并且对于每个空间0X
  • (⍴⍺)⍴:调整结果的形状,使其具有原始矩阵的形状。

3

PHP,110 91 97 88 82 81 80 75字节

@ user59178节省了6个字节

while(""<$c=$argv[1][$i++])echo$c<1?$c?:" ":($s=$argv[2])[$k++%strlen($s)];

用运行-r。期望矩阵在第一个参数中为多行字符串,在第二个参数中为字符串。


1
根据你的82字节80字节版本版本:foreach(str_split($argv[1])as$c)echo$c<1?$c?:" ":($s=$argv[2])[$k++%strlen($s)];我换两个ternaries的顺序,因此使用的下降,从第二个括号<1,而不是>0
user59178

1
您可以使用for(;""!=$c=$argv[1][$i++];)而不是foreach(...)
user59178,2016年

3

PowerShell v2 +,70个字节

param($a,$b)$b|%{-join($_|%{if($_){$a[$n++];$n%=$a.length}else{' '}})}

将输入字设为$a,将矩阵设为数组$b(请参见下面的示例)。循环遍历$b,然后循环遍历每一行的元素$_|%{...}。内循环是一个if/else条件,在这里我们要么输出$a[$n++]并等于字符串的长度,要么输出一个空格' '。将它们-join一起编回到字符串中。每个字符串都留在管道上,并且Write-Output在程序完成时通过之间的换行符进行隐式输出。

PS C:\Tools\Scripts\golfing> .\the-art-of-word-shaping.ps1 'PPCGPPCG' @(@(0,0,1,0,0),@(0,1,0,1,0),@(1,0,0,0,1),@(0,1,0,1,0),@(0,0,1,0,0))
  P  
 P C 
G   P
 P C 
  G  

PS C:\Tools\Scripts\golfing> .\the-art-of-word-shaping.ps1 'lambda' @(@(1,0,0),@(0,1,0),@(1,0,1))
l  
 a 
m b

PS C:\Tools\Scripts\golfing> .\the-art-of-word-shaping.ps1 'PPCG' @(@(1,1,1),@(1,0,1),@(1,1,1))
PPC
G P
PCG


2

Python 3、104(或83)个字节

import itertools as i
def f(s,L):s=i.cycle(s);return'\n'.join(' '.join(next(s)*e for e in l)for l in L)

有较短的选项(83字节),但是如果字符串比所需的长度短999倍以上,它将失败:

def f(s,L):s=list(s)*999;return'\n'.join(' '.join(s.pop(0)*e for e in l)for l in L)

第二种解决方案对我不起作用,因为您无法调用next列表。如果您这样s=iter(list(s)*999)做(89字节)
L3viathan

1
@ L3viathan抱歉,我的意思是s.pop(0)。看来我复制了错误的版本,已解决。
艾丽莎

s[i++%s.length()]是一种很好的方法,尽管我不了解python。
魔术章

会很酷,但是没有i++Python 这样的东西
Alissa

1

Pyth,12个字节

jms?R@z~hZ\ 

在线尝试: 演示

说明:

jms?R@z~hZ\ dQ   implicit d and Q at the end
                 I use the variable Z, which is initialized with 0 by default
 m           Q   map each line d of the Q (input matrix) to:
   ?R       d       map each number d of the line either to
     @z~hZ             input[Z++] (increase Z, but lookup in input string with old value)
          \            or space
  s                 join chars to a string
j                print each string on a separate line


1

普通Lisp,152个字节

(defun m(g w)(let((a 0))(loop for r in g do(loop for e in r do(format t"~[ ~;~c~]"e(char w a))(if(= e 1)(setf a(mod(1+ a)(length w)))))(format t"~%"))))

用法:

* (m (list (list 1 0 1)
           (list 0 1 0)
           (list 1 0 1)) "ppcg")
p p
 c 
g p

此函数循环遍历网格每一行的每个元素。所述format控制字符串或者打印的空间,如果元件是0或消耗字符参数如果元素是1的换行获取网格中的每一行之后打印。如果字符串太短,则从头开始重复。如果太长,则仅输出适当的部分。


1

,18字节

17个字节的代码,-l标志+1 。

Yb{a?y@++vs}MMa^s

将数组作为第一个命令行参数,如下所示:(100 010 101需要在shell中引用),并将字符串作为第二个命令行参数。在线尝试!

说明

                   a and b are cmdline args, s is space, v is -1
Yb                 Yank b into global variable y
              a^s  Split a on space into list of rows
  {        }MM     Map this function to the items of the items of a (i.e. each character):
   a               Function argument
    ?              Ternary operator (truthy if 1, falsey if 0)
       ++v         If truthy, increment v...
     y@            ... and use it to index into y (cyclically)
                   I.e.: each time we hit a 1, replace it with the next character of y
          s        If falsey, space
                   The result is a list of lists of characters; -l concats sublists and
                   newline-separates the main list

1

Java,237233字节

编辑:感谢Mukul Kumar保存了4个字节

打高尔夫球:

String T(int[][]m,String b){int l=m.length,a=0;String o="";for(int i=0;i<l;i++){for(int j=0;j<l;j++){if(m[i][j]==1&&a<b.length()){o+=Character.toString(b.toCharArray()[a]);a++;if(a== b.length()-1)a=0;}else o+=" ";}o+="\n";}return o;}

取消高尔夫:

public String T(int[][] m, String b) {
    int l = m.length,a=0;
    String o = "";
    for(int i = 0; i < l; i++)
    {
        for(int j = 0; j < l; j++)
        {
            if(m[i][j] == 1 && a < b.length())
            {
                o += Character.toString(b.toCharArray()[a]);
                a++;

                if(a == b.length() - 1)
                    a = 0;
            }
            else
             o += " ";
        }
        o += "\n";
    }
    return o;
}

测试:

  int[][] matrix = new int[][]
  {{ 0, 0, 1, 0, 0 }, { 0, 1, 0, 1, 0 },
  { 1, 0, 0, 0, 1 },{ 0, 1, 0, 1, 0 },
  { 0, 0, 1, 0, 0 },};
  TheArtOfWordShaping taows = new TheArtOfWordShaping();
  System.out.println(taows.T(matrix, "PPCGPPCG"));

  matrix = new int[][] {{1,0,0}, {0,1,0}, {1,0, 1}};
  taows = new TheArtOfWordShaping();
  System.out.println(taows.T(matrix, "lamda"));

  matrix = new int[][] {{1,1,1},{1,0,1},{1,1, 1}};
  taows = new TheArtOfWordShaping();
  System.out.println(taows.T(matrix, "PPCG"));

  P  
 P C 
G   P
 P C 
  P  

l  
 a 
m d

PPC
P P
CPP

您可以在一行中声明所有int .....
Mukul Kumar

1

Pyke,12个字节

.FdRIKQoQl%@

在这里尝试!

输出字符矩阵

或9个字节,无竞争力。

.FdRIKQo@

在这里尝试!

  • 在要求的索引大于可索引的长度的索引上添加包装。.F-deep_for(input)I-if ^:Qo @-Q [o ++] dR-else“”

甚至更多非竞争性的8字节

.FIQo@(P

在这里尝试!

  • print_grid 现在可以正确对齐空字符串
  • deep_for 现在对类型与真相不同的虚假进行类型猜测

.F    (  -  deep_for(input)
 I       -   if ^:
  Qo@    -    input[o++]
       P - pretty_print(^)

1

Java,122个字节

String g(int[][]a,char[]b){String r="";int e=0;for(int[]c:a){for(int d:c){r+=d==0?' ':b[e++%b.length];}r+='\n';}return r;}

0

Mathematica,76个字节

""<>(s=#2;f:=(s=RotateLeft[s];Last[s]);Map[If[#1,f," "]&,#,{2}]~Riffle~"\n")&

两个参数的未命名函数,第一个(#)是Trues和Falses 的数组,第二个(s)是字符列表。辅助功能

f:=(s=RotateLeft[s];Last[s])

被定义,它将移动的第一个字符s放到最后,然后返回刚刚移动的字符。f多次调用将循环返回sorder 的字符。

核心功能是

Map[If[#1,f," "]&,#,{2}]

它调用输入数组中的f每个True值,并在每个错误的输入上返回一个空格。({2}告诉操作Map数组的组件列表中的元素,而不是列表本身。)

这60个字节返回一个由字符s和空格组成的数组。包装纸

    ""<>(...~Riffle~"\n")&

在该数组的每个列表之间放置换行符,然后将所有内容串联在一起。


0

C ++,61字节

for(auto&i:m){for(int&j:i)cout<<(j?s[k++%l]:' ');cout<<'\n';}
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.