矩阵拼图碎片


10

(受到https://codegolf.meta.stackexchange.com/a/17272/42963的随机启发)

给定一个矩形的数字矩阵(即0 - 9),输出矩阵的“块”,就好像这些数字被连接在一起形成单个块(按数字升序排列)一样。这些部件保证只能正交连接-没有任何部件将对角连接。最多只能有10个片段(即,一个3片段不会在同一矩阵中出现两次)。

例如,给定矩阵

0 1 1 1
0 0 1 2
3 3 2 2

以下是片段,以及示例输出:

0
0 0

1 1 1
  1

  2
2 2

3 3

间距对于保持部件的形状很重要,但是部件不一定需要内部间距。作品本身应以某种方式以一致的方式进行区分(例如,作品之间的换行符,确保每一个都是不同的字符,等等)。此外,不允许使用多余的空格(例如,尾随换行符或前导列)。例如,以下内容也将有效:

0
00
111
 1
 2
22
33

要么

#
##

###
 #

 #
##

##

但是以下内容不是(请注意0s 后面的空格):

0      
0 0    

也不允许旋转或反射。例如,输出

 1
111

对于上述矩阵也是无效的。

矩阵块可能有孔,也可能只有一个元素:

0 0 0 1
0 2 0 1
0 0 0 3

或者,该部分可能是整个矩阵:

0 0 0
0 0 0

这是一个更大,更复杂的测试用例:

1 1 1 1 1 2 2
3 4 4 4 2 2 2
5 5 4 4 2 0 0
5 6 6 6 6 7 7
5 6 8 8 6 6 7
9 6 6 6 7 7 7

和一个示例输出:

00

11111

 22
222
2

3

444
 44

55
5
5

6666
6  66
666

 77
  7
777

88

9

规则和I / O

  • 输入和输出可以通过任何方便的方法给出。
  • 您可以将其打印到STDOUT或将其作为功能结果返回。
  • 完整的程序或功能都是可以接受的。
  • 需要保持形状的前导空格(例如,1示例中的“ T”形),一致的空格以使各部分区分开,并且允许在末尾使用单个尾随换行符,但不允许其他空格。
  • 您可以放心地假设片段的编号0N连续的,这意味着(例如)3在六个片段的矩阵中不会被跳过。
  • 禁止出现标准漏洞
  • 这是因此所有常用的高尔夫规则都适用,并且最短的代码(以字节为单位)获胜。

输出实际上可以是零件清单吗?还是不是使用字符串而是使用矩阵和整数(带有-1或表示空的空间,或者如果可能的话没有元素)来完成I / O ?
Erik the Outgolfer

如果输入基于1(不包含零)并且输出0用作填充值,是否可以接受?因此,将输出每个片段,并将矩阵中的其余值设置为0
Luis Mendo

与我之前的问题无关不允许有其他空格:甚至没有尾随空格使所有行的长度相等?
Luis Mendo,

@EriktheOutgolfer没有元素就可以了,因为那只会输出“片断”本身。但是,为每个带有-1或其他值而不是没有空格/空白的输出矩阵都不是可以的。
AdmBorkBork

@AdmBorkBork哦,那么' '在这种情况下应该使用空格()吗?
乡村大佬埃里克(Erik the Outgolfer)'19年

Answers:


2

05AB1E20 19 字节

ZƒNQ2Fζʒà}}ε0Ü}0ð:,

-1个字节,感谢@ Mr.Xcoder

每条换行符输出2D片段列表(带有1和空格字符" ")。

在线尝试验证所有测试用例精美打印所有测试用例

说明:

Z              # Get the maximum digit of the (implicit) matrix-input (implicitly flattens)
 ƒ             # Loop in the range [0, max]:
  NQ           #  Check for each digit in the (implicit) matrix if it's equal to the index
    2F    }    #  Inner loop two times:
      ζ        #   Zip/transpose; swapping rows/columns
       ʒ }     #   Filter the inner lists by:
        à      #    Get the max of the list
               #  (so all rows/columns containing only 0s are removed)
  ε  }         #  Map the remaining rows:
   0Ü          #   Remove all trailing 0s
  0ð:          #  Then replace any remaining 0 with a space " "
     ,         #  And output the piece-matrix with a trailing newline

2

Haskell中,133个 132 129字节

f x=[until(any(>"!"))(tail<$>)m|m<-[[until((>'!').last)init r|r<-[[last$' ':[s|s==n]|s<-z]|z<-x],any(>'!')r]|n<-['0'..'9']],m>[]]

将矩阵作为字符串列表,并返回字符串列表。

在线尝试!

                                    -- example matrix: ["0111","0012","3322"] 
                                    --
[          |n<-[0..9]]              -- for each digit 'n' from '0' .. '9'
  [  |z<-x]                         --   for each line 'z' of the input matrix 'x'
   [      |s<-z]                    --     for each digit 's' of line 'z'
      last$' ':[s|s==n]             --       take 's' if 's'=='n', else a space
                                    --       now we have a list of 10 matrices where
                                    --       each matrix contains only the
                                    --       corresponding digit 'n' at it's original
                                    --       position and spaces for all other digits
                                    --       -> [["0   ","00  ","    "],[" 111","  1 ","    "],["    ","   2","  22"],["    ","    ","33  "],["    ","    ","    "],["    ","    ","    "],["    ","    ","    "],["    ","    ","    "],["    ","    ","    "],["    ","    ","    "]]
   [     |r<-[    ],any(>'!')r]     --     loop through rows 'r' and keep those with
                                    --     at least one non-space element
    until((>'!').last)init r        --     and remove trailing spaces
                                    --     -> [["0","00"],[" 111","  1"],["   2","  22"],["33"],[],[],[],[],[],[]]
   [     |m<-[   ],m>[]]            --   loop through matrices 'm' and keep only
                                    --   non-empty
    until(any(>"!"))(tail<$>)m      --   and remove common leading spaces
                                    --   -> [["0","00"],["111"," 1"],[" 2","22"],["33"]]

2

果冻,18字节

ẎQṢ=€ẸƇZ$⁺œr€ɗ€0o⁶

在线尝试!

返回片段列表,其中1代表片段的一部分,并' '进行填充。尾随' 's被删除。


ẎQ=€应该这样做,尽管我们需要按升序排列这些片断,所以9Ż=€(除非在这种情况下我们不能包含“不存在的片断” ẎQṢ=€
Jonathan Allan

@JonathanAllan解决了该问题,尽管我非常确定9Ż=€这是行不通的(我认为“不允许过分的空格”也扩展到数组,这就是为什么要修剪的原因)。
乡村大佬埃里克(Erik the Outgolfer)

是的,那很有道理。
乔纳森·艾伦,

2

Python 3中271个 209 206 183 176 172 191字节

lambda t:[[[*"".join(' #'[i==d]for i in r).rstrip()]for r in[w[min(r.index(d)for r in t if d in r):max(len(R)-R[::-1].index(d)for R in t if d in R)]for w in t if d in w]]for d in{*sum(t,[])}]

在线尝试!

编辑:一些清理和-5感谢@ Jonathan Frech

编辑:-3 -26再次感谢@ Jonathan Frech

编辑:-7再次感谢@ Jonathan Frech

编辑:+19:如@ nimi所指出,先前输出的格式不正确。


输入为矩阵作为列表列表:

Input =  [[0, 1, 1, 1],
          [0, 0, 1, 2],
          [3, 3, 2, 2]]

输出是矩阵列表:

Output = [[['#'],
           ['#', '#']],
          [['#', '#', '#'],
           [' ', '#']],
          [[' ', '#'],
           ['#', '#']],
          [['#', '#']]],

取消高尔夫:

O = ' '
X = '#'

def digits(t):
    return {d for r in t for d in r}

def rows_with_digit(table, digit):
    return [row for row in table if digit in row]

def table_with_digit(table, digit):
    subtable = rows_with_digit(table, digit)
    left_most_column = min([row.index(digit) for row in subtable])
    right_most_column = max([len(row) - row[::-1].index(digit) for row in subtable])
    return [row[left_most_column:right_most_column] for row in subtable]

def format_table(table, digit):
    return [[X if i==digit else O for i in row] for row in table]

def f(table):
    D = digits(table)
    R = []
    for d in D:
        digit_table = table_with_digit(table, d)
        R.append(format_table(digit_table, d))    
    return R


2

Python 2中173个 172 165字节

s=input()
for i in sorted(set(sum(s,[]))):R=[''.join([' ',i][c==i]for c in r)for r in s if i in r];print'\n'.join(t[min(r.find(i)for r in R):t.rfind(i)+1]for t in R)

在线尝试!

妮米(Nimi)观察到的-15个字节。

以程序形式,输入单个字符列表的列表;通过打印使用其角色找到的作品来输出。


@AdmBorkBork-对,错过了该标准。立即修复。
Chas Brown

2

C#(.NET核心)258,238个字节

没有LINQ。

编辑:无知的体现指出更好的var声明!ty ty。

p=>{int j=0,o=0,l=0,x=p.GetLength(1),d=p.Length;while(j<d){int t=j/x,u=j++%x,z=p[t,u];o=z>o?z:o;l=z<l?z:l;}var s="";for(var m=l;m<=o;m++){j=0;while(j<d){int t=j/x,u=j++%x;s+=(p[t,u]==m?p[t,u]+"":" ")+(u==x-1?"\n":"");}s+="\n";}return s;};

在线尝试!



1

Python 2,291字节

import re
t=input()
a,b=t.split(),{c for c in t if' '<c}
for c in sorted((b,a)[int(max(a))==len(a)],key=int):s=re.sub(r'[^%s\s]'%c,' ',t).split('\n');print"\n".join(''.join(l[i]for i in sorted({i for l in s for i,j in enumerate(l)if j in c})if i<len(l)).rstrip()for l in s if l.strip())+'\n'

在线尝试!

需要用引号分隔的字符串作为输入。该代码的半荒谬的百分比专用于处理非空格分隔/非空格填充的输入。

取消说明:

# built-in python regex handling.
import re
# get argument from STDIN
t=input()
# get elements which are whitespace separated, and all distinct non-whitespace characters
a,b=set(t.split()),{c for c in t if' '<c}
                # choose whichever set has the appropriate number of values based on its max element
                # for non-space separated inputs, this prevents values like '333' for 4-piece sets
                (b,a)[int(max(a))==len(a)]
# get elements in order by their integer value
# this will force the items to print in order, since sets are unordered
for c in sorted(..........................,key=int):
      # using regex substitute, replace any instance that DOESN'T match the current value or a whitespace with a space
      re.sub(r'[^%s\s]'%c,' ',t)
    # split replaced string into lines on line breaks
    s=...........................split('\n')
                # for each line in replaced input
                for l in s
                           # get the index and value of each item in line
                           for i,j in enumerate(l)
             # get distinct indexes which have a value that appears in the current piece
             {i ..................................if j in c}
    # get ordered list of distinct indexes
    a=sorted(...............................................)
                                                               # for each line in the replaced input
                                                               # only return values where line has non-whitespace values
                                                               for l in s if l.strip()
                           # get the value for each index that has a non-space value on other lines
                           # as long as that index exists (for non-space-padded inputs)
                           # this ensures that the spaces between values, if any, are removed
                           # there may still be trailing spaces
                           l[i]for i in a if i<len(l)
                   # join characters back into one string, and remove trailing whitespace
                   ''.join(..........................).rstrip()
    # join the lines back together with line breaks, and terminate with an extra line break
    # print output to screen
    print"\n".join(...................................................................)+'\n'

如果输入代码会使代码更加复杂,则可以指定输入格式(例如,列表列表或空格分隔的段落)。
AdmBorkBork

1

视网膜,75字节

$
¶9
.-10{T`9d`d`.$
*;(s`(\d)(?!.*\1$)
 
 +¶
¶
G`\d
/^\d|^$/m^+m`^.

.$
$&¶

在线尝试!说明:

$
¶9

在输入后附加一个数字。这代表循环计数器。换行符简化了尾随空格的删除。

.-10{

禁止默认输出并精确重复10次。

T`9d`d`.$

前进循环数字。

*;(

输出脚本其余部分的结果,然后还原缓冲区。

s`(\d)(?!.*\1$)
 

用空格替换与循环数字不匹配的所有数字。(因为这使用了前瞻性,并且在这一点上没有什么可预见的,所以这也取代了循环数字。)

 +¶
¶

删除所有尾随空格。

G`\d

删除所有空白行。

/^\d|^$/m^+

只要没有行以数字开头,请重复执行...

m`^.

...删除每一行的第一个字符。

.$
$&¶

如果还剩下任何内容,请添加换行符以将每个形状与下一个形状分开。(这样做是为了避免流失换行符而丢失数字。)


如果这样会使您的代码更短,则可以保证绝对不会出现“丢失数字”。
AdmBorkBork

@AdmBorkBork我认为这不会有所帮助。更可能有帮助的是不必按数字顺序输出片段。可以吗
尼尔,

不,那只是挑战的一半,否则那就太容易了。;-)
AdmBorkBork,

1

木炭,43字节

WS⊞υιFχ«≔Φυ№κIιθ¿θ«UTFθ«Fκ«¿⁼λIιλ→»M±Lκ¹»D⎚

在线尝试!链接是详细版本的代码。说明:

WS⊞υι

将输入读入数组。(如果我使用难看的输入格式,则可以将其删除。)

Fχ«

循环显示10位数字。

≔Φυ№κIιθ

获取包含这些数字的行。

¿θ«

检查是否确实找到了该数字(以防止输出虚假的换行符)。

UT

关闭自动填充。

Fθ«

循环查找找到的行。

Fκ«

循环浏览每列...

¿⁼λIιλ→»

...如果当前输入字符等于当前循环数字,则打印该字符,否则将光标向右移动。

M±Lκ¹»

移至下一行的开头。使用这样的运动命令可以使木炭修整两侧的输出。

D⎚

转储并清除画布以准备下一位数字。这允许不同的数字具有不同的修整量。

我尝试了一种编程方法,但是它的重量为47个字节,尽管在向量化的短暂时间内也为43个字节Equals

UTWS⊞υιFχ«≔ΦEυEκ⁼μIιΣκθEθ⭆✂κ⌊Eθ⌕μ¹⁻Lκ⌕⮌κ¹¦¹⎇μι 

在线尝试!链接是详细版本的代码。说明:

UT

关闭自动填充。

WS⊞υι

将输入读入数组。

Fχ«

循环显示10位数字。

≔ΦEυEκ⁼μIιΣκθ

将每个字符与输入进行比较,并建立一个布尔数组,然后过滤掉没有匹配项的行。

Eθ⭆✂κ⌊Eθ⌕μ¹⁻Lκ⌕⮌κ¹¦¹⎇μι 

循环遍历其余行,并从任何行中最早的匹配片到当前行中的最新匹配片,然后将布尔数组映射回数字或空格,然后隐式打印为字符串数组。


1

Wolfram语言101字节

必须有一种更有效的方法来完成此任务。

(g=#;Column[Table[Grid@Map[Replace[#,Thread[Complement[u=Union@Flatten@g,{n}]->""]]&/@#&,g],{n,u}]])&

1

Perl 5,97个字节

$x=$_;for$i(0..9){$_=$x;y/ //d;s/(?!$i)./ /g;s/ *$//gm;s/^
//gm;s/^ //gm until/^(?! )/m;$\.=$_}}{

蒂奥

说明

-p0777                       # options to read whole intput and print special var by default

$x=$_;                       # save default var (input) into $x
for$i(0..9){                 # for $i in 0..9
    $_=$x;                   #   restore default var 
    y/ //d;                  #   remove all space char
    s/(?!$i)./ /g;           #   replace all char except $i by a space
    s/ *$//gm;               #   remove trailing space
    s/^\n//gm;               #   remove empty lines
    s/^ //gm until/^(?! )/m; #   remove leading space until there is no more
    $\.=$_                   #   append default var to output record separator
}
}{                           # trick with -p to output only reacord separator

1

APL(Dyalog Unicode),38 字节SBCS

匿名默认前缀功能。以数值矩阵为参数,并返回列表字符串列表。每个字符串列表代表一个用1s 隔开的片段。前导和内部(但不是尾随)空格是空格。

⊂{' +$'R''↓⍕' '@~{⍉⍵⌿⍨∨/⍵}⍣2⊢⍺=⍵}¨∪∘,

在线尝试!

∪∘, ravel(展平)矩阵的唯一元素

⊂{ 对于每个as ,请使用以下整个矩阵调用以下函数

⍺=⍵ 指示该零件的编号在矩阵中的位置

 得到的是(分离2

{}⍣2 两次应用以下函数(是布尔矩阵):

  ∨/ 遮罩,用于至少包含一个的1行(逐行OR减少)

  ⍵⌿⍨ 用它来过滤行

   转置(因此我们也在列上执行此操作,然后转回)

' '@~ 在不存在的位置(即0)替换为空格

 格式为字符矩阵

 分成字符串列表

' +$'⎕R'' PCRE用任何内容替换尾随空格(任意数量的空格后跟行尾)


1

Japt,29个字节

AÆ®®¥X ÑÃÃÕfx Õfx ®¬r0S x1
fl

在线尝试!

更新以符合更严格的输出格式。

输出为作品列表,每个作品由行列表表示,使用2作为填充字符。

说明:

AÆ                            #For the numbers 0-9:
  ®®    ÃÃ                    # Map over each digit in the input:
    ¥X                        #  True if it equals the current number, false otherwise
       Ñ                      #  Multiply by 2 to turn the bool into a number
          Õfx                 # Remove columns that are all 0
              Õfx             # Remove rows that are all 0
                  ®           # For each remaining row:
                   ¬          #  Turn it into a string
                    r0S       #  Replace "0" with " "
                        x1    #  Trim spaces from the right
fl                            #Remove unused pieces

您忘记false从内部列表中删除所有尾随。这里有一个pastebin,所以我可以更好地解释应该是什么输出。随意要求OP进行澄清,但是据我从挑战中了解到,所有尾随空格都不应该在输出中根本没有。
凯文·克鲁伊森

0

Python 3,133字节

lambda s:[dedent(re.sub(" *$","",re.sub(f"[^{c}\\n]"," ",s),0,8)).strip("\n")for c in sorted(*s)[1:]]
from textwrap import*
import re

在线尝试!

接受换行符分隔的字符串,返回换行符分隔的字符串的列表。用于textwrap.dedent摆脱前导空格。


@AdmBorkBork忽略了该规则,已修复
Black Owl Kai

0

果冻,19字节

ŒĠµŒṬZSƇ$⁺ị⁾# œr€⁶)

在线尝试!

以矩阵为输入的单子链接,并返回一个每个参差不齐列表的列表。页脚显示得很漂亮,但是我认为没有该显示的输出与问题规则是一致的。

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.