マトリックスジグソーパズルのピース


10

(ランダムにhttps://codegolf.meta.stackexchange.com/a/17272/42963からインスピレーションを得た)

数字の長方形マトリックス(つまり、0 - 9)が与えられた場合、数字の昇順で、数字が1つに接続されているかのように、マトリックスの「ピース」を出力します。ピースは、直角にのみ接続することが保証されています-ピースは斜めに接続しません。最大10個のピース​​しかあり3ません(つまり、ピースは同じマトリックスに2回表示されません)。

たとえば、行列

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に出力するか、関数の結果として返すことができます。
  • 完全なプログラムまたは関数のいずれかを使用できます。
  • 形状を維持するための先頭の空白(例ではの「T」形1)が必要であり、ピースを区別するために一貫した空白が必要です。最後に単一の末尾の改行が許可されますが、他の空白は許可されません。
  • ピースは連続して番号が付けられ0ていると安全に想定できますN。つまり、(たとえば)36ピースのマトリックスではスキップされません。
  • 標準の抜け穴は禁止されています。
  • これはので、すべての通常のゴルフ規則が適用され、最短のコード(バイト単位)が優先されます。

出力は実際にピースのリストになりますか?または、I / Oは文字列ではなく行列と整数(-1空のスペースを表す、またはスペース、または可能な場合は要素がない)で行われますか?
Erik the Outgolfer

入力が1ベース(ゼロを含まない)であり、出力が0フィラー値として使用されている場合は許容されますか?したがって、各ピースは、マトリックスの残りの値を設定して出力されます0
Luis Mendo

私の前の質問とは無関係:他の空白は許可されていません:すべての行を同じ長さにするために末尾のスペースすらありませんか?
Luis Mendo

@EriktheOutgolfer「ピース」そのものを出力するだけなので、要素がなくても問題ありません。-1ただし、何もない/空白の代わりに、またはその他の値を持つ各部分の行列全体を出力することはできません。
AdmBorkBork

@AdmBorkBorkああ、その場合はスペース(' ')を使用する必要がありますか?
Erik the Outgolfer

回答:


2

05AB1E20 19 バイト

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

@ Mr.Xcoderのおかげで-1バイト。

改行ごとに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

ハスケル、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の一部を表し、' 'パディングされているピースのリストを返します。末尾' 'のは削除されます。


ẎQ=€我々は昇順に駒を必要とするが、これを行う必要があります9Ż=€(私たちは、その場合には「存在しない部分」が含まれてはならない場合を除きẎQṢ=€
ジョナサン・アラン

@JonathanAllan問題が修正されますが、動作しないことはほぼ間違いあり9Ż=€ません(「余分な空白[...]は許可されていません」は配列にも拡張されると考えられるため、トリミングしています)。
Erik the Outgolfer

ええ、それは理にかなっています。
ジョナサンアラン

2

Pythonの3271の 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,[])}]

オンラインでお試しください!

編集:いくつかのクリーンアップと@ Jonathan Frechによる -5のおかげ。

編集:-3 -26もう一度@ Jonathan Frechに感謝します。

編集:再び@ Jonathan Frechのおかげで-7 。

編集:+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

パイソン2173の 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


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

Retina、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それは役に立たないと思います。より役立つ可能性が高いのは、ピースを番号順に出力する必要がないことです。それは許されますか?
Neil

いいえ、それは半分の挑戦です、さもなければそれはあまりにも簡単です。;-)
AdmBorkBork

1

チャコール、43バイト

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

オンラインでお試しください!リンクはコードの詳細バージョンです。説明:

WS⊞υι

入力を配列に読み込みます。(これは、醜い入力フォーマットを使用した場合は削除できます。)

Fχ«

10桁でループします。

≔Φυ№κIιθ

それらの数字を含む行を取得します。

¿θ«

数字が実際に見つかったことを確認します(偽の改行を出力しないようにするため)。

UT

自動パディングをオフにします。

Fθ«

見つかった行をループします。

Fκ«

各列をループ...

¿⁼λIιλ→»

...現在の入力文字が現在のループ桁と等しい場合は印刷し、それ以外の場合はカーソルを右に移動します。

M±Lκ¹»

次の行の先頭に移動します。このような移動コマンドを使用すると、Charcoalは出力を両側でトリミングできます。

D⎚

キャンバスをダンプしてクリアし、次の桁に備えます。これにより、桁ごとにトリミングの量を変えることができます。

私はプログラムによるアプローチを試しましたが、47バイトの重さでしたが、Equalsベクトル化した場合、短時間で43バイトになることもありました。

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;$\.=$_}}{

TIO

説明

-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⊢⍺=⍵}¨∪∘,

オンラインでお試しください!

∪∘, ラヴェル(平坦化)行列の一意の要素

⊂{ asのそれぞれについて、行列全体を次のように使用して次の関数を呼び出します

⍺=⍵ そのピースの番号がマトリックスのどこにあるかを示します

 降伏する(2から分離

{}⍣2 次の関数を2回適用します(ブール行列です):

  ∨/ 少なくとも1つの行のマスク1(lit.行ごとの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内部リストからすべての末尾を削除するのを忘れました。ここにペーストビンがあるので、出力されるはずのものをよりよく説明できます。OPに明確にするように頼んでも構いませんが、私が挑戦から理解している限り、すべての末尾の空白が出力に含まれていてはいけません。
Kevin Cruijssen、

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.