Pezzi Matrix Jigsaw Puzzle


10

(Ispirato casualmente da https://codegolf.meta.stackexchange.com/a/17272/42963 )

Data una matrice rettangolare di cifre (cioè, 0 - 9), emette i "pezzi" della matrice come se le cifre fossero collegate insieme formando un singolo pezzo, in ordine crescente dalle cifre. I pezzi sono garantiti per il collegamento solo ortogonalmente - nessun pezzo si collegherà in diagonale. Ci saranno sempre e solo un massimo di 10 pezzi (ovvero, un 3pezzo non apparirà due volte nella stessa matrice).

Ad esempio, data la matrice

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

i seguenti sono i pezzi e un esempio di output:

0
0 0

1 1 1
  1

  2
2 2

3 3

La spaziatura è importante per mantenere la forma dei pezzi, ma i pezzi non necessitano necessariamente di spaziatura interna. I pezzi stessi dovrebbero in qualche modo essere distinti in modo coerente (ad esempio, una nuova riga tra i pezzi, assicurandosi che ognuno di essi abbia un carattere diverso, ecc.). Inoltre, non sono consentiti spazi bianchi estranei (ad esempio newline finali o colonne iniziali). Ad esempio, sarebbe valido anche quanto segue:

0
00
111
 1
 2
22
33

o

#
##

###
 #

 #
##

##

Ma quanto segue non sarebbe (notare gli spazi finali dietro la 0s):

0      
0 0    

Rotazioni o riflessi non sono ammessi. Ad esempio, in uscita

 1
111

per la matrice sopra non è valido.

I pezzi della matrice possono avere buchi o essere solo un singolo elemento:

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

Oppure, il pezzo può essere l'intera matrice:

0 0 0
0 0 0

Ecco un caso di prova più ampio e complicato:

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

E un esempio di output:

00

11111

 22
222
2

3

444
 44

55
5
5

6666
6  66
666

 77
  7
777

88

9

Regole e I / O

  • Input e output possono essere forniti con qualsiasi metodo conveniente .
  • È possibile stamparlo su STDOUT o restituirlo come risultato di una funzione.
  • È accettabile un programma completo o una funzione.
  • È richiesto lo spazio bianco principale per mantenere la forma (ad esempio, la forma a "T" 1nell'esempio), spazi bianchi coerenti per rendere distinti i pezzi e è consentita una sola nuova riga finale alla fine, ma non sono ammessi altri spazi bianchi.
  • Puoi tranquillamente supporre che i pezzi siano numerati 0in modo Ncontiguo, il che significa che (ad esempio) 3non verrebbero ignorati in una matrice di sei pezzi.
  • Sono vietate le scappatoie standard .
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte).

L'output può effettivamente essere un elenco dei pezzi? Oppure l'I / O non deve essere eseguito con stringhe ma con matrici e numeri interi (con -1o uno spazio che rappresenta uno spazio vuoto o l'assenza di un elemento se possibile)?
Erik the Outgolfer,

È accettabile se l'input è basato su 1 (non contiene zeri) e l'output utilizza 0come valore di riempimento? Quindi ogni pezzo verrebbe prodotto con il resto dei valori nella matrice impostato su0
Luis Mendo,

Indipendentemente dalla mia domanda precedente: nessun altro spazio bianco è consentito : nemmeno gli spazi finali per rendere tutte le linee di uguale lunghezza?
Luis Mendo,

@EriktheOutgolfer L'assenza di un elemento sarebbe OK, dal momento che sta producendo solo il "pezzo" stesso. -1Tuttavia, produrre un'intera matrice per ogni pezzo con o qualche altro valore invece di niente / spazi bianchi non sarebbe OK.
AdmBorkBork,

@AdmBorkBork Oh, quindi lo spazio ( ' ') dovrebbe essere usato in quel caso?
Erik the Outgolfer,

Risposte:


2

05AB1E , 20 19 byte

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

-1 byte grazie a @ Mr.Xcoder .

Emette elenchi 2D di pezzi (con 1e spazi " ") per newline.

Provalo online o verifica tutti i casi di prova o stampa tutti i casi di prova .

Spiegazione:

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

Prende la matrice come un elenco di stringhe e restituisce un elenco di un elenco di stringhe.

Provalo 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"]]

2

Gelatina , 18 byte

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

Provalo online!

Restituisce un elenco di pezzi, dove 1rappresenta una parte di un pezzo, ed ' 'è il riempimento. I messaggi finali ' 'vengono rimossi.


ẎQ=€dovremmo fare, anche se abbiamo bisogno dei pezzi in ordine crescente, quindi 9Ż=€(a meno che non dobbiamo includere "pezzi inesistenti" nel qual caso ẎQṢ=€)
Jonathan Allan,

@JonathanAllan Risolto il problema, anche se sono abbastanza sicuro 9Ż=€che non funzionerà (penso che "spazi bianchi estranei [...] non sono ammessi" si estende anche agli array, ecco perché sto tagliando).
Erik the Outgolfer,

Sì, ha senso.
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,[])}]

Provalo online!

Modifica: un po 'di pulizia e -5 grazie a @ Jonathan Frech .

Modifica: -3 -26 ancora una volta grazie a @ Jonathan Frech .

Modifica: -7 di nuovo grazie a @ Jonathan Frech .

Modifica: +19: Come notato da @ nimi in precedenza l'output aveva un formato errato.


L'input è una matrice come elenco di elenchi:

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

L'output è un elenco di matrici:

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

Ungolfed:

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

Provalo online!

-15 byte da un'osservazione di nimi .

Nel modulo del programma, accetta come input un elenco di elenchi di singoli caratteri; stampa stampando i pezzi trovati usando il loro personaggio.


@AdmBorkBork - Giusto, ho mancato quei criteri. Riparato ora.
Chas Brown,

2

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

Senza LINQ.

EDIT: Embodiment Of Ignorance sottolineando migliori dichiarazioni var! Grazie grazie.

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

Provalo online!



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'

Provalo online!

Si aspetta una puntura delimitata da virgolette come input. Una percentuale semi-ridicola del codice è dedicata alla gestione di input non separati da spazio / non riempiti di spazio.

Spiegazione senza 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'

Puoi specificare il formato di input (ad esempio, come un elenco di elenchi o come un paragrafo separato da spazi) se rende il tuo codice più golfico.
AdmBorkBork

1

Retina , 75 byte

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

.$
$&¶

Provalo online! Spiegazione:

$
¶9

Aggiungi una cifra all'ingresso. Questo rappresenta il contatore di loop. La nuova riga semplifica la rimozione degli spazi bianchi finali.

.-10{

Inibisce l'output predefinito e ripeti esattamente 10 volte.

T`9d`d`.$

Avanzare la cifra del loop.

*;(

Emette il risultato del resto dello script ma ripristina il buffer.

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

Sostituisci tutte le cifre che non corrispondono alla cifra del ciclo con spazi. (Poiché questo utilizza un lookahead e non c'è nulla da guardare a questo punto, questo sostituisce anche la cifra del loop.)

 +¶
¶

Rimuovi tutti gli spazi bianchi finali.

G`\d

Rimuovi tutte le righe vuote.

/^\d|^$/m^+

Ripeti finché nessuna riga inizia con una cifra ...

m`^.

... cancella il primo carattere su ogni riga.

.$
$&¶

Se è rimasto qualcosa, aggiungi una nuova riga per separare ciascuna forma dalla successiva. (Questo viene fatto per evitare newline vaganti per le cifre mancanti.)


È garantito che non ci sarà mai una "cifra mancante" se questo accorcia il codice.
AdmBorkBork

@AdmBorkBork Non penso che sarebbe d'aiuto. Ciò che avrebbe maggiori probabilità di aiutare è di non dover produrre i pezzi in ordine numerico. È permesso?
Neil

No, questa è metà della sfida, altrimenti sarebbe troppo facile. ;-)
AdmBorkBork

1

Carbone , 43 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

WS⊞υι

Leggi l'input in un array. (Questo potrebbe essere rimosso se avessi usato un brutto formato di input.)

Fχ«

Passa sopra le 10 cifre.

≔Φυ№κIιθ

Ottieni le righe che contengono quelle cifre.

¿θ«

Verificare che la cifra sia stata effettivamente trovata (per impedire l'emissione di newline spurie).

UT

Disattiva l'imbottitura automatica.

Fθ«

Passa sopra le righe trovate.

Fκ«

Passa sopra ogni colonna ...

¿⁼λIιλ→»

... se il carattere di input corrente è uguale alla cifra del loop corrente, stampalo altrimenti sposta il cursore a destra.

M±Lκ¹»

Passa all'inizio della riga successiva. L'uso di comandi di movimento come questo consente al carbone di tagliare l'output su entrambi i lati.

D⎚

Scarica e cancella la tela pronta per la cifra successiva. Ciò consente alle diverse cifre di avere diverse quantità di rifilatura.

Ho provato un approccio programmatico, ma che pesava 47 byte, anche se sarebbe stato anche 43 byte per un breve periodo di tempo quando Equalsvettorizzato:

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

UT

Disattiva l'imbottitura automatica.

WS⊞υι

Leggi l'input in un array.

Fχ«

Passa sopra le 10 cifre.

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

Confronta ogni personaggio con l'input e crea un array booleano, quindi filtra le righe senza corrispondenze.

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

Passa con il mouse sulle righe rimanenti e separa dalla prima corrispondenza di qualsiasi riga all'ultima corrispondenza della riga corrente, quindi mappando la matrice booleana su cifre o spazi, che vengono quindi implicitamente stampati come una matrice di stringhe.


1

Wolfram Language 101 byte

Deve esserci un modo molto più efficiente per raggiungere questo obiettivo.

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

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

Spiegazione

-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 byte SBCS

Funzione prefisso tacito anonimo. Prende una matrice numerica come argomento e restituisce un elenco di stringhe di elenchi. Ogni elenco di stringhe rappresenta un pezzo con 1s separati da spazio . Gli spazi iniziali e interni (ma non finali) sono spazi.

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

Provalo online!

∪∘, gli elementi unici della matrice ravel (appiattita)

⊂{...  per ognuno di quelli come , chiama la seguente funzione con l'intera matrice come :

⍺=⍵ indica dove si trova il numero di quel pezzo nella matrice

 cedere che (separa 2da )

{}⍣2 Applica due volte la seguente funzione ( è la matrice booleana):

  ∨/ maschera per righe con almeno una 1(lit. row-wise OR-riduzione)

  ⍵⌿⍨ usalo per filtrare le righe

   trasporre (quindi lo facciamo anche sulle colonne, quindi trasporre indietro)

' '@~ sostituire con spazi in posizioni dove non (cioè dove 0)

 formato come matrice di caratteri

 diviso in un elenco di stringhe

' +$'⎕R'' PCRE sostituisce gli spazi finali (qualsiasi numero di spazi seguito da un fine riga) con nulla


1

Japt , 29 byte

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

Provalo online!

Aggiornato per conformarsi a una formattazione di output più rigorosa.

Emette come un elenco di pezzi con ogni pezzo rappresentato da un elenco di linee, usando 2 come carattere di riempimento.

Spiegazione:

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

Hai dimenticato di rimuovere tutto il trailing falsedagli elenchi interni. Qui un pastebin in modo da poter spiegare meglio ciò che dovrebbe essere l'output. Sentiti libero di chiedere a OP di chiarire, ma per quanto ho capito dalla sfida, tutti gli spazi bianchi finali non dovrebbero essere presenti nell'output.
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

Provalo online!

Prende una stringa separata da nuova riga, restituisce un elenco di stringhe separate da nuova riga. Utilizza textwrap.dedentper sbarazzarsi di spazi iniziali.


@AdmBorkBork Trascurato tale regola, risolto
Black Owl Kai

0

Gelatina , 19 byte

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

Provalo online!

Un collegamento monadico che prende la matrice come input e restituisce un elenco di un elenco irregolare per pezzo. Piè di pagina mostra questo graziosamente, ma penso che l'output senza che sia coerente con le regole della domanda.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.