X marca el lugar

18

X marca el lugar

Su objetivo es agregar una cruz alrededor de la X mayúscula:

Ejemplo de entrada / salida

Entrada:

                mdhyyyyyyyhhhddmmm                
            mdyyssoo  oooosyyyhhhdmm              
          hsso     oossoooooyyhhdhhdmmm           
        yoooooo     oo ssysssyhhdyyyhmmmm         
      myso oso  o  oyo    hhhdhhyhyhhm mm m       
     mhsyhhys  oss      yyyhhhsosyhhmmmmdmmm
    mhyhhhy y         ssyhoho o shhdmmmmdmmmm        
    hhyyyh   s   oo syysyyhhdysso oyhdhhhmmmmm     
   dhysyys      sdysoXoyyyyhhso     syshm  mmm    
   hhyhyo       o      osss y   shhyyhd mmmmmm    
   yyhyyyss           o  oyyyydmmdmmmmmmmmm mm    
   ysyhyhhho   s     osy  sdm m  mddmmddhydmmm   
   h  oshhhyyyddhoo  ooyysshdmdohdmmdmddsshmmm    
    y   oyhhhdhhsyhsssshdddsss    hdddyyyhddm     
    dyyshyyhssyyhyyyyddhhmmdmmmdy syssoosyhdm     
     hsyyhhhhsoo sooyyhhdoohdhhyhyysoo  osdm      
      doyhhhyyyyhhhysyyy oossyyssso   osydm       
        soyhyyhhhhhhyhyyyooos       ohdddm        
         msoyyyyyyyhyyyyo ooo       syyd          
            ho oyyysooo    osso   osyd            
               dhyyysssyyyyyysoosdm               
                    mmdddddmmm                    

Salida:

                mdhyyyyyyyhhhddmmm                
            mdyyssoo  oooosyyyhhhdmm              
          hsso     oossoooooyyhhdhhdmmm           
        yoooooo     oo ssysssyhhdyyyhmmmm         
      myso oso  o  oyo    hhhdhhyhyhhm mm m       
     mhsyhhys  oss   |  yyyhhhsosyhhmmmmdmmm
    mhyhhhy y        |ssyhoho o shhdmmmmdmmmm        
    hhyyyh   s   oo s|ysyyhhdysso oyhdhhhmmmmm     
   dhysyys      -----X-----hhso     syshm  mmm    
   hhyhyo       o    | osss y   shhyyhd mmmmmm    
   yyhyyyss          |o  oyyyydmmdmmmmmmmmm mm    
   ysyhyhhho   s     |sy  sdm m  mddmmddhydmmm   
   h  oshhhyyyddhoo  ooyysshdmdohdmmdmddsshmmm    
    y   oyhhhdhhsyhsssshdddsss    hdddyyyhddm     
    dyyshyyhssyyhyyyyddhhmmdmmmdy syssoosyhdm     
     hsyyhhhhsoo sooyyhhdoohdhhyhyysoo  osdm      
      doyhhhyyyyhhhysyyy oossyyssso   osydm       
        soyhyyhhhhhhyhyyyooos       ohdddm        
         msoyyyyyyyhyyyyo ooo       syyd          
            ho oyyysooo    osso   osyd            
               dhyyysssyyyyyysoosdm               
                    mmdddddmmm               

Entrada:

000000000000
000000000000
0000X0000000
0000000X0000
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000
000000000000

Salida:

     |
 0000|00|0000
 0000|00|0000
-----X--+--00
 00--+--X-----
 0000|00|0000
 0000|00|0000
 0000000|0000
 000000000000
 000000000000
 000000000000
 000000000000
 000000000000

Entrada:

00000000000000000
00000000000000000
00000000000000000
00000X000X0000000
00000000000000000
00000000000000000
00000000000000000
00000000000000000
00000000000000000
00000000000000000
00000000000000000
00000000000000000   

Salida:

00000|000|0000000
00000|000|0000000
00000|000|0000000
----+#+++#+----00
00000|000|0000000
00000|000|0000000
00000|000|0000000
00000000000000000
00000000000000000
00000000000000000
00000000000000000
00000000000000000    

Punto de mira

Su punto de mira debe ser de 3 de alto y 5 de ancho:

     |
     |
     |
-----X-----
     |
     |
     |

Entrada

La entrada tendrá un tamaño de al menos 12x12 caracteres y consistirá solo en caracteres ASCII. Se puede tomar a través de STDIN o argumento de función. La entrada no siempre contendrá una X. La entrada tendrá cualquier forma y tendrá una cantidad arbitraria de espacios en blanco. La entrada no contendrá ninguna de: +, -, #, y|

Salida

La salida puede ser a través de STDOUT o el valor de retorno de una función. La salida debe ser la imagen de entrada con la cruz dibujada. Si no hay suficiente espacio para dibujar la cruz, debe agregar líneas / espacios para dibujarla. Los puntos superpuestos deben reemplazarse con a +. Si el |o -del retículo se superpone , debería aparecer un X, en lugar de un .+#

El espacio en blanco al final no está permitido, excepto para una nueva línea al final.


Este es el código de golf, ¡el código más corto en bytes gana!

Downgoat
fuente
1
1. si la entrada es un argumento, ¿tiene que ser una cadena con líneas separadas por líneas nuevas, o puede ser una matriz de cadenas? 2. ¿Es aceptable agregar espacios en blanco alrededor del diseño, incluso si no es necesario (es decir, siempre agregue 3 filas arriba / abajo y 5 columnas a la izquierda / derecha)? 3. Falta la entrada para el tercer caso de prueba.
Level River St el
@steveverrill 1. Será una cadena separada por una nueva línea, no una matriz de cadenas 2. No, eso no está permitido. Puede usar eso en su código, pero no debería aparecer en la salida
Downgoat
3
¿Se +superpone -y se |aplica solo cuando esos caracteres son parte de la mira, o afecta literalmente -y se |encuentra también en la entrada?
DLosc
1
@DLosc esos no estarán en la entrada. He actualizado la pregunta
Downgoat
1
¿Qué pasa si #un punto de mira encuentra un literal en la entrada? ¿Se sobreescribirá?
Kodos Johnson

Respuestas:

3

CoffeeScript, 345 336   327 bytes

Z=(s,c)->s in'X#'&&'#'||s in'-|+'&&'+'||c
X=(s)->l=u=0;o=(r.split ''for r in s.split '\n');c in'X#'&&(i-x&&(o[y][i]=Z o[y][i],'-';i<l&&l=i)for i in[x-5..x+5];i-y&&((o[i]?=[])[x]=Z o[i][x],'|';i<u&&u=i)for i in[y-3..y+3])for c,x in r for r,y in o;((o[y][x]||' 'for x in[l...o[y].length]).join ''for y in[u...o.length]).join '\n'

X es la función para llamar.

Explicado:

# get new char. s - old char. c - '|' or '-'
Z=(s,c)->s in'X#'&&'#'||s in'-|+'&&'+'||c

X=(s)->

  # leftmost and upmost positions
  l=u=0

  # split input into 2D array
  o=(r.split ''for r in s.split '\n')

  # for every 'X' or '#'
  c in'X#'&&(

    # for positions to left and right
    i-x&&(

        # draw horisontal line
      o[y][i]=Z o[y][i],'-'

      # update leftmost position
      i<l&&l=i

    )for i in[x-5..x+5]

    # for positions above and below
    i-y&&(

      # add row if necessary and draw vertical line
      (o[i]?=[])[x]=Z o[i][x],'|'

      # update upmost position
      i<u&&u=i

    )for i in[y-3..y+3]

  )for c,x in r for r,y in o

  # concatenate into string, replacing empty chars with spaces
  ((o[y][x]||' 'for x in[l...o[y].length]).join ''for y in[u...o.length]).join '\n'

Ejecutable:

metalim
fuente
1
¡345 es demasiado bueno! Estoy tratando de acercarme, pero hasta ahora estás muy por delante. No sé si puedo hacer mucho más sin cambiar mi enfoque por completo ... Hmm :)
Dom Hastings
Hasta que alguien venga con CJam / Pyth / GolfScript y haga sub-100. Pero gracias.
metalim
Hah ... Demasiado cierto ... Me pregunto si este debería ser el estímulo que necesito para aprender Pyth ...
Dom Hastings
4

Python 3, 577 519 515 490 475 467 454 bytes

def c(g,d):
 R,L,V,e,b=range,list,len,'-|+','#';t,g=(lambda g,d:sum([[(i,j)for j in R(V(L(g.split('\n')[i])))if g.split('\n')[i][j]==d]for i in R(V(g.split('\n')))],[]))(g,d),[L(i)for i in g.split('\n')]
 for a,r in t:
  for j in R(a-3,a+4):
   if V(g)>j>-1:n=g[j][r];g[j][r]='+'if n in e else'#'if n in(d,b)else'|'
  for j in R(r-5,r+6):
   if V(g[a])>j>-1:n=g[a][j];g[a][j]='+'if n in e else'#'if n in(d,b)else'-'
 return'\n'.join(''.join(l)for l in g)

No estoy seguro de cuánto más puedo jugar golf.

Uso:

c(g, d)

Dónde gestá la cuadrícula de entrada y des el carácter de marca de cruz.

Puertas de Zach
fuente
3

Perl, 370 bytes

sub r{$h=pop;($=[$n=pop].=$"x(1+"@_"-length$=[$n]))=~s!(.{@_})(.)!"$1".($2=~/[-|+]/?'+':$2=~/[X#]/?'#':$h)!e}map{chop;push@c,[$-,pos]while/X/g;$-++}@==<>;($x,$y)=@$_,3-$x>$a?$a=3-$x:0,$x+5-@=>$b?$b=$x+5-@=:0,6-$y>$c?$c=6-$y:0 for@c;@==($",@=)for 1..$a;$_=$"x$c.$_ for@=;map{($x,$y)=@$_;$_&&r$y+$c+$_-1,$x+$a,'-'for-5..5;$_&&r$y+$c-1,$x+$_+$a,'|'for-3..3}@c;print@=,$,=$/

Uso, guardar arriba como xmarks.pl:

perl xmarks.pl <<< 'X'

No estoy seguro de cuánto más pequeño puedo hacer esto, ¡pero estoy seguro de que volveré a hacerlo más tarde! Podría publicar una explicación si alguien también está interesado.

Maneja la entrada de entradas Xno cuadradas también ahora.

Dom Hastings
fuente
2

Python 2, 755 706 699 694 678 626 Bytes

Espera entrada en stdin, con una nueva línea final. El final de la entrada se activa con cmd+d.

import sys;a=sys.stdin.readlines();b=max;c=len;d=enumerate;e=c(b(a,key=lambda x:c(x)))-1;a=[list(line.replace('\n','').ljust(e))for line in a];R=range;f=lambda:[[i for i,x in d(h)if x=='X']for h in a+[[]]*4];q=lambda y,z:'#'if z=='X'else'+'if z in'|-+'else y;g=f();h=j=k=l=0
for m,n in d(g):
 if n:h=b(3-m,h);l=b(abs(n[0]-5),l);j=b(m-c(a)+4,j);k=b(n[-1]-e+6,k)
o=[' ']*(l+k+e);a=[o for _ in R(h)]+[[' ']*l+p+[' ']*k for p in a]+[o for _ in R(j)];g=f()
for m,x in d(a):
 for i in[3,2,1,-1,-2,-3]:
    for r in g[m+i]:x[r]=q('|',x[r])
 for r in g[m]:
    for i in R(5,0,-1)+R(-1,-6,-1):x[r+i]=q('-',x[r+i])
for s in a:print''.join(s)

Programa completo:

import sys

lines = sys.stdin.readlines()

# pad all lines with spaces on the right
maxLength = len(max(lines, key=lambda x:len(x))) - 1 # Subtract the newline
lines = [list(line.replace('\n', '').ljust(maxLength)) for line in lines]


def findX():
    global xs
    xs = [[i for i, ltr in enumerate(line) if ltr == 'X'] for line in lines+[[]]*4]

# add sufficient padding to the edges to prevent wrap
findX()
top,bottom,right,left=0,0,0,0
for ind, item in enumerate(xs):
    if item:
        top = max(3-ind, top)
        left = max(abs(item[0]-5), left)
        bottom = max(ind-len(lines)+4, bottom)
        right = max(item[-1]-maxLength+6, right)
clear = [' '] * (left+right+maxLength)
lines = [clear for _ in range(top)] + [[' ']*left + line + [' ']*right for line in lines] + [clear for _ in range(bottom)]



findX()
def chooseChar(expected, curr):
    return '#' if curr == 'X' else ('+' if curr in '|-+' else expected)

for ind, x in enumerate(lines):
    # try:
        for i in [3, 2, 1, -1, -2, -3]:
            for elem in xs[ind+i]:
                x[elem] = chooseChar('|', x[elem])
        for elem in xs[ind]:
            for i in [5, 4, 3, 2, 1, -1, -2, -3, -4, -5]:
                x[elem+i] = chooseChar('-', x[elem+i])
    # except:f



for line in lines: print(''.join(line))

Estoy seguro de que se podría hacer mucho más golf en esto (ya que todavía estoy aprendiendo Python), por lo que cualquier ayuda es apreciada.

Ediciones

  1. Afeitado de unos 50 bytes findXmediante el uso de comprensiones
  2. Guardado 7 bytes gracias a la sugerencia de @ mbomb007 sobre el uso en rangelugar de una matriz literal
  3. Se eliminaron 5 bytes cambiando findXa una lambda
  4. Ahorró 15 bytes extendiendo xspor 4 y eliminando el try-exceptbloqueo
  5. Afeitado 2 más usando pestañas en lugar de espacios
  6. Se eliminaron 5 bytes usando en h=i=j=k=l=0lugar deh,j,k,l=0,0,0,0
  7. Gracias a @ mbomb007, eliminé unos 40 bytes más de chooseChar
J Atkin
fuente
1
Debe definir R=rangeacortar los rangos. Entonces también puedes cambiar for i in[5,4,3,2,1,-1,-2,-3,-4,-5]:afor i in R(5,0,-1)+R(-1,-6,-1):
mbomb007
¡Gracias! Había pensado en hacer eso, pero parecía que sería más largo.
J Atkin
¡Buen trabajo para recortar! No estoy seguro si ha visto los hilos de las sugerencias, pero puede haber algunos acortadores que puede obtener desde aquí: codegolf.stackexchange.com/questions/54/…
Dom Hastings
Lo hice hace unos días, pero olvidé algunas cosas.
J Atkin
También tu q lambda me parece muy ineficiente. ¿Se puede acortar eso? Por lo menos, no creo que los paréntesis sean necesarios, pero creo que la lógica booleana y las comparaciones de cadenas también se pueden acortar.
mbomb007