X marque l'endroit

18

X marque l'endroit

Votre objectif est d'ajouter un réticule autour du X majuscule:

Exemple d'entrée / sortie

Contribution:

                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                    

Production:

                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               

Contribution:

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

Production:

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

Contribution:

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

Production:

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

Réticule

Votre réticule doit être un 3 de haut et 5 de large:

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

Contribution

L'entrée aura au moins 12 x 12 caractères et ne sera composée que de caractères ASCII. Il peut être récupéré via STDIN ou un argument de fonction. L'entrée ne contiendra pas toujours un X. L'entrée aura n'importe quelle forme et aura une quantité arbitraire d'espaces. L'entrée ne contiendra aucune de: +, -, #et|

Production

La sortie peut se faire via STDOUT ou la valeur de retour d'une fonction. La sortie doit être l'image d'entrée avec le réticule dessiné. S'il n'y a pas assez d'espace pour dessiner le réticule, vous devez ajouter des lignes / espaces pour le dessiner. Les taches qui se chevauchent doivent être remplacées par a +. Si le |ou -du réticule chevauche un X, au lieu d'un +, un #devrait apparaître.

Les espaces blancs de fin ne sont pas autorisés, sauf pour une seule nouvelle ligne à la toute fin.


C'est le code-golf donc le code le plus court en octets gagne!

Downgoat
la source
1
1. si l'entrée est un argument, doit-il s'agir d'une chaîne avec des lignes séparées par des retours à la ligne, ou peut-il s'agir d'un tableau de chaînes? 2. est-il acceptable d'ajouter des espaces autour du motif même si cela n'est pas nécessaire (c'est-à-dire toujours ajouter 3 lignes au-dessus / en dessous et 5 colonnes à gauche / à droite)? 3. L'entrée est manquante pour le 3e cas de test.
Level River St
@steveverrill 1. Ce sera une chaîne séparée par des sauts de ligne, pas un tableau de chaînes 2. Non, cela n'est pas autorisé. Vous pouvez utiliser cela dans votre code mais cela ne devrait pas apparaître dans la sortie
Downgoat
3
Est-ce que le +chevauchement -et |s'applique uniquement lorsque ces caractères font partie du réticule, ou cela affecte-t-il le littéral -et se |trouve-t-il également dans l'entrée?
DLosc
1
@DLosc ceux-ci ne seront pas en entrée. J'ai mis à jour la question
Downgoat
1
Que faire si un littéral #dans l'entrée est rencontré par un réticule? Sera-t-il écrasé?
Kodos Johnson

Réponses:

3

CoffeeScript, 345 336   327 octets

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 est la fonction à appeler.

Expliqué:

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

Exécutable:

metalim
la source
1
345 est trop bon! J'essaie de me rapprocher, mais tu as déjà une longueur d'avance! Je ne sais pas si je peux faire beaucoup plus sans changer complètement mon approche ... Hmm :)
Dom Hastings
Jusqu'à ce que quelqu'un vienne avec CJam / Pyth / GolfScript et fasse moins de 100. Mais merci.
metalim
Hah .. Trop vrai ... Je me demande si cela devrait être l'encouragement dont j'ai besoin pour apprendre le Pyth ...
Dom Hastings
4

Python 3, 577 519 515 490 475 467 454 octets

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)

Je ne sais pas jusqu'où je peux jouer au golf.

Usage:

c(g, d)

gest la grille d'entrée et dle caractère de réticule.

Zach Gates
la source
3

Perl, 370 octets

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@=,$,=$/

Utilisation, enregistrez ci-dessus comme xmarks.pl:

perl xmarks.pl <<< 'X'

Je ne sais pas combien je peux faire plus petit, mais je suis sûr que j'y reviendrai plus tard! Je pourrais poster une explication si quelqu'un est intéressé aussi.

Gère également les entrées Xet les entrées non carrées.

Dom Hastings
la source
2

Python 2, 755 706 699 694 678 626 octets

Attend une entrée sur stdin, avec une nouvelle ligne de fin. La fin de l'entrée est déclenchée avec 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)

Programme complet:

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

Je suis sûr que beaucoup plus de golf pourrait être fait à ce sujet (puisque j'apprends encore le python), donc toute aide est appréciée.

Modifications

  1. Rasé à environ 50 octets de findX aide de pour la compréhension
  2. 7 octets enregistrés grâce à la suggestion de @ mbomb007 sur l'utilisation range au lieu d'un tableau littéral
  3. Suppression de 5 octets en changeant findX à un lambda
  4. 15 octets enregistrés en étendant xsde 4 et en éliminant letry-except blocage
  5. Rasé 2 de plus en utilisant des tabulations au lieu d'espaces
  6. Suppression de 5 octets en utilisant h=i=j=k=l=0au lieu deh,j,k,l=0,0,0,0
  7. Grâce à @ mbomb007, j'ai supprimé environ 40 octets supplémentaires de chooseChar
J Atkin
la source
1
Vous devez définir R=rangepour raccourcir les plages. Ensuite, vous pouvez également changer for i in[5,4,3,2,1,-1,-2,-3,-4,-5]:pourfor i in R(5,0,-1)+R(-1,-6,-1):
mbomb007
Merci! J'avais pensé à faire ça, mais il semblait que ce serait plus long.
J Atkin
Bon travail sur la coupe! Je ne sais pas si vous avez vu les discussions sur les astuces, mais vous pouvez obtenir quelques raccourcis à partir d'ici: codegolf.stackexchange.com/questions/54/…
Dom Hastings
Je l'ai fait il y a quelques jours, mais j'ai oublié certaines choses.
J Atkin
De plus, votre qlambda me semble très inefficace. Cela peut-il être raccourci du tout? À tout le moins, je ne pense pas que les parenthèses soient nécessaires, mais je pense que la logique booléenne et les comparaisons de chaînes peuvent également être raccourcies.
mbomb007