Potongan Jigsaw Puzzle Matrix

10

(Diilhami secara acak oleh https://codegolf.meta.stackexchange.com/a/17272/42963 )

Diberikan matriks persegi empat digit (yaitu, 0 - 9), output "potongan-potongan" dari matriks seolah-olah digit tersebut terhubung bersama-sama membentuk satu bagian, dalam urutan naik dengan digit. Potongan-potongan dijamin untuk terhubung hanya ortongonal - tidak ada bagian yang akan terhubung secara diagonal. Hanya akan pernah ada maksimum 10 buah (yaitu, 3sepotong tidak akan muncul dua kali dalam matriks yang sama).

Misalnya diberi matriks

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

berikut ini adalah potongan-potongan, dan contoh output:

0
0 0

1 1 1
  1

  2
2 2

3 3

Spasi penting untuk menjaga bentuk potongan, tetapi potongan tidak perlu jarak interior. Potongan-potongan itu sendiri entah bagaimana harus dibuat berbeda secara konsisten (misalnya, baris baru di antara potongan-potongan, memastikan masing-masing adalah karakter yang berbeda, dll.). Selain itu, spasi putih asing (misalnya, mengikuti baris baru atau kolom utama) tidak diperbolehkan. Misalnya, berikut ini juga akan valid:

0
00
111
 1
 2
22
33

atau

#
##

###
 #

 #
##

##

Tapi yang berikut ini tidak akan (perhatikan spasi tambahan di belakang huruf 0s):

0      
0 0    

Rotasi atau refleksi juga tidak diperbolehkan. Misalnya, keluaran

 1
111

untuk matriks di atas juga tidak valid.

Potongan-potongan matriks mungkin memiliki lubang, atau hanya elemen tunggal:

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

Atau, potongannya mungkin seluruh matriks:

0 0 0
0 0 0

Ini kasus uji yang lebih besar dan lebih rumit:

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

Dan contoh output:

00

11111

 22
222
2

3

444
 44

55
5
5

6666
6  66
666

 77
  7
777

88

9

Aturan dan I / O

  • Input dan output dapat diberikan dengan metode apa pun yang mudah .
  • Anda dapat mencetaknya ke STDOUT atau mengembalikannya sebagai hasil fungsi.
  • Program lengkap atau fungsi dapat diterima.
  • Diperlukan spasi putih untuk menjaga bentuk (misalnya, bentuk "T" 1pada contoh) diperlukan, spasi putih yang konsisten untuk membuat potongan-potongan menjadi berbeda, dan satu baris baru di belakangnya dibolehkan, tetapi tidak ada spasi lain yang diizinkan.
  • Anda dapat dengan aman berasumsi bahwa potongan-potongan diberi nomor 0untuk Ncontiguously, yang berarti bahwa (misalnya) 3tidak akan melewatkan dalam matriks enam-piece.
  • Celah standar dilarang.
  • Ini adalah sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.
AdmBorkBork
sumber
Bisakah output benar-benar menjadi daftar potongan? Atau I / O tidak dilakukan dengan string tetapi dengan matriks dan bilangan bulat (dengan -1atau ruang yang mewakili ruang kosong, atau tidak adanya elemen jika memungkinkan)?
Erik the Outgolfer
Apakah dapat diterima jika input berbasis 1 (tidak mengandung nol) dan output digunakan 0sebagai nilai pengisi? Jadi masing-masing bagian akan menjadi keluaran dengan sisa nilai-nilai dalam matriks diatur ke0
Luis Mendo
Independen dari pertanyaan saya sebelumnya: tidak ada spasi putih yang diizinkan : bahkan tidak tertinggal spasi untuk membuat semua garis sama panjang?
Luis Mendo
@EriktheOutgolfer Tidak adanya elemen akan baik-baik saja, karena hanya menghasilkan "bagian" itu sendiri. Mengeluarkan seluruh matriks untuk setiap bagian dengan -1atau beberapa nilai lain alih-alih tidak ada / spasi tidak akan baik-baik saja.
AdmBorkBork
@ AdmBorkBork Oh, jadi haruskah ruang ( ' ') digunakan dalam kasus itu?
Erik the Outgolfer

Jawaban:

2

05AB1E , 20 19 byte

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

-1 byte terima kasih kepada @ Mr.Xcoder .

Menghasilkan daftar potongan 2D (dengan 1dan spasi karakter " ") per baris baru.

Cobalah secara online atau verifikasi semua test case atau cukup cetak semua test case .

Penjelasan:

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
Kevin Cruijssen
sumber
2

Haskell, 133 132 129 byte

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>[]]

Mengambil matriks sebagai daftar string dan mengembalikan daftar daftar string.

Cobalah online!

                                    -- 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"]]
nimi
sumber
2

Jelly , 18 byte

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

Cobalah online!

Mengembalikan daftar keping, yang 1mewakili bagian dari keping, dan ' 'melapisi. Trailing ' 's dihapus.

Erik the Outgolfer
sumber
ẎQ=€harus dilakukan, meskipun kita membutuhkan potongan dalam urutan menaik, jadi 9Ż=€(kecuali kita tidak boleh memasukkan "potongan tidak ada" dalam hal ini ẎQṢ=€)
Jonathan Allan
@ JonathanAllan Memperbaiki masalah, meskipun saya cukup yakin 9Ż=€tidak akan bekerja (saya pikir "spasi kosong [...] tidak diizinkan" meluas ke array juga, itu sebabnya saya memotong).
Erik the Outgolfer
Ya, itu masuk akal.
Jonathan Allan
2

Python 3 , 271 209 206 183 176 172 191 byte

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

Cobalah online!

Sunting: Beberapa pembersihan dan -5 berkat @ Jonathan Frech .

Sunting: -3 -26 sekali lagi terima kasih kepada @ Jonathan Frech .

Sunting: -7 lagi terima kasih kepada @ Jonathan Frech .

Sunting: +19: Seperti yang dicatat oleh @ nimi, keluaran sebelumnya memiliki format yang salah.


Input adalah matriks sebagai daftar daftar:

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

Output adalah daftar matrik:

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

Tidak Disatukan:

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
Nishioka
sumber
1
176 byte .
Jonathan Frech
2

Python 2 , 173 172 165 byte

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)

Cobalah online!

-15 byte dari pengamatan oleh nimi .

Dalam bentuk program, masukkan input daftar karakter tunggal; output dengan mencetak potongan-potongan yang ditemukan menggunakan karakter mereka.

Chas Brown
sumber
@ AdmBorkBork - Benar, ketinggalan kriteria itu. Diperbaiki sekarang
Chas Brown
2

C # (.NET Core) , 258 , 238 byte

Tanpa LINQ.

EDIT: Perwujudan Ketidaktahuan menunjukkan deklarasi var lebih baik! 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;};

Cobalah online!

Destroigo
sumber
1
238 byte
Perwujudan Ketidaktahuan
1

Python 2 , 291 byte

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'

Cobalah online!

Mengharapkan sengatan terbatas-kutipan sebagai input. Persentase semi-menggelikan dari kode ini didedikasikan untuk menangani input non-spasi-terpisah / non-spasi-empuk.

Penjelasan Tidak Diputar Golf:

# 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'
Triggernometri
sumber
Anda diizinkan menentukan format input (mis., Sebagai daftar daftar, atau sebagai paragraf yang dipisahkan oleh spasi) jika itu membuat kode golfier Anda.
AdmBorkBork
1

Retina , 75 byte

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

.$
$&¶

Cobalah online! Penjelasan:

$
¶9

Tambahkan digit ke input. Ini mewakili penghitung lingkaran. Baris baru menyederhanakan penghapusan spasi spasi tambahan.

.-10{

Menghambat keluaran default dan ulangi tepat 10 kali.

T`9d`d`.$

Tingkatkan angka loop.

*;(

Keluarkan hasil dari sisa skrip tetapi kemudian pulihkan buffer.

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

Ganti semua digit yang tidak cocok dengan digit lingkaran dengan spasi. (Karena ini menggunakan lookahead dan tidak ada yang melihat ke depan pada saat ini, ini juga menggantikan digit lingkaran.)

 +¶
¶

Hapus semua spasi spasi tambahan.

G`\d

Hapus semua baris kosong.

/^\d|^$/m^+

Ulangi selama tidak ada garis yang dimulai dengan digit ...

m`^.

... hapus karakter pertama di setiap baris.

.$
$&¶

Jika ada yang tersisa, tambahkan baris baru untuk memisahkan setiap bentuk dari yang berikutnya. (Ini dilakukan untuk menghindari baris baru yang tersesat karena kehilangan digit.)

Neil
sumber
Dijamin tidak akan ada "digit yang hilang" jika itu membuat kode Anda lebih pendek.
AdmBorkBork
@ AdmBorkBork Saya tidak berpikir itu akan membantu. Apa yang lebih mungkin untuk membantu adalah tidak harus menampilkan potongan-potongan dalam urutan numerik. Apakah itu diizinkan?
Neil
Tidak, itu setengah dari tantangan, kalau tidak akan terlalu mudah. ;-)
AdmBorkBork
1

Arang , 43 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

WS⊞υι

Baca input ke dalam array. (Ini bisa dihapus jika saya menggunakan format input yang jelek.)

Fχ«

Ulangi lebih dari 10 digit.

≔Φυ№κIιθ

Dapatkan baris yang berisi angka-angka itu.

¿θ«

Periksa apakah digit itu memang ditemukan (untuk mencegah keluaran baris baru palsu).

UT

Matikan padding otomatis.

Fθ«

Lingkari baris yang ditemukan.

Fκ«

Lingkari setiap kolom ...

¿⁼λIιλ→»

... jika karakter input saat ini sama dengan digit loop saat ini, maka cetaklah jika tidak, gerakkan kursor ke kanan.

M±Lκ¹»

Pindah ke awal baris berikutnya. Menggunakan perintah gerakan seperti ini memungkinkan Charcoal memangkas output di kedua sisi.

D⎚

Buang dan kosongkan kanvas siap untuk digit berikutnya. Ini memungkinkan angka yang berbeda memiliki jumlah pemotongan yang berbeda.

Saya mencoba pendekatan terprogram tetapi itu berbobot pada 47 byte, meskipun itu juga akan menjadi 43 byte untuk waktu singkat ketika Equalsvektor:

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

UT

Matikan padding otomatis.

WS⊞υι

Baca input ke dalam array.

Fχ«

Ulangi lebih dari 10 digit.

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

Bandingkan setiap karakter dengan input dan bangun array boolean, tetapi kemudian filter baris tanpa kecocokan.

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

Lingkarilah baris dan irisan yang tersisa dari kecocokan paling awal di setiap baris ke kecocokan terbaru pada baris saat ini, kemudian pemetaan boolean array kembali ke digit atau spasi, yang kemudian dicetak secara implisit sebagai array string.

Neil
sumber
1

Bahasa Wolfram 101 byte

Harus ada cara yang jauh lebih efisien untuk mencapai ini.

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

Perl 5, 97 byte

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

TIO

Penjelasan

-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
Nahuel Fouilleul
sumber
1

APL (Dyalog Unicode) , 38 byte SBCS

Fungsi awalan diam-diam anonim. Mengambil matriks numerik sebagai argumen dan mengembalikan daftar string daftar. Setiap daftar string mewakili bagian dengan spasi- 1s. Leading dan internal (tetapi tidak trailing) spasi adalah spasi.

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

Cobalah online!

∪∘, elemen unik dari matriks ravel (diratakan)

⊂{...  untuk masing-masing sebagai , panggil fungsi berikut dengan seluruh matriks sebagai :

⍺=⍵ menunjukkan di mana nomor itu dalam matriks

 hasilkan itu (terpisah 2dari )

{... }⍣2 terapkan fungsi berikut dua kali ( adalah matriks Boolean):

  ∨/ mask untuk baris dengan setidaknya satu 1(lit-row-wise OR-reduction)

  ⍵⌿⍨ gunakan itu untuk menyaring baris

   transpos (jadi kami melakukan ini pada kolom juga, lalu transpos kembali)

' '@~ ganti dengan spasi pada posisi di mana tidak (yaitu di mana 0)

 format sebagai matriks karakter

 terpecah menjadi daftar string

' +$'⎕R'' PCRE mengganti spasi tambahan (jumlah spasi diikuti oleh garis-akhir) dengan nol

Adm
sumber
1

Japt , 29 byte

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

Cobalah online!

Diperbarui untuk mematuhi pemformatan output yang lebih ketat.

Output sebagai daftar potongan dengan masing-masing bagian diwakili oleh daftar garis, menggunakan 2 sebagai karakter pengisi.

Penjelasan:

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
Kamil Drakari
sumber
Anda lupa menghapus semua trailing falsedari daftar dalam. Di sini pastebin jadi saya bisa lebih baik menjelaskan apa yang seharusnya menjadi output. Merasa bebas untuk meminta OP untuk mengklarifikasi, tetapi sejauh yang saya mengerti dari tantangan, semua spasi putih tertinggal tidak boleh ada di output sama sekali.
Kevin Cruijssen
0

Python 3 , 133 byte

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

Cobalah online!

Mengambil string yang dipisahkan baris baru, mengembalikan daftar string yang dipisahkan baris yang baru. Menggunakan textwrap.dedentuntuk menyingkirkan ruang terdepan.

Black Owl Kai
sumber
@AdmBorkBork Mengabaikan aturan itu, memperbaiki
Black Owl Kai
0

Jelly , 19 byte

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

Cobalah online!

Tautan monadik mengambil matriks sebagai input dan mengembalikan daftar satu daftar kasar per potong. Footer menampilkan ini dengan cantik, tapi saya pikir keluaran tanpa itu konsisten dengan aturan pertanyaan.

Nick Kennedy
sumber