X menandai titiknya

18

X menandai titiknya

Tujuan Anda adalah menambahkan tanda silang di sekitar ibukota X:

Contoh Input / Output

Memasukkan:

                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                    

Keluaran:

                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               

Memasukkan:

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

Keluaran:

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

Memasukkan:

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

Keluaran:

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

Crosshair

Rambut lintas Anda harus 3-tinggi dan 5-lebar:

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

Memasukkan

Input berukuran paling tidak 12x12 karakter dan hanya terdiri dari karakter ASCII. Ini dapat diambil melalui argumen fungsi atau STDIN. Input tidak akan selalu berisi X. Input akan dalam bentuk apa pun dan memiliki jumlah spasi kosong yang sewenang-wenang. Input tidak akan mengandung dari: +, -, #, dan|

Keluaran

Output dapat melalui STDOUT atau nilai pengembalian fungsi. Output harus berupa gambar input dengan garis rambut ditarik. Jika tidak ada cukup ruang untuk menggambar crosshair, Anda harus menambahkan garis / spasi untuk menggambarnya. Tempat yang tumpang tindih harus diganti dengan a +. Jika garis bidik |atau -garis lintang tumpang tindih X, bukannya a +, #harus muncul.

Trailing whitespace tidak diperbolehkan kecuali untuk satu baris baru di bagian paling akhir.


Ini adalah kode-golf sehingga kode terpendek dalam byte menang!

Downgoat
sumber
1
1. jika input adalah argumen, apakah harus berupa string dengan garis yang dipisahkan oleh baris baru, atau bisakah itu menjadi array string? 2. apakah bisa menambahkan spasi putih di sekitar desain meskipun tidak perlu (yaitu selalu menambahkan 3 baris di atas / di bawah dan 5 kolom di sebelah kiri / kanan)? 3. Input tidak ada untuk case uji ke-3.
Level River St
@steveverrill 1. Ini akan menjadi string yang dipisahkan baris baru, bukan array dari string 2. Tidak, itu tidak diperbolehkan. Anda dapat menggunakannya dalam kode Anda tetapi itu tidak akan muncul di output
Downgoat
3
Apakah +untuk tumpang tindih -dan |hanya berlaku ketika karakter tersebut merupakan bagian dari bidik silang, atau apakah itu mempengaruhi literal -dan |ditemukan dalam input juga?
DLosc
1
@ Dlosc itu tidak akan ada di input. Saya telah memperbarui pertanyaan
Downgoat
1
Bagaimana jika literal #dalam input ditemui oleh crosshair? Apakah akan ditimpa?
Kodos Johnson

Jawaban:

3

CoffeeScript, 345 336   327 byte

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 adalah fungsi untuk memanggil.

Dijelaskan:

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

Dapat dieksekusi:

metalim
sumber
1
345 terlalu bagus! Saya mencoba untuk mendekati, tetapi Anda jauh di depan sejauh ini! Saya tidak tahu apakah saya bisa melakukan lebih banyak lagi tanpa mengubah pendekatan saya sepenuhnya ... Hmm :)
Dom Hastings
Sampai seseorang datang dengan CJam / Pyth / GolfScript dan membuat sub-100. Tapi terima kasih.
metalim
Hah .. Terlalu benar ... Saya bertanya-tanya apakah ini harus menjadi dorongan yang saya butuhkan untuk belajar Pyth ...
Dom Hastings
4

Python 3, 577 519 515 490 475 467 454 byte

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)

Saya tidak yakin seberapa jauh saya bisa bermain golf ini.

Pemakaian:

c(g, d)

Di mana gkisi masukan dan dkarakter tanda-silang.

Zach Gates
sumber
3

Perl, 370 byte

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

Penggunaan, simpan di atas sebagai xmarks.pl:

perl xmarks.pl <<< 'X'

Saya tidak yakin seberapa kecil saya bisa membuat ini, tapi saya yakin saya akan kembali lagi nanti! Saya mungkin memposting penjelasan jika ada yang tertarik juga.

Menangani input Xdan input non-kuadrat juga sekarang.

Dom Hastings
sumber
2

Python 2, 755 706 699 694 678 626 Bytes

Diharapkan input pada stdin, dengan baris baru tambahan. Akhir input dipicu dengan 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)

Program lengkap:

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

Saya yakin bahwa lebih banyak bermain golf dapat dilakukan dalam hal ini (karena saya masih belajar python), jadi bantuan apa pun sangat dihargai.

Suntingan

  1. Dicukur sekitar 50 byte dari findX dengan menggunakan untuk pemahaman
  2. Disimpan 7 byte berkat saran @ mbomb007 tentang penggunaan range alih-alih array literal
  3. Dihapus 5 byte dengan mengubah findX ke lambda
  4. Disimpan 15 byte dengan memperluas xs dengan 4 dan menghilangkantry-except blok
  5. Bercukur 2 lebih banyak dengan menggunakan tab, bukan spasi
  6. Dihapus 5 byte dengan menggunakan h=i=j=k=l=0bukanh,j,k,l=0,0,0,0
  7. Berkat @ mbomb007, saya menghapus sekitar 40 byte lebih banyak dari chooseChar
J Atkin
sumber
1
Anda harus menentukan R=rangeuntuk mempersingkat rentang. Kemudian Anda juga dapat mengubah for i in[5,4,3,2,1,-1,-2,-3,-4,-5]:kefor i in R(5,0,-1)+R(-1,-6,-1):
mbomb007
Terima kasih! Saya sudah berpikir untuk melakukan itu tetapi sepertinya itu akan lebih lama.
J Atkin
Kerja bagus untuk mengurangi! Saya tidak yakin apakah Anda telah melihat utas ujungnya, tetapi mungkin ada beberapa pemendek yang bisa Anda dapatkan dari sini: codegolf.stackexchange.com/questions/54/…
Dom Hastings
Saya melakukannya beberapa hari yang lalu, tetapi saya lupa beberapa hal.
J Atkin
Juga, qlambda Anda tampaknya sangat tidak efisien bagi saya. Bisakah itu dipersingkat sama sekali? Paling tidak, saya tidak berpikir tanda kurung diperlukan, tapi saya pikir logika boolean dan perbandingan string dapat dipersingkat juga.
mbomb007