Xはスポットをマークします


18

Xスポットをマーク

あなたの目標は、首都Xの周りに十字線を追加することです:

入力/出力の例

入力:

                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                    

出力:

                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               

入力:

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

出力:

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

入力:

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

出力:

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

十字線

十字線は、高さが3で幅が5である必要があります。

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

入力

入力は少なくとも12x12文字で、ASCII文字のみで構成されます。STDINまたは関数の引数を使用して取り込むことができます。入力には常にXが含まれるわけではありません。入力は任意の形状で、任意の量の空白が含まれます。:入力のいずれかを含んでいないだろう+-#、および|

出力

出力は、STDOUTまたは関数の戻り値を介して行うことができます。出力は、十字線が描かれた入力画像でなければなりません。十字線を描画するのに十分なスペースがない場合は、線/スペースを追加して描画する必要があります。重複するスポットはに置き換える必要があり+ます。場合|-十字線の重複X、代わりに+#表示されます。

末尾の単一の改行を除き、末尾の空白は許可されません。


これはコードゴルフなので、バイト単位の最短コードが勝ちです!


1
1.入力が引数である場合、改行で区切られた行を持つ文字列である必要がありますか、それとも文字列の配列であることができますか?2.不要な場合でも、デザインの周りに空白を追加することは許容されますか(つまり、常に上下に3行、左右に5列を追加します)。3. 3番目のテストケースの入力がありません。
レベルリバーセント

@steveverrill 1.文字列の配列ではなく、改行で区切られた文字列になります2.いいえ、許可されていません。コードでそれを使用できますが、出力に表示されるべきではありません
-Downgoat

3
+の重複のために-と、|これらの文字は、十字線の一部である、またはそれは文字通りの影響を与えないときにのみ適用されます-|、同様の入力で見られますか?
DLosc

1
@DLoscは入力に含まれません。質問を更新しました
-Downgoat

1
#入力内のリテラルが十字線に遭遇した場合はどうなりますか?上書きされますか?
コドスジョンソン

回答:


3

CoffeeScript、345 336   327バイト

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 呼び出す関数です。

説明:

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

実行可能ファイル:


1
345が良すぎる!私は近づこうとしていますが、あなたはこれまでのところ先を行っています!アプローチを完全に変えずにもっと多くのことができるかどうかわからない...うーん:)
ドムヘイスティングス

誰かがCJam / Pyth / GolfScriptを使ってサブ100になるまで。でもありがとう。
metalim

これは私がPythを学ぶ必要が激励するかどうほら..あまりにも真の...私は...思ったんだけど
ドムヘイスティングス

4

Python 3、577 519 515 490 475 467 454バイト

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)

これをどれだけ遠くまでゴルフできるかわかりません。

使用法:

c(g, d)

どこgに入力グリッドdがあり、十字線のマーク文字です。


3

Perl、370バイト

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

使用法、上記として保存xmarks.pl

perl xmarks.pl <<< 'X'

これをどれだけ小さくできるかはわかりませんが、後でまた戻ってくるでしょう。誰もが興味を持っているなら、私は説明を投稿するかもしれません。

ハンドルの入力Xとなりました非正方形の入力としても。


2

Python 2、755 706 699 694 678 626バイト

末尾に改行を付けて、stdinに入力を期待します。入力の終了はでトリガーされ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)

完全なプログラム:

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

(私はまだPythonを学んでいるので)もっと多くのゴルフができると確信しているので、どんな助けでも大歓迎です。

編集

  1. findX内包表記を使用して、 約50バイト削った
  2. rangeリテラル配列の代わりに使用する ことについての@ mbomb007の提案のおかげで7バイトを節約しました
  3. findXラムダに変更して 5バイトを削除
  4. xs4を拡張してtry-exceptブロック を削除することで15バイトを節約しました
  5. スペースの代わりにタブを使用してさらに2を剃った
  6. h=i=j=k=l=0代わりにを使用して5バイトを削除しましたh,j,k,l=0,0,0,0
  7. @ mbomb007のおかげで、さらに約40バイトを削除しました chooseChar

1
R=range範囲を短くするように定義する必要があります。その後、次のように変更for i in[5,4,3,2,1,-1,-2,-3,-4,-5]:することもできますfor i in R(5,0,-1)+R(-1,-6,-1):
mbomb007

ありがとう!私はそれをすることを考えていましたが、それはもっと長くなるようでした。
Jアトキン

トリミングの良い仕事!私はあなたが、先端のスレッドを見てきたかどうかわからないんだけど、あなたはここから得ることができるいくつかの短縮サービスがあるかもしれません:codegolf.stackexchange.com/questions/54/...
ドムヘイスティングス

数日前にやりましたが、いくつかのことを忘れていました。
Jアトキン

また、あなたのqラムダは私にとって非常に非効率的です。それはまったく短縮できますか?少なくとも、括弧は必要ないと思いますが、ブール論理と文字列比較も短縮できると思います。
mbomb007
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.