Conecte os pixels


40

Dado um texto como este:

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

Produza o mesmo texto, mas conectando os pixels aos caracteres ─│┌┐└┘├┤┬┴┼. Se um pixel não tiver vizinhos, não o altere.

Portanto, a saída do último texto é:

│ ─┬── ┌─ │
└─ │  ┌┘  │
   └──┘  ─┘
  • Você pode receber a entrada como uma matriz booleana.
  • A entrada sempre conterá pelo menos 1 pixel.
  • Você pode contar caracteres de desenho de caixa como 1 byte.
  • Você pode assumir que a entrada é preenchida com espaços.

Casos de teste

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

Como esse é o , o código mais curto vence.


2
Devo usar o caractere de hash como um pixel? Posso receber entrada como uma matriz booleana?
Rohan Jhunjhunwala

Pode haver espaço à direita ou nova linha (s)?
Sanchises 20/09/16

btw: -|r7LJE3TW+é uma substituição de 1 byte-char adequada para os caracteres do bloco.
Titus

Respostas:


7

Geléia , 60 52 51 50 49 48 bytes

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

Guardou um byte graças a @ Dennis.

A entrada é uma matriz booleana de 1 e 0. Repete cada coluna e cada linha, convertendo a cabeça e a cauda de cada infixo do tamanho 3 de um par de dígitos binários para um decimal e multiplica isso pelo centro de cada infixo. Em seguida, soma-o para encontrar o índice '#───│┌┐┬│└┘┴│├┤┼ '.

Experimente online! ( caso 2 ) ( caso 3 ) ( caso 4 )

Explicação

Isso se baseia na mesma idéia da minha resposta em J, mas em vez de processar em cada sub-matriz 3x3, eu processo sobre cada linha e cada coluna enquanto ainda obtenho a mesma tabela de índices.

Mais da metade dos bytes são gastos na geração da lista de caracteres da caixa '#───│┌┐┬│└┘┴│├┤┼ '. Os literais de string começam com Jelly e têm significados diferentes, dependendo do terminador. Aqui, o terminador significa que a cadeia será analisada como os pontos de código de cada caractere, de acordo com a página de código Jelly , e convertida de uma lista de 250 dígitos base para um 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) => '───│┌┐┬│└┘┴│├┤┼'

Em seguida, converta esse decimal em uma lista de dígitos na base bijetiva 61 e aumente cada um em 9471 para movê-lo para o intervalo dos caracteres da caixa e converter cada um usando o Python chr. Em seguida, ”#acrescente um caractere literal e um espaço .

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

15

J , 82 72 66 bytes

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

A entrada é uma tabela booleana de 1 e 0. As regras afirmam que os caracteres da caixa contam como um byte, não como três, e que foram aplicados aqui.

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

Explicação

Primeiro, a entrada é preenchida com zeros em todos os 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

Em seguida, cada sub-matriz de tamanho 3 é selecionada

   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│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘

Então, apenas 5 dos valores em cada sub-matriz são considerados

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

Os valores ABCDsão selecionados achatando cada sub-matriz e selecionando os índices 1 7 3 5. Esses valores são multiplicados pelo Eque está no índice 4. Em seguida, é convertido de uma lista de dígitos binários para um decimal e incrementado por E. Os xvalores não são necessários.

   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

Isso é usado como um índice para selecionar qual caractere desenhar de acordo com a tabela abaixo (reordenada um pouco para jogar golfe). A última coluna corresponde ao valor de saída de cada sub-matriz com um caractere de caixa.

 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

Além disso, em J, a cadeia de caracteres ' #───│┌┐┬│└┘┴│├┤┼'usa caracteres de 8 bits, com um comprimento de 47 (para cada byte) para os 17 caracteres necessários. O comando o ucpconverte em caracteres de 16 bits, o que permite o comprimento 17.


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' +
  '   ####  ##'
));

Edit: salvou 18 bytes com a ajuda de ETHproductions
Edit: salvou 1 byte usando o 1º parâmetro de replace () como'#'

Como funciona

Nós iteramos em todos os #caracteres encontrados na string de entrada. Para cada um deles, testamos se seus vizinhos também são #caracteres usando a t()função:

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

O parâmetro xda t()função é o deslocamento do vizinho em relação à posição atual p. Usamos -1 / + 1 para testar vizinhos esquerdo / direito e -w / + w para vizinhos superior / inferior (onde wé a largura de uma linha, ou seja, a posição da primeira quebra de linha + 1).

Cada vizinho recebe um peso diferente (1, 2, 4 ou 8) de acordo com a seguinte bússola:

  1
2 + 4
  8

Cada combinação de peso leva a um valor único em [0 .. 15]. Por exemplo, se o vizinho no topo e o vizinho à direita estiverem definidos, a soma será 1 + 4 = 5, que é traduzida para o uso desta tabela:

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

Portanto, '#│─┘─└─┴││┐┤┌├┬┼'[weight_sum]leva ao caractere esperado.


Ha, tivemos basicamente a mesma ideia;)
ETHproductions

@ETHproductions - Praticamente. ^^
Arnauld

Realmente, muito boa técnica lá. Você solidamente out-golfed me :)
ETHproductions

Você pode salvar 2 bytes assim: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

E, na verdade, é muito mais curto retornar a uma cadeia de 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)
linhas múltiplas

8

Python 2.7, 318 315 bytes ( 270 267 caracteres)

Tenho certeza de que isso pode ser ainda mais influenciado (especialmente eu adoraria me livrar desse comentário irritante de primeira linha), mas aqui está a minha 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')],' ')

Aqui está uma explicação de como tudo funciona:

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

EDIT: Removido alguns espaços antes for ... in ...


9
Usando Python 3 em vez deve resolver o seu problema de codificação Unicode, eu acho ...
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`
`

Recebe entrada como uma matriz de strings, por exemplo f(["###", " # "]).

Snippet de teste


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"─".

Requer as -fIbandeiras.

Essa solução usa um número muito grande de bytes, mas é única na medida em que usa um autômato celular. O ALPACA é geralmente usado como uma metalinguagem, mas aqui estou usando-o como uma linguagem de programação.

Versão não destruída:

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 "─".

4

PHP, 203 bytes

Provavelmente isso pode ser feito de uma maneira mais curta.

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

lê a entrada de STDIN. corra com -r.


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 como entrada ##\n #\ne retorna como saída ['─', '┐', '\n', ' ', '│', '\n'].


3

R, 199 212 bytes

EDIT: Agora é uma função, em vez de um trecho de código.

A entrada é uma matriz mde 1s e 0s. Isso é muito feio e 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")}
}

Alguns testes:

> 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")}
┌┬┬┐
├┼┼┤
├┼┼┤
└┴┴┘

O envio deve ser um programa completo ou uma função. Ler de uma variável existente não é uma forma de entrada permitida.
TuxCrafting

Como você faz com que alguns dos caracteres unicode funcionem bem com o R? x = "\ U253C" funciona, mas x = "┼" não.
Vlo

@ TùxCräftîñg: Corrigido agora!
precisa saber é o seguinte

@Vlo utf-8 é a minha codificação nativa do SO. x = "┼"funciona muito bem para mim.
rturnbull

3

Perl, 89 88 bytes

Inclui +2 para -0p. Os caracteres especiais são contados como 1 byte, mas para torná-los realmente exibidos como caracteres únicos, é melhor adicionar também a opção -C.

Dê entrada no STDIN com o espaço de linhas preenchido para que todos tenham o mesmo comprimento:

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

1

MATL, 102 caracteres

Atribuo um valor a um vizinho (1, 2, 4 ou 8); sua soma corresponderá a um caractere em uma sequência que contém os caracteres de desenho. Eu acho que ainda há muito espaço para melhorias, mas para um rascunho:

' #│││─┌└├─┐┘┤─┬┴┼' % 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 ).

Melhorias a serem feitas:

  • Possivelmente substitua toda a parte da soma por algum tipo de loop trabalhando em cópias rotacionadas da matriz
  • Abandone a coisa toda e faça algo com base em um único loop trabalhando através da matriz
  • Use a indexação modular para trabalhar em um vetor nivelado da matriz original (?)

Experimente Online! (pode não ter suporte para caracteres de desenho de caixa)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.