X 찾기
나는 주어진 모양에 대해 “X 찾기”를 요구하는 수학 문제에 영감을 받았습니다. 원래, 나는 문자 ‘x’의 x와 y 위치를 문자열로 인쇄하는 것이 어려웠습니다. 그러나 나는 그것이 너무 간단하다고 생각했습니다. 그래서 나는 그들이 일반적으로있는 맥락을 고려하고 x 옆에있는 줄의 길이를 찾는 것이 적절하다고 판단했습니다.
단일 ‘x’와 잠재적으로 정크 문자뿐만 아니라 ascii ‘line’다이어그램을 포함하는 문자열 입력이 주어지면 ‘x’가 직접 연결된 유일한 행의 길이를 인쇄하십시오.
예
입력:
|
|
|x
|
|
출력 :
5
입력:
|\
| \x
| \
|___\
산출:
4
입력:
Diagram of a Wobbly Line:
IRRELEVANTTEXT____
____ ____/
\___/ X ;)
x
산출:
3
입력:
______________
/ ____________ \
|/ __________ \|
||/ ________ \||
|||/ ______ \|||
||||/ \||||
|||||/ x |||||
|||||\_____/||||
||||\_______/|||
|||\_________/||
||\___________/|
\_____________/
산출:
5
노트
- 유효한 줄 문자는
\/_|
\
왼쪽 상단과 오른쪽 하단을 연결합니다./
오른쪽 상단과 왼쪽 하단을 연결합니다._
왼쪽과 오른쪽을 연결합니다|
자체의 상단과 하단을 연결- 줄은 항상 직선이며 n 번 반복되는 줄 문자 중 하나로 만 구성됩니다.
- x는 항상 소문자이며 다이어그램에서 항상 유일한 것입니다.
- Adjecent는 x가 정확히 위, 아래 또는 옆에있는 한 문자임을 나타냅니다.
- x는 항상 정확히 한 줄 옆에 있습니다.
- 입력에 탭이 나타나지 않습니다.
- 입력 및 출력은 허용되는 형식 일 수 있습니다.
- 이것은 코드 골프이므로 최단 코드가 승리합니다!
- 재미있다. 해. 너 자신을 즐겨.
답변
자바 스크립트 (ES6), 165155 바이트
편집 : 더 많은 바이트를 저장하기 위해 인라인 된 x 및 w .
골프를 쳤다
(입력이 사각형으로 만들어지는 공백으로 채워져 있다고 가정)
t=>([k=e=o=1,v=t.search`\n`+2,-1,-v].some(h=>i=({"|":v-1,"_":1,"/":v,"\\":v})[d=t[r=l=t.search`x`+h]]),[...t].map(_=>o+=(k&=t[l-=i]==d)+(e&=t[r+=i]==d)),o)
넓히는
/*
G(<input string,space padded>) => line length
*/
G=t=> {
/*
! Note that these two are inlined, in the "golfed" version !
"w" - line "width"
"x" - index of "x"
*/
x=t.search`x`;
w=t.search`\n`+1;
/*
Locate the "line"
l,r - left cursor, right cursor (for navigating along the line)
k - left stop flag, e - right stop flag
i - increment
d - direction (char)
*/
[k=e=o=1,v=w+1,-1,-w-1].some(h=>i=({"|":w,"_":1,"/":v,"\\":v})[d=t[r=l=x+h]]);
/*
Travel along the line axis in both directions
Note, the stop condition should rather be: while(k|e),
but we iterate over all the chars with map instead (as o is guaranteed to be < # chars),
to save some space
*/
[...t].map(_=>o+=(k&=t[l-=i]==d)+(e&=t[r+=i]==d));
/*
Resulting line length
*/
return o;
};
테스트
G=
t=>([k=e=o=1,v=t.search`\n`+2,-1,-v].some(h=>i=({"|":v-1,"_":1,"/":v,"\\":v})[d=t[r=l=t.search`x`+h]]),[...t].map(_=>o+=(k&=t[l-=i]==d)+(e&=t[r+=i]==d)),o);
[
G(
"| \n" +
"| \n" +
"|x\n" +
"| \n" +
"| \n"
),
G(
"|\\ \n" +
"| \\x \n" +
"| \\ \n" +
"|___\\\n"
),
G(
"Diagram of a Wobbly Line:\n" +
"IRRELEVANTTEXT____ \n" +
"____ ____\/ \n" +
" \___\/ X ;) \n" +
" x \n"
),
G(
" ______________ \n" +
"/ ____________ \\\n" +
"|/ __________ \\|\n" +
"||/ ________ \\||\n" +
"|||/ ______ \\|||\n" +
"||||/ \\||||\n" +
"|||||/ x |||||\n" +
"|||||\_____\/||||\n" +
"||||\_______\/|||\n" +
"|||\_________\/||\n" +
"||\___________\/|\n" +
" \_____________\/\n"
)
]
샘플 출력 (Chrome 개발자 도구 콘솔에서 실행하는 경우)
[5, 4, 3, 5]
답변
파이썬 3 428 408 385 378 바이트
작동하지만 골프를 치기에는 엄청난 잠재력이 있습니다. 나는 조금 녹슬었다.
사각형을 만들기 위해 공백이 채워져 있다고 가정합니다.
편집 : 23 바이트 절약을위한 @Artyer 덕분에!
EDIT2 : 와우 6 바이트 절약을 완전히 놓쳤습니다. 등호 검사의 측면을 바꾸어 1 개 더 절약했습니다.
*i,=map(list,input().split('\n'))
r=c=s=q=e=w=0
o=lambda y,x:len(i[0])>x>=0<=y<len(i)
d='\/_|'
for l in i:
if'x'in l:r=i.index(l);c=l.index('x')
for a,b in(1,0),(0,1),(-1,0),(0,-1):
y,x=r+a,c+b;f=o(y,x)and i[y][x]
if f in d:s=f;w=d.index(f);q,e=y,x
k=lambda y,x,g=[1,1,0,1][w],v=[1,-1,1,0][w]:o(y,x)and s==i[y][x]and(exec('i[y][x]=0')or 1+k(y+g,x+v)+k(y-g,x-v))
print(k(q,e))
설명이있는 확장 버전 :
inputtt=''' ______________.
/ ____________ \
|/ __________ \|
||/ ________ \||
|||/ ______ \|||
||||/ \||||
|||||/ x |||||
|||||\_____/||||
||||\_______/|||
|||\_________/||
||\___________/|
\_____________/'''
# First, we get the input from STDIN and make it
# into a doubly-nested array
*input_text,=map(list,inputtt.split('\n'))
# A pretty cool Python trick to assign 0 to
# mulitple variables at once.
row=col=line_letter=line_row=line_col=line_char_index=0
# A function to check if a certian row and col is
# in bounds or not. Uses python's comparator chaining
in_bounds=lambda y,x:len(input_text[0])>x>=0<=y<len(input_text)
# A string to store all the line characters.
chars='\/_|'
# Search for the x
for line in input_text:
# If this line contains the x...
if'x'in line:
# Mark the row and column
row=input_text.index(line);col=line.index('x')
# For each direction...
for down,right in(1,0),(0,1),(-1,0),(0,-1):
# Move in that direction
y,x=row+down,col+right
# If the position is in bounds, mark the char at that position
line_found=in_bounds(y,x)and input_text[y][x]
# If the char is a line char, set all the variables saying we found it
if line_found in chars:
line_letter=line_found
line_char_index=chars.index(line_found)
line_row,line_col=y,x
recur=lambda y,x,\
# Find which directions we are supposed to recur in based on the line char
g=[1,1,0,1][line_char_index],v=[1,-1,1,0][line_char_index]:\
# If the char is in bounds and we are still on the line...
in_bounds(y,x)and input_text[y][x]==line_letter and\
# Set the spot to a 0, so we won't go back, increment,
# and recur in both directions
(exec('i[y][x]=0')or 1+recur(y+g,x+v)+recur(y-g,x-v))
# Finally, print the answer
print(recur(line_row,line_col))
답변
루아, 480 바이트
Lua는 장황한 언어이기 때문에 Python Answer를 능가하지 않습니다. 그러나 그럴 필요는 없습니다.
a=...s={}for _ in a:gmatch"[^\n]*"do s[#s+1]={}for S in _:gmatch"."do if S=="x"then x=#s[#s]+1y=#s end s[#s][#s[#s]+1]=S end end c="\\/_|"X={-1,1,1,0}Y={-1,-1,0,-1}for _,d in pairs({{x-1,y},{x,y-1},{x+1,y},{x,y+1}})do K=d[2]k=d[1]h=s[K]w=h and h[k]C=w and c:find(w)if C then n=1 j=k J=K while true do j=j+X[C]J=J+Y[C]if s[J]and s[J][j]==w then n=n+1 else break end end j=k J=K while true do j=j-X[C]J=J-Y[C]if s[J]and s[J][j]==w then n=n+1 else break end end print(n)break end end
내 참조 구현과 유사하지만 골프에서 실제 샷을 취하고 이전보다 조금 더 똑똑하게 수행합니다. 그래도 아마 골프가 조금 나아질 수 있습니다.
의견이 있습니다.
a=... -- Take the input from the command line.
s={} -- Store the string as a 2D Table, instead of a multiline string.
for _ in a:gmatch"[^\n]*"do -- For each new row.
s[#s+1] = {} -- Make a new sub-table. This is our line.
for S in _:gmatch"."do -- For every character.
if S=="x"then x=#s[#s]+1y=#s end -- If it's an x, mark down the X and Y position of it.
s[#s][#s[#s]+1]=S -- Push the character. This could probably be better golfed.
end
end
c="\\/_|" -- The ascii line characters.
X={-1,1,1,0} -- Their X Directionals.
Y={-1,-1,0,-1} -- Their Y Directionals.
-- These are inversed to get their opposite direction.
for _,d in pairs({{x-1,y},{x,y-1},{x+1,y},{x,y+1}}) do -- For each up down left and right.
K=d[2] -- K = y
k=d[1] -- k = x
h=s[K] -- h = the yth row
w=h and h[k] -- w = the xth character of the yth row, if the yth row exists.
C=w and c:find(w) -- C = the id of the ascii line character, if w existed.
if C then
n=1 -- n = the length of the line.
j=k -- Temp x
J=K -- Temp y
while true do
j=j+X[C] -- Increment j by the directional of the ascii.
J=J+Y[C] -- Ditto. for J
if s[J]and s[J][j]==w then -- if it's still the same.
n=n+1 -- Add 1 to the length.
else
break -- Or stop.
end
end
j=k -- Re-assign the temps as their original.
J=K
while true do
j=j-X[C] -- Search in the other direction.
J=J-Y[C]
if s[J]and s[J][j]==w then
n=n+1
else
break
end
end
print(n) -- Print the length.
break
end
end
답변
자바 스크립트 (ES6), 175
사각형을 만들기 위해 입력에 공백이 채워져 있다고 가정합니다.
s=>(o=>{s.replace(/[_|\\/]/g,(c,p)=>[o,-o,1,-1].map(d=>s[p+d]=='x'?[q,k]=[p,c]:c));for(n=z=k>'_'?o:k>'\\'?-1:k>'/'?o-1:o+1;s[q+=z]==k||z<0&&(n=-1,z=-z);)n++})(~s.search`
`)||n
덜 골프
s=>{
o = ~s.search`\n`; // offset between rows (negated)
// look for a line character near an 'x'
s.replace(/[_|\\/]/g,
(c,p)=> // for each line char 'c' in position 'p'
[o,-o,1,-1].map(d=>s[p+d]=='x' // found a near 'x' ?
?[q,k]=[p,c] // remember char and position
:c)
);
n=0;
z=k>'_'?o:k>'\\'?-1:k>'/'?o-1:o+1; // offset to prev char of line
while (s[q+=z]==k // move to left/top first
|| z<0 && (n=0,z=-z) // at left/top, go back and start counting
)
n++;
return n-1;
}
명확성을 위해 공백 대신 점 테스트
f=
s=>(o=>{s.replace(/[_|\\/]/g,(c,p)=>[o,-o,1,-1].map(d=>s[p+d]=='x'?[q,k]=[p,c]:c));for(n=z=k>'_'?o:k>'\\'?-1:k>'/'?o-1:o+1;s[q+=z]==k||z<0&&(n=-1,z=-z);)n++})(~s.search`
`)||n
out=x=>O.textContent+=x
;["|.\n|.\n|x\n|.\n|.\n", "|\\...\n|.\\x.\n|..\\.\n|___\\\n"
,"Diagram of a Wobbly Line:\nIRRELEVANTTEXT...........\n____.....____/...........\n....\\___/.X.;)...........\n......x..................\n"
,"./ ____________ \\\n.|/ __________ \|\n.||/ ________ \\||\n.|||/ ______ \\|||\n.||||/ \\||||\n.|||||/ x |||||\n.|||||\\_____/||||\n.||||\\_______/|||\n.|||\\_________/||\n.||\\___________/|\n. \\_____________/\n"].forEach(s=>out(s+f(s)+'\n\n'))
<pre id=O></pre>