Piezas de rompecabezas de matriz


10

(Aleatoriamente inspirado por https://codegolf.meta.stackexchange.com/a/17272/42963 )

Dada una matriz rectangular de dígitos (es decir, 0 - 9), genera las "piezas" de la matriz como si los dígitos estuvieran conectados entre sí formando una sola pieza, en orden ascendente por los dígitos. Se garantiza que las piezas se conecten solo de forma ortogonal; ninguna pieza se conectará diagonalmente. Solo habrá un máximo de 10 piezas (es decir, una 3pieza no aparecerá dos veces en la misma matriz).

Por ejemplo, dada la matriz

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

Las siguientes son las piezas y un resultado de ejemplo:

0
0 0

1 1 1
  1

  2
2 2

3 3

El espacio es importante para mantener la forma de las piezas, pero las piezas no necesariamente necesitan espacio interior. Las piezas en sí mismas deben diferenciarse de alguna manera consistente (por ejemplo, una nueva línea entre las piezas, asegurándose de que cada una sea un personaje diferente, etc.). Además, no se permiten espacios en blanco extraños (por ejemplo, líneas nuevas o columnas iniciales). Por ejemplo, lo siguiente también sería válido:

0
00
111
 1
 2
22
33

o

#
##

###
 #

 #
##

##

Pero lo siguiente no sería (tenga en cuenta los espacios finales detrás de la 0s):

0      
0 0    

Las rotaciones o reflejos tampoco están permitidos. Por ejemplo, la salida

 1
111

para la matriz anterior también es inválida.

Las piezas de la matriz pueden tener agujeros o ser solo un elemento:

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

O, la pieza puede ser la matriz completa:

0 0 0
0 0 0

Aquí hay un caso de prueba más grande y complicado:

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

Y un ejemplo de salida:

00

11111

 22
222
2

3

444
 44

55
5
5

6666
6  66
666

 77
  7
777

88

9

Reglas y E / S

  • La entrada y salida se pueden dar por cualquier método conveniente .
  • Puede imprimirlo en STDOUT o devolverlo como resultado de una función.
  • Un programa completo o una función son aceptables.
  • 1Se requiere un espacio en blanco inicial para mantener la forma (p. Ej., La forma de "T" del ejemplo), se necesita un espacio en blanco consistente para distinguir las piezas y se permite una nueva línea final al final, pero no se permite ningún otro espacio en blanco.
  • Puede suponer con seguridad que las piezas están numeradas 0de forma Ncontigua, lo que significa que (por ejemplo) 3no se omitirán en una matriz de seis piezas.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).

¿Puede la salida ser realmente una lista de las piezas? ¿O las E / S no se hacen con cadenas sino con matrices y enteros (con -1o un espacio que representa un espacio vacío, o la ausencia de un elemento si es posible)?
Erik the Outgolfer

¿Es aceptable si la entrada se basa en 1 (no contiene ceros) y la salida se usa 0como valor de relleno? Por lo tanto, cada pieza se generará con el resto de los valores en la matriz establecida en0
Luis Mendo el

Independientemente de mi pregunta anterior: no se permite ningún otro espacio en blanco : ¿ni siquiera los espacios finales para hacer que todas las líneas tengan la misma longitud?
Luis Mendo

@EriktheOutgolfer La ausencia de un elemento estaría bien, ya que eso solo genera la "pieza". Sin embargo, generar una matriz completa para cada pieza con -1o algún otro valor en lugar de nada / espacio en blanco no estaría bien.
AdmBorkBork

@AdmBorkBork Oh, entonces, ¿debería ' 'usarse el espacio ( ) en ese caso?
Erik the Outgolfer

Respuestas:


2

05AB1E , 20 19 bytes

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

-1 byte gracias a @ Mr.Xcoder .

Produce listas 2D de piezas (con 1caracteres y espacios " ") por nueva línea.

Pruébelo en línea o verifique todos los casos de prueba o imprima con letra bonita todos los casos de prueba .

Explicación:

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 bytes

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

Toma la matriz como una lista de cadenas y devuelve una lista de la lista de cadenas.

Pruébalo en línea!

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

Jalea , 18 bytes

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

Pruébalo en línea!

Devuelve una lista de piezas, donde 1representa una parte de una pieza y ' 'está rellenando. ' 'Se eliminan los s finales .


ẎQ=€debería hacerlo, aunque necesitamos las piezas en orden ascendente, entonces 9Ż=€(a menos que no debamos incluir "piezas inexistentes" en cuyo caso ẎQṢ=€)
Jonathan Allan

@JonathanAllan Solucionó el problema, aunque estoy bastante seguro de 9Ż=€que no funcionará (creo que "los espacios en blanco [...] extraños no están permitidos" también se extienden a los arreglos, por eso estoy recortando).
Erik the Outgolfer

Sí, eso tiene sentido.
Jonathan Allan el

2

Python 3 , 271 209 206 183 176 172 191 bytes

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

Pruébalo en línea!

Editar: Un poco de limpieza y -5 gracias a @ Jonathan Frech .

Editar: -3 -26, una vez más gracias a @ Jonathan Frech .

Editar: -7 nuevamente gracias a @ Jonathan Frech .

Editar: +19: Como lo señaló @ nimi, la salida anterior tenía un formato incorrecto.


La entrada es matriz como lista de listas:

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

La salida es una lista de matrículas:

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

Sin golf:

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 bytes

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)

Pruébalo en línea!

-15 bytes de una observación de nimi .

En forma de programa, toma como entrada una lista de listas de caracteres individuales; salidas imprimiendo las piezas encontradas usando su personaje.


@AdmBorkBork - Correcto, omití ese criterio. Corregido ahora.
Chas Brown el


1

Python 2 , 291 bytes

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'

Pruébalo en línea!

Espera una picadura delimitada por comillas como entrada. Un porcentaje semi-ridículo del código está dedicado a manejar entradas sin espacios separados / sin espacios.

Explicación sin 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'

Puede especificar el formato de entrada (por ejemplo, como una lista de listas o como un párrafo separado por espacios) si hace que su código sea más atractivo.
AdmBorkBork

1

Retina , 75 bytes

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

.$
$&¶

Pruébalo en línea! Explicación:

$
¶9

Agregue un dígito a la entrada. Esto representa el contador de bucle. La nueva línea simplifica la eliminación del espacio en blanco final.

.-10{

Inhibe la salida predeterminada y repite exactamente 10 veces.

T`9d`d`.$

Avanzar el dígito del bucle.

*;(

Genere el resultado del resto del script pero luego restaure el búfer.

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

Reemplace todos los dígitos que no coincidan con los dígitos del bucle con espacios. (Debido a que esto usa una búsqueda anticipada y no hay nada que mirar hacia adelante en este punto, esto también reemplaza el dígito del bucle).

 +¶
¶

Elimine todo el espacio en blanco al final.

G`\d

Eliminar todas las líneas en blanco.

/^\d|^$/m^+

Repita siempre que ninguna línea comience con un dígito ...

m`^.

... borra el primer caracter en cada línea.

.$
$&¶

Si queda algo, entonces agregue una nueva línea para separar cada forma de la siguiente. (Esto se hace para evitar nuevas líneas perdidas por dígitos faltantes).


Se garantiza que nunca habrá un "dígito faltante" si eso hace que su código sea más corto.
AdmBorkBork

@AdmBorkBork No creo que eso ayude. Lo que sería más probable que ayude es no tener que generar las piezas en orden numérico. eso está permitido?
Neil

No, eso es la mitad del desafío, de lo contrario sería demasiado fácil. ;-)
AdmBorkBork

1

Carbón , 43 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

WS⊞υι

Lea la entrada en una matriz. (Esto podría eliminarse si usara un formato de entrada feo).

Fχ«

Recorre los 10 dígitos.

≔Φυ№κIιθ

Obtenga las filas que contienen esos dígitos.

¿θ«

Verifique que se haya encontrado el dígito (para evitar generar nuevas líneas falsas).

UT

Desactiva el relleno automático.

Fθ«

Pase sobre las filas encontradas.

Fκ«

Pase sobre cada columna ...

¿⁼λIιλ→»

... si el carácter de entrada actual es igual al dígito del bucle actual, imprímalo o mueva el cursor hacia la derecha.

M±Lκ¹»

Ir al inicio de la siguiente fila. El uso de comandos de movimiento como este le permite a Charcoal recortar la salida en ambos lados.

D⎚

Volcar y despejar el lienzo listo para el siguiente dígito. Esto permite que los diferentes dígitos tengan diferentes cantidades de recorte.

Intenté un enfoque programático pero pesaba 47 bytes, aunque también habría sido de 43 bytes durante un breve período de tiempo cuando se Equalsvectorizó:

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

UT

Desactiva el relleno automático.

WS⊞υι

Lea la entrada en una matriz.

Fχ«

Recorre los 10 dígitos.

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

Compare cada carácter con la entrada y cree una matriz booleana, pero luego filtre las filas sin coincidencias.

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

Pase por las filas restantes y corte desde la primera coincidencia en cualquier fila hasta la última coincidencia en la fila actual, luego asigne la matriz booleana a dígitos o espacios, que luego se imprimen implícitamente como una matriz de cadenas.


1

Wolfram Language 101 bytes

Tiene que haber una forma mucho más eficiente de lograr esto.

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

1

Perl 5, 97 bytes

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

TIO

Explicación

-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) , SBCS de 38 bytes

Función de prefijo tácito anónimo. Toma una matriz numérica como argumento y devuelve una lista de cadenas de listas. Cada lista de cadenas representa una pieza con 1s separados por espacios . Los espacios iniciales e internos (pero no finales) son espacios.

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

Pruébalo en línea!

∪∘, Los elementos únicos de la matriz ravel (aplanada)

⊂{ Para cada uno de esos , llame a la siguiente función con toda la matriz como :

⍺=⍵ indicar dónde está el número de esa pieza en la matriz

 rendimiento que (se separa 2de )

{... }⍣2 aplique la siguiente función dos veces ( es la matriz booleana):

  ∨/ máscara para filas con al menos una 1(iluminada reducción OR por fila)

  ⍵⌿⍨ usar eso para filtrar las filas

   transponer (entonces hacemos esto también en las columnas, luego transponemos de regreso)

' '@~ reemplazar con espacios en las posiciones donde no (es decir, donde 0)

 formatear como matriz de caracteres

 dividido en una lista de cadenas

' +$'⎕R'' PCRE reemplaza los espacios finales (cualquier número de espacios seguidos de un final de línea) con nada


1

Japt , 29 bytes

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

Pruébalo en línea!

Actualizado para cumplir con un formato de salida más estricto.

Sale como una lista de piezas con cada pieza representada por una lista de líneas, usando 2 como el carácter de relleno.

Explicación:

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

Olvidó eliminar todo el final falsede las listas internas. Aquí un pastebin para que pueda explicar mejor lo que se supone que es la salida. Siéntase libre de pedirle a OP que aclare, pero por lo que entiendo del desafío, todos los espacios en blanco finales no deberían estar allí en la salida.
Kevin Cruijssen

0

Python 3 , 133 bytes

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

Pruébalo en línea!

Toma una cadena separada por una nueva línea, devuelve una lista de cadenas separadas por una nueva línea. Usos textwrap.dedentpara deshacerse de los espacios principales.


@AdmBorkBork Pasó por alto esa regla, corregida
Black Owl Kai

0

Jalea , 19 bytes

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

Pruébalo en línea!

Un enlace monádico que toma la matriz como entrada y devuelve una lista de una lista irregular por pieza. El pie de página muestra esto con precisión, pero creo que la salida sin eso es consistente con las reglas de pregunta.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.