รับแผนผัง, ค้นหา X


19

ค้นหา X

ฉันได้รับแรงบันดาลใจจากคำถามทางคณิตศาสตร์ที่ขอให้ "Find X" สำหรับรูปร่างที่กำหนด ในขั้นต้นฉันเพิ่งจะได้รับความท้าทายคือการพิมพ์ตำแหน่ง x และ y ของตัวละคร 'x' ในสตริง แต่ฉันคิดว่ามันจะง่ายเกินไป ดังนั้นฉันจึงพิจารณาบริบทที่ปกติแล้วและตัดสินใจหาความยาวของบรรทัดถัดจาก x ที่เหมาะสม

รับอินพุตสตริงที่มีไดอะแกรมของ ascii 'lines' รวมถึง 'x' ตัวเดียวและอักขระขยะที่อาจเกิดขึ้นพิมพ์ความยาวของบรรทัดเดียวที่มี 'x' อยู่ติดกันโดยตรง

ตัวอย่าง

การป้อนข้อมูล:

|
|
|x
|
|

ouput:

5

การป้อนข้อมูล:

|\
| \x
|  \
|___\

เอาท์พุท:

4

การป้อนข้อมูล:

Diagram of a Wobbly Line:
IRRELEVANTTEXT____
____     ____/
    \___/ X ;)   
      x

เอาท์พุท:

3

การป้อนข้อมูล:

  ______________
 / ____________ \
 |/ __________ \|
 ||/ ________ \||
 |||/ ______ \|||
 ||||/      \||||
 |||||/  x  |||||
 |||||\_____/||||
 ||||\_______/|||
 |||\_________/||
 ||\___________/|
  \_____________/

เอาท์พุท:

5

หมายเหตุ

  • อักขระบรรทัดที่ใช้ได้คือ \/_|
  • \ เชื่อมต่อด้านบนซ้ายและขวาล่างของตัวเอง
  • / เชื่อมต่อด้านบนขวาและซ้ายล่างของตัวเอง
  • _ เชื่อมต่อด้านซ้ายและขวาของตัวเอง
  • | เชื่อมต่อด้านบนและด้านล่างของตัวเอง
  • บรรทัดจะเป็นเส้นตรงเสมอและประกอบด้วยอักขระบรรทัดเดียวซ้ำหนึ่งครั้ง
  • x จะเป็นตัวพิมพ์เล็กเสมอและมันจะเป็นตัวเดียวในแผนภาพ
  • Adjecent อ้างถึง x ที่เป็นหนึ่งตัวอักษรด้านบนด้านล่างหรือด้านข้าง
  • x จะอยู่ถัดจากหนึ่งบรรทัดเสมอ
  • แท็บจะไม่ปรากฏในอินพุต
  • อินพุตและเอาต์พุตอาจเป็นรูปแบบที่ยอมรับได้
  • นี่คือรหัสกอล์ฟดังนั้นรหัสที่สั้นที่สุดจึงชนะ!
  • มีความสุข. ทำมัน. สนุกกับตัวเอง

การดำเนินการอ้างอิง


เป็นความท้าทายที่ดี แต่ฉันคิดว่ามันจะดีกว่าที่จะรับประกันว่าไม่มีแท็บในอินพุต การบอกว่าพวกเขาอาจเกิดขึ้นได้คุณกำลังบังคับให้ทุกคนเพิ่มรหัสเพื่อแปลงแท็บเป็น 4 ช่องว่างซึ่งไม่เกี่ยวข้องกับความท้าทายหลัก
เลเวลริเวอร์เซนต์

ใช่คุณมีจุดที่ดี ฉันจะตัดมัน
ATaco

คุณควรเพิ่มตู้ทดสอบที่มีรูปร่างคล้ายกับ@คำตอบการทดสอบความเครียด
orlp

ความท้าทายที่ฉลาดมากฉันหวังว่าจะได้เห็นกลวิธีบางอย่างที่ใช้ในการแก้ปัญหา
Darren H

คำตอบ:


3

JavaScript (ES6) 165, 155 ไบต์

แก้ไข: Inline xและwเพื่อบันทึกเพิ่มเติมบางไบต์

Golfed (สมมติว่าอินพุตถูกเสริมด้วยช่องว่างเพื่อสร้างสี่เหลี่ยมผืนผ้า)

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

เอาต์พุตตัวอย่าง (หากคุณเรียกใช้ในคอนโซลเครื่องมือนักพัฒนาซอฟต์แวร์ Google Chrome)

[5, 4, 3, 5]


8

Python 3, 428 408 385 378 ไบต์

การทำงาน แต่มีศักยภาพมากมายที่จะตีกอล์ฟ ฉันเป็นสนิมเล็กน้อย

สมมติว่าอินพุตเป็นเบาะด้วยช่องว่างเพื่อสร้างสี่เหลี่ยมผืนผ้า

แก้ไข: ขอบคุณ @Artyer เพื่อการออม 23 ไบต์!

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

ผมได้ทำข้อเสนอแนะในการเล่นกอล์ฟบางpastebin.com/zKENQUeR รู้สึกอิสระที่จะใช้พวกเขาหากคุณต้องการ (รวม: -18 ไบต์) นอกจากนี้คุณอาจต้องการเพิ่ม<!-- language-all: lang-py -->สำหรับการเน้นไวยากรณ์
Artyer

@Artyer ขอบคุณ! ฉันงี่เง่าที่จะไม่ทำสิ่งเหล่านั้นส่วนใหญ่ แต่ฉันไม่มีความคิดเกี่ยวกับแบ็กสแลชที่ไม่หนี ขณะนี้ฉันอยู่บนมือถือ แต่ฉันจะต้องรวมคำแนะนำของคุณในภายหลัง!
บลู

โอ้และอีกหนึ่ง: บรรทัดแรกไปที่*i,=map(list,inputtt.split('\n'))( *i,ทำiรายการแทนแผนที่) (-6 ไบต์เพิ่มเติม)
Artyer

ว้าว ... เล่นกอล์ฟอย่างครบถ้วน
Erik the Outgolfer

0

Lua, 480 ไบต์

Lua การเป็นภาษา Verbose ไม่ได้ชนะคำตอบของ Python แต่มันไม่จำเป็นต้อง

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

-1

JavaScript (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

น้อย golfed

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;
}

ทดสอบ Dots แทนการเว้นวรรคเพื่อความชัดเจน

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>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.