Biorąc pod uwagę schemat, znajdź X

19

Znajdź X

Zainspirowały mnie pytania matematyczne, w których zadaje się pytanie „Znajdź X” dla danego kształtu. Początkowo miałem właśnie za zadanie wydrukować lokalizację xiy znaku „x” w ciągu znaków. Ale myślałem, że to byłoby zbyt proste. Rozważyłem więc kontekst, w którym normalnie się znajdowali, i zdecydowałem, że znalezienie długości linii obok x wydaje się odpowiednie.

Biorąc pod uwagę ciąg znaków zawierający diagram ascii „linii”, a także pojedynczy znak „x” i potencjalnie śmieci, wydrukuj długość jedynego wiersza, który ma bezpośrednio „x”.

Przykłady

Wejście:

|
|
|x
|
|

Ouput:

5

Wejście:

|\
| \x
|  \
|___\

Wynik:

4

Wejście:

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

Wynik:

3

Wejście:

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

Wynik:

5

Notatki

  • Prawidłowe znaki wiersza to \/_|
  • \ łączy lewy górny i prawy dolny róg.
  • / łączy w sobie prawy górny i lewy dolny róg.
  • _ łączy lewą i prawą część siebie
  • | łączy górę i dół samego siebie
  • Linia zawsze będzie prosta i składać się będzie tylko z jednego znaku linii powtarzanego n razy.
  • X będzie zawsze małymi literami i zawsze będzie jedynym na schemacie.
  • Adjecent oznacza, że ​​x jest dokładnie jedną postacią powyżej, poniżej lub poza nią.
  • X zawsze będzie znajdować się dokładnie obok dokładnie jednej linii.
  • Zakładki nigdy nie pojawią się na wejściu.
  • Dane wejściowe i wyjściowe mogą mieć dowolny akceptowalny format.
  • To jest Code Golf, więc wygrywa najkrótszy kod!
  • BAW SIĘ DOBRZE. ZRÓB TO. BAW SIĘ DOBRZE.

Wdrożenie referencyjne

ATaco
źródło
Niezłe wyzwanie, ale myślę, że lepiej byłoby zagwarantować brak kart wejściowych. Mówiąc, że mogą się zdarzyć, skutecznie zmuszasz wszystkich do dodania kodu do konwersji tabulacji na 4 spacje, co nie ma nic wspólnego z głównym wyzwaniem.
Level River St
Tak, masz rację. Wytnę to.
ATaco,
Należy dodać walizkę @testową, która ma kształt podobny do odpowiedzi z testu warunków skrajnych.
orlp
Bardzo sprytne wyzwanie, nie mogę się doczekać, aby zobaczyć niektóre taktyki zastosowane do jego rozwiązania
Darren H

Odpowiedzi:

3

JavaScript (ES6), 165, 155 bajtów

EDYCJA: Wstawione x i w , aby zaoszczędzić trochę więcej bajtów.

Gra w golfa (przy założeniu, że dane wejściowe są wypełnione spacjami, aby utworzyć prostokąt)

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)

Rozszerzony

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

Test

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

Przykładowe dane wyjściowe (jeśli uruchomisz to w konsoli Narzędzi programisty Google Chrome)

[5, 4, 3, 5]

zepelin
źródło
8

Python 3, 428 408 385 378 bajtów

Pracuje, ale ma mnóstwo możliwości do gry w golfa. Jestem trochę zardzewiały.

Zakłada, że ​​dane wejściowe są wypełnione spacjami, aby utworzyć prostokąt.

EDYCJA: Dzięki @Artyer za 23 bajty oszczędności!

EDYCJA 2: Wow, całkowicie brakowało mi 6 bajtów oszczędności. Zaoszczędził jeszcze 1, zamieniając strony testu równości.

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

Wersja rozszerzona z wyjaśnieniem:

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))
niebieski
źródło
Zrobiłem kilka sugestii dotyczących gry w golfa na pastebin.com/zKENQUeR . Możesz z nich korzystać, jeśli chcesz (łącznie: -18 bajtów). Możesz także dodać <!-- language-all: lang-py -->do podświetlania składni.
Artyer
@Artyer Dziękujemy! Głupio było nie robić większości z nich, ale nie miałem pojęcia o nieuchwytnym odwrotnym ukośniku. Jestem obecnie na telefonie komórkowym, ale z pewnością uwzględnię twoje sugestie później!
niebieski
Aha i jeszcze jedno: Pierwsza linia do *i,=map(list,inputtt.split('\n'))( *i,tworzy ilistę zamiast mapy) (-6 dodatkowych bajtów)
Artyer
Wow ... gra w golfa w całości.
Erik the Outgolfer
0

Lua, 480 bajtów

Lua, będąc językiem pełnym, nie pokonuje odpowiedzi w języku Python. Ale nie musi.

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

Podobne do mojej referencyjnej implementacji, ale faktycznie gra w golfa i robi pewne rzeczy bardziej sprytnie niż wcześniej. Prawdopodobnie można by go trochę lepiej zagrać w golfa.

Z komentarzami.

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
ATaco
źródło
-1

JavaScript (ES6), 175

Zakładając, że dane wejściowe są wypełnione spacjami, aby utworzyć prostokąt.

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

Mniej golfa

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

Testuj kropki zamiast spacji dla zachowania przejrzystości

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>

edc65
źródło