Conectar los píxeles

40

Dado un texto como este:

# #### ## #
## #  ##  #
   ####  ##

Imprime el mismo texto pero conectando los píxeles con los caracteres ─│┌┐└┘├┤┬┴┼. Si un píxel no tiene vecinos, no lo cambie.

Entonces la salida del último texto es:

│ ─┬── ┌─ │
└─ │  ┌┘  │
   └──┘  ─┘
  • Puede tomar la entrada como una matriz booleana.
  • La entrada siempre contendrá al menos 1 píxel.
  • Puede contar los caracteres de dibujo de caja como 1 byte.
  • Puede suponer que la entrada está rellenada con espacios.

Casos de prueba

## #
=>
── #
###
 #
=>
─┬─
 │
##### ##
 # #  #
########
=>
─┬─┬─ ┌─
 │ │  │
─┴─┴──┴─
 # #
#####
 # #
=>
 │ │
─┼─┼─
 │ │
# # # # #
 # # # #
# # # # #
 # # # #
# # # # #
=>
# # # # #
 # # # #
# # # # #
 # # # #
# # # # #
#####
#####
#####
#####
#####
=>
┌┬┬┬┐
├┼┼┼┤
├┼┼┼┤
├┼┼┼┤
└┴┴┴┘

Como se trata de , gana el código más corto.

TuxCrafting
fuente
2
¿Debo usar el carácter hash como píxel? ¿Puedo recibir información como una matriz booleana?
Rohan Jhunjhunwala
¿Puede haber espacios finales o líneas nuevas?
Sanchises
BTW: -|r7LJE3TW+es un reemplazo adecuado de 1 byte-char para los caracteres de bloque.
Tito

Respuestas:

7

Gelatina , 60 52 51 50 49 48 bytes

ṖḤ0;+Ḋ×
“µ³Q~E!G⁸ṗṫ\’ḃ61+9471Ọ⁾# j
ZÑ€4×Z++Ñ€ị¢Y

Salvó un byte gracias a @ Dennis.

La entrada es una matriz booleana de 1 y 0. Itera sobre cada columna y cada fila convirtiendo la cabeza y la cola de cada infijo de tamaño 3 de un par de dígitos binarios a un decimal, y lo multiplica con el centro de cada infijo. Luego lo resume consigo mismo para encontrar el índice '#───│┌┐┬│└┘┴│├┤┼ '.

Pruébalo en línea! ( caso 2 ) ( caso 3 ) ( caso 4 )

Explicación

Esto se basa en la misma idea que mi respuesta en J, pero en lugar de procesar en cada submatriz de 3x3, proceso sobre cada fila y cada columna mientras obtengo la misma tabla de índices.

Más de la mitad de los bytes se gastan generando la lista de caracteres de cuadro '#───│┌┐┬│└┘┴│├┤┼ '. Los literales de cadena comienzan con Jelly y tienen diferentes significados según su terminador. Aquí el terminador significa que la cadena se analizará como los puntos de código de cada carácter de acuerdo con la página de códigos Jelly , y se convertirá de una lista de 250 dígitos de base a un decimal.

“µ³Q~E!G⁸ṗṫ\’ => 10041542192416299030874093
(bijective base 61) => [1, 1, 1, 3, 13, 17, 45, 3, 21, 25, 53, 3, 29, 37, 61]
(add 9471 and convert to char) => '───│┌┐┬│└┘┴│├┤┼'

Luego, convierta ese decimal a una lista de dígitos en la base 61 del biyetivo e incremente cada uno en 9471 para moverlo al rango de los caracteres del cuadro y conviértalos usando Python chr. Luego, agréguele un carácter literal ”#y agregue un espacio .

ṖḤ0;+Ḋ×  Helper link - Input: 1d list A
Ṗ        Get all of A except the last value
 Ḥ       Double each value in it
  0;     Prepend a 0
    +    Add elementwise with
     Ḋ     All of A except the first value
      ×  Multiply elementwise by A

“µ³Q~E!G⁸ṗṫ\’ḃ61+9471Ọ⁾# j  Nilad. Represents '#───│┌┐┬│└┘┴│├┤┼ '
“µ³Q~E!G⁸ṗṫ\’               Get the code points of each char in the string and
                            convert from a list of base 250 digits to decimal
             ḃ61            Convert that to a list of digits in bijective base 61
                +9471       Add 9400 to each
                     Ọ      Convert from ordinals to chars, gets '───│┌┐┬│└┘┴│├┤┼'
                      ⁾#    A pair of chars ['#', ' ']
                         j  Join the pair using the box characters

ZÑ€4×Z++Ñ€ị¢Y  Input: 2d list M
Z              Transpose
 р            Apply the helper link to each row of the transpose (each column of M)
   4×          Multiply each by 4
     Z         Transpose
      +        Add elementwise with M
       +       Add elementwise with
        р       The helper link applied to each row of M
          ị¢   Use each result as an index to select into the nilad
            Y  Join using newlines
               Return and print implicitly
millas
fuente
15

J , 82 72 66 bytes

(ucp' #───│┌┐┬│└┘┴│├┤┼'){~]+]*3 3((2#.1 7 3 5{,);._3)0,.~0,.0,~0,]

La entrada es una tabla booleana de 1 y 0. Las reglas establecen que los caracteres del cuadro cuentan como un byte, no tres, y eso se ha aplicado aquí.

Uso

   f =: (ucp' #───│┌┐┬│└┘┴│├┤┼'){~]+]*3 3((2#.1 7 3 5{,);._3)0,.~0,.0,~0,]
   m =: 1 0 1 1 1 1 0 1 1 0 1 , 1 1 0 1 0 0 1 1 0 0 1 ,: 0 0 0 1 1 1 1 0 0 1 1
   m { ' #'
# #### ## #
## #  ##  #
   ####  ##
   f m
│ ─┬── ┌─ │
└─ │  ┌┘  │
   └──┘  ─┘
   ' #' {~ m =: 5 5 $ 1
   f m
┌┬┬┬┐
├┼┼┼┤
├┼┼┼┤
├┼┼┼┤
└┴┴┴┘
   ' #' {~ m =: 5 9 $ 1 0
# # # # #
 # # # # 
# # # # #
 # # # # 
# # # # #
   f m
# # # # #
 # # # # 
# # # # #
 # # # # 
# # # # #

Explicación

Primero, la entrada se rellena con 0 en todos los lados.

   ] m =: 1 0 1 1 1 1 0 1 1 0 1 , 1 1 0 1 0 0 1 1 0 0 1 ,: 0 0 0 1 1 1 1 0 0 1 1
1 0 1 1 1 1 0 1 1 0 1
1 1 0 1 0 0 1 1 0 0 1
0 0 0 1 1 1 1 0 0 1 1
   (0,.~0,.0,~0,]) m
0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 1 1 1 1 0 1 1 0 1 0
0 1 1 0 1 0 0 1 1 0 0 1 0
0 0 0 0 1 1 1 1 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0

Luego se selecciona cada subconjunto de tamaño 3

   3 3 <;._3 (0,.~0,.0,~0,]) m
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│
│0 1 0│1 0 1│0 1 1│1 1 1│1 1 1│1 1 0│1 0 1│0 1 1│1 1 0│1 0 1│0 1 0│
│0 1 1│1 1 0│1 0 1│0 1 0│1 0 0│0 0 1│0 1 1│1 1 0│1 0 0│0 0 1│0 1 0│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│0 1 0│1 0 1│0 1 1│1 1 1│1 1 1│1 1 0│1 0 1│0 1 1│1 1 0│1 0 1│0 1 0│
│0 1 1│1 1 0│1 0 1│0 1 0│1 0 0│0 0 1│0 1 1│1 1 0│1 0 0│0 0 1│0 1 0│
│0 0 0│0 0 0│0 0 1│0 1 1│1 1 1│1 1 1│1 1 0│1 0 0│0 0 1│0 1 1│1 1 0│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│0 1 1│1 1 0│1 0 1│0 1 0│1 0 0│0 0 1│0 1 1│1 1 0│1 0 0│0 0 1│0 1 0│
│0 0 0│0 0 0│0 0 1│0 1 1│1 1 1│1 1 1│1 1 0│1 0 0│0 0 1│0 1 1│1 1 0│
│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘

Entonces, solo se consideran 5 de los valores en cada submatriz

┌───┐
│xAx│
│CED│
│xBx│
└───┘

Los valores ABCDse seleccionan al acoplar cada submatriz y seleccionar en los índices 1 7 3 5. Esos valores se multiplican por Ecuál está en el índice 4. Luego se convierte de una lista de dígitos binarios a un decimal, y se incrementa en E. Los xvalores no son necesarios.

   3 3 (4&{([+2#.*)1 7 3 5&{)@,;._3 (0,.~0,.0,~0,]) m
 5 0 2  8 4 3  0  6 3 0  5
10 3 0 13 0 0  6 11 0 0 13
 0 0 0 10 4 4 11  0 0 2 11

Esto se usa como índice para seleccionar qué personaje dibujar de acuerdo con la tabla a continuación (reordenado un poco para jugar al golf). La última columna hace coincidir el valor de salida de cada submatriz con un carácter de cuadro.

 0  (space)  0
 1  #        1
 2  ┌        6
 3  ┬        8
 4  ┐        7
 5  ├        14
 6  ┼        16
 7  ┤        15
 8  └        10
 9  ┴        12
10  ┘        11
11  │        5, 9, 13
12  ─        2, 3, 4

Además, en J, la cadena ' #───│┌┐┬│└┘┴│├┤┼'utiliza caracteres de 8 bits, por lo que tiene una longitud de 47 (por cada byte) para los 17 caracteres necesarios. El comando lo ucpconvierte en caracteres de 16 bits, lo que le permite tener una longitud de 17.

millas
fuente
13

JavaScript (ES6), 155 121 103 102 caracteres

let f =
    
s=>s.replace(/#/g,(c,p)=>'#│─┘─└─┴││┐┤┌├┬┼'[t=x=>s[p+x]==c,8*t(w=s.search`
`+1)+4*t(1)+2*t(-1)+t(-w)])

console.log(f(
  '# #### ## #\n' +
  '## #  ##  #\n' +
  '   ####  ##'
));

Edición: guardado 18 bytes con la ayuda de ETHproductions
Edición: guardada 1 byte utilizando el primer parámetro de replace () como'#'

Cómo funciona

Repetimos todos los #caracteres encontrados en la cadena de entrada. Para cada uno de ellos, probamos si sus vecinos también son #personajes que usan la t()función:

t = x => s[p + x] == c  // where c = '#'

El parámetro xde la t()función es el desplazamiento del vecino con respecto a la posición actual p. Usamos -1 / + 1 para probar vecinos izquierdo / derecho y -w / + w para vecinos superiores / inferiores (donde wes el ancho de una fila, es decir, la posición del primer salto de línea + 1).

A cada vecino se le asigna un peso diferente (1, 2, 4 u 8) de acuerdo con la siguiente brújula:

  1
2 + 4
  8

Cada combinación de peso conduce a un valor único en [0 .. 15]. Por ejemplo, si se configuran tanto el vecino en la parte superior como el vecino a la derecha, la suma será 1 + 4 = 5, que se traduce al uso de esta tabla:

00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
#  │  ─  ┘  ─  └  ─  ┴  │  │  ┐  ┤  ┌  ├  ┬  ┼

Por lo tanto, '#│─┘─└─┴││┐┤┌├┬┼'[weight_sum]conduce al carácter esperado.

Arnauld
fuente
Ja, teníamos básicamente la misma idea;)
ETHproductions
@ETHproductions: más o menos. ^^
Arnauld
Realmente, muy buena técnica allí. Me has superado con creces :)
ETHproductions
Puede guardar 2 bytes así:s=>(w=s[0].length+1,s=s.join`\n`).replace(/#/g,(_,p)=>'#│─┘─└─┴││┐┤┌├┬┼'[t=x=>s[p+x]>' ',t(-w)+2*t(-1)+4*t(1)+8*t(w)])
ETHproductions
Y en realidad es mucho más corto volver a una cadena multilínea:s=>s.replace(/#/g,(_,p)=>'#│─┘─└─┴││┐┤┌├┬┼'[t=x=>s[p+x]>' ',t(-w)+2*t(-1)+4*t(1)+8*t(w)],w=s.indexOf`\n`+1)
ETHproductions
8

Python 2.7, 318 315 bytes ( 270 267 caracteres)

Estoy seguro de que esto se puede jugar más (particularmente me encantaría deshacerme de ese molesto comentario de primera línea) pero aquí está mi entrada:

#encoding:utf-8
f=lambda t:(lambda l,s:'\n'.join(''.join((u'┼├┤│┬┌┐│┴└┘│───#'[(s==l[i][j-1])+2*(s==l[i][j+1])+4*(i<1 or s==l[i-1][j])+8*(i>len(l)-2 or s==l[i+1][j])],s)[s==l[i][j]]for j in range(len(l[i])-1))for i in range(len(l))))([l+' 'for l in t.split('\n')],' ')

Aquí hay una explicación de cómo funciona todo:

#encoding:utf-8 # Dammit, Python. This adds an extra 16 bytes!
f=lambda t:( # main lambda function
    lambda l,s: # inner lambda so we can pass it "local constants" (see last line)
        '\n'.join( # join each line
            ''.join( # join each char within the line
                (u'┼├┤│┬┌┐│┴└┘│───#'[ # string of all possible characters, indexed by binary 0-15 based on adjacent chars
                    (s==l[i][j-1])+ # left
                    2*(s==l[i][j+1])+ # right
                    4*(i<1 or s==l[i-1][j])+ # up ('i<1' just yields zero in case this is the first line, so that we don't get index problems)
                    8*(i>len(l)-2 or s==l[i+1][j])], # down ('i>len(l)-2' is same as above)
                s)[s==l[i][j]] # if original is space, choose space, else choose the previously chosen box-drawing char
                for j in range(len(l[i])-1)) # do this process for each char (excluding last, which is a space)
            for i in range(len(l))) # do this for each line
    )([l+' ' for l in t.split('\n')],' ') # call the inner lambda with two parameters: first, the text split into lines; second, a space char (actually makes code shorter)

EDITAR: se eliminaron algunos espacios antes for ... in ...

Hactar
fuente
9
En su lugar, usar Python 3 debería resolver su problema de codificación Unicode, creo ...
Byte Commander
6

JavaScript (ES6), 150 139 133 131 caracteres

a=>a.map((q,y)=>q.replace(/#/g,(c,x)=>"#│─┘─└─┴││┐┤┌├┬┼"[g=(X,Y=0)=>(a[Y+y]||[])[X+x]==c,g(0,1)*8+g(1)*4+g(-1)*2+g(0,-1)])).join`
`

Toma la entrada como un conjunto de cadenas, por ejemplo f(["###", " # "]).

Fragmento de prueba

ETHproducciones
fuente
5

ALPACA , 414 + 2 = 416 bytes

neighbourhoodV(^ v < >);states" ";statep"#"toA when4inV p,toB when3inV p andvs,toC when3inV p and^s,toD when3inV p and>s,toE when3inV p and<s,toF when2inV p and>s andvs,toG when2inV p andvs and<s,toH when2inV p and<s and^s,toI when2inV p and^s and>s,toJ when^p orvp,toK when<p or>p;stateA"┼";stateB"┴";stateC"┬";stateD"┤";stateE"├";stateF"┘";stateG"└";stateH"┌";stateI"┐";stateJ"│";stateK"─".

Requiere las -fIbanderas.

Esta solución usa una gran cantidad de bytes, pero es única en el sentido de que usa un autómata celular. ALPACA generalmente se usa como metalenguaje, pero aquí lo estoy usando como lenguaje de programación.

Versión sin golf:

neighbourhood V (^ v < >);
state s " ";
state p "#" to A when 4 in V p,
to B when 3 in V p and v s,
to C when 3 in V p and ^ s,
to D when 3 in V p and > s,
to E when 3 in V p and < s,
to F when 2 in V p and > s and v s,
to G when 2 in V p and v s and < s,
to H when 2 in V p and < s and ^ s,
to I when 2 in V p and ^ s and > s,
to J when ^ p or v p,
to K when < p or > p;
state A "┼";
state B "┴";
state C "┬";
state D "┤";
state E "├";
state F "┘";
state G "└";
state H "┌";
state I "┐";
state J "│";
state K "─".
DanTheMan
fuente
4

PHP, 203 bytes

Esto probablemente se puede hacer de una manera más corta.

while($s=fgets(STDIN))$f[]=$s;foreach($f as$y=>&$s)for($x=strlen($s);$x--;)if($s[$x]>$b=" ")$s[$x]="#───│┘└┴│┐┌┬│┤├┼"[($s[$x-1]>$b)+2*($s[$x+1]>$b)+4*($f[$y-1][$x]>$b)+8*($f[$y+1][$x]>$b)];echo join($f);

lee la entrada de STDIN. correr con -r.

Titus
fuente
4

Python 3, 149 bytes

def f(s):S=' ';w=s.find('\n')+1;t=lambda i:(s+w*S)[i]>S;return[[c,'#│─┘─└─┴││┐┤┌├┬┼'[t(p-w)+2*t(p-1)+4*t(p+1)+8*t(p+w)]][c>S]for p,c in enumerate(s)]

Toma entrada como ##\n #\ny devuelve salida como ['─', '┐', '\n', ' ', '│', '\n'].

Lynn
fuente
3

R, 199 212 bytes

EDITAR: ahora es una función, en lugar de un fragmento de código.

La entrada es una matriz mde 1s y 0s. Esto es bastante feo y hacky.

function(m){
v=strsplit(" #─│┘│┐│┤──└┴┌┬├┼","")[[1]]
d=dim(m)+1
n=array(0,dim=d+1)
n[2:d[1],2:d[2]]=m
for(i in 0:(d[1]-2)){for(j in 0:(d[2]-2))cat(v[1+(p<-n[2+i,2+j])*sum(2^(0:3)*n[1:3+i,1:3+j][1:4*2])+p]);cat("\n")}
}

Un par de pruebas:

> m = matrix(c(1, 1, 1, 0, 1, 0), nrow=2, byrow=TRUE)
> v=strsplit(" #─│┘│┐│┤──└┴┌┬├┼","")[[1]]
> d=dim(m)+1
> n=array(0,dim=d+1)
> n[2:d[1],2:d[2]]=m
> for(i in 0:(d[1]-2)){for(j in 0:(d[2]-2))cat(v[1+(p<-n[2+i,2+j])*sum(2^(0:3)*n[1:3+i,1:3+j][1:4*2])+p]);cat("\n")}
─┬─
 │ 
> m = matrix(rep(1, 16), ncol=4)
> v=strsplit(" #─│┘│┐│┤──└┴┌┬├┼","")[[1]]
> d=dim(m)+1
> n=array(0,dim=d+1)
> n[2:d[1],2:d[2]]=m
> for(i in 0:(d[1]-2)){for(j in 0:(d[2]-2))cat(v[1+(p<-n[2+i,2+j])*sum(2^(0:3)*n[1:3+i,1:3+j][1:4*2])+p]);cat("\n")}
┌┬┬┐
├┼┼┤
├┼┼┤
└┴┴┘
rturnbull
fuente
La presentación debe ser un programa completo o una función. Leer de una variable existente no es una forma permitida de entrada.
TuxCrafting
¿Cómo logras que algunos de los personajes Unicode funcionen bien con R? x = "\ U253C" funciona pero x = "┼" no.
Vlo
@ TùxCräftîñg: arreglado ahora!
rturnbull
@Vlo utf-8 es mi codificación nativa del sistema operativo. x = "┼"funciona bien para mí
rturnbull
3

Perl, 89 88 bytes

Incluye +2 para -0p . Los caracteres especiales se cuentan como 1 byte, pero para que se muestren como caracteres individuales, lo mejor es agregar también la opción -C.

Dé entrada en STDIN con el espacio de líneas rellenado para que todos tengan la misma longitud:

perl -C connect.pl
# #### ## #
## #  ##  #
   ####  ##
^D

connect.pl:

#!/usr/bin/perl -0p
/
/;$n=".{@-}";s%#%substr"#───│└┘┴│┌┐┬│├┤┼",/\G##/+2*/#\G/+4*/#$n\G/s+8*/\G#$n#/s,1%eg
Ton Hospel
fuente
1

MATL, 102 caracteres

Asigno un valor a un vecino (1, 2, 4 u 8); su suma coincidirá con un carácter en una cadena que contiene los caracteres del dibujo. Creo que todavía hay mucho espacio para mejoras, pero para un borrador:

' #│││─┌└├─┐┘┤─┬┴┼' % String to be indexed
wt0J1+t4$(          % Get input, and append zeros at end of matrix (solely to avoid
                    %  indexing a non-existent second row/column for small inputs)
ttttt               % Get a whole load of duplicates to work on
3LXHY)              % Select rows 2:end from original matrix (one of the many dupes)
      w4LXIY)       % Select rows 1:end-1 from the 'destination' summing matrix)
             +HY(   % Add the neighbors below, store in 'destination' matrix
tIY)b3LY)2*+IY(     % +2* the neighbors above    +-------------------------------+
tHZ)b4LZ)4*+HZ(     % +4* the neighbors right    |(note: H and I contain 1:end-1 |
tIZ)b3LZ)8*+IZ(     % +8* the neighbors left     |  and 2:end respectively)      |
HH3$)               % Select the original matrix +-------------------------------+
*                % Make sure only cells that originally had a # get replaced
  1+)            % Add one because the original string is one-indexed. Index using ).

Mejoras a realizar:

  • Posiblemente reemplace toda la parte sumadora con algún tipo de bucle que funcione en copias rotadas de la matriz
  • Deshazte de todo y crea algo basado en un solo bucle que funcione a través de la matriz
  • Utilice la indexación modular para trabajar en un vector plano de la matriz original (?)

Pruébalo en línea! (puede no tener soporte para caracteres de dibujo de recuadro)

Sanchises
fuente