Wenn Sie ein Diagramm haben, suchen Sie X

19

Finde X

Ich wurde von mathematischen Fragen inspiriert, bei denen man gefragt wird, ob man für eine bestimmte Form "X finden" möchte. Ursprünglich bestand die Herausforderung darin, die x- und y-Position des Zeichens 'x' in einer Zeichenfolge zu drucken. Aber ich nahm an, das wäre zu einfach. Also überlegte ich, in welchem ​​Kontext sie sich normalerweise befanden, und entschied, die Länge einer Linie neben dem x als angemessen zu betrachten.

Bei einer Zeichenfolgeeingabe, die ein Diagramm aus ASCII-Zeilen sowie ein einzelnes "x" und möglicherweise Junk-Zeichen enthält, geben Sie die Länge der einzigen Zeile aus, an die sich ein "x" direkt anschließt.

Beispiele

Eingang:

|
|
|x
|
|

Ausgang:

5

Eingang:

|\
| \x
|  \
|___\

Ausgabe:

4

Eingang:

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

Ausgabe:

3

Eingang:

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

Ausgabe:

5

Anmerkungen

  • Die gültigen Zeilenzeichen sind \/_|
  • \ verbindet oben links und unten rechts von sich.
  • / verbindet oben rechts und unten links von sich.
  • _ verbindet links und rechts von sich
  • | verbindet die Ober- und Unterseite von sich
  • Eine Linie ist immer gerade und besteht nur aus einem der n-mal wiederholten Linienzeichen.
  • Das x wird immer klein geschrieben und es wird immer das einzige im Diagramm sein.
  • Adjecent bezieht sich darauf, dass das x genau ein Zeichen über, unter oder neben dem Zeichen ist.
  • Das x steht immer neben genau einer Zeile.
  • Tabulatoren werden niemals in der Eingabe angezeigt.
  • Die Eingabe und Ausgabe kann in jedem akzeptablen Format erfolgen.
  • Dies ist Code Golf, also gewinnt der kürzeste Code!
  • HABE SPASS. TU ES. VIEL SPASS.

Referenzimplementierung

Ein Taco
quelle
Schöne Herausforderung, aber ich denke, es wäre besser, keine Tabs in der Eingabe zu garantieren. Indem Sie sagen, dass sie auftreten können, zwingen Sie effektiv jeden, Code hinzuzufügen, um Tabulatoren in 4 Leerzeichen zu konvertieren, was nichts mit der Hauptherausforderung zu tun hat.
Level River St
Ja, du hast einen guten Punkt. Ich werde das abschneiden.
ATaco
Sie sollten einen Testfall hinzufügen, dessen Form @den Stresstest-Antworten ähnelt .
Orlp
Sehr clevere Herausforderung, ich freue mich darauf, einige der zur Lösung verwendeten Taktiken zu sehen
Darren H

Antworten:

3

JavaScript (ES6), 165155 Bytes

BEARBEITEN: Inline x und w , um weitere Bytes zu sparen.

Golf (setzt voraus, dass die Eingabe mit Leerzeichen aufgefüllt ist, um ein Rechteck zu erstellen )

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)

Erweitert

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

Prüfung

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

Beispielausgabe (wenn Sie diese in der Google Chrome Developer Tools-Konsole ausführen)

[5, 4, 3, 5]

Zeppelin
quelle
8

Python 3, 428 408 385 378 Bytes

Arbeiten, hat aber eine Menge Potenzial zum Golfen. Ich bin ein bisschen verrostet.

Angenommen, die Eingabe wird mit Leerzeichen aufgefüllt, um ein Rechteck zu erstellen.

EDIT: Danke an @Artyer für die 23-Byte-Einsparung!

EDIT2: Wow, ich habe die Einsparungen von 6 Byte komplett verpasst. 1 weitere gespart, indem die Seiten eines Equals Checks getauscht wurden.

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

Erweiterte Version mit Erläuterung:

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))
Blau
quelle
Ich habe einige Golfvorschläge unter pastebin.com/zKENQUeR gemacht . Fühlen Sie sich frei, sie zu verwenden, wenn Sie möchten (Gesamt: -18 Bytes). Möglicherweise möchten Sie auch eine <!-- language-all: lang-py -->Syntaxhervorhebung hinzufügen .
Artyer
Vielen Dank! Ich war dumm, die meisten davon nicht zu tun, aber ich hatte keine Ahnung von dem unvermeidlichen Backslash. Ich bin zurzeit auf dem Handy, werde Ihre Vorschläge jedoch später einfließen lassen!
Blau
Oh, und noch eine: Erste Linie *i,=map(list,inputtt.split('\n'))( *i,macht ieine Liste statt einer Karte) (-6 mehr Bytes)
Artyer
Wow ... Golfen in seiner Gesamtheit.
Erik der Outgolfer
0

Lua, 480 Bytes

Lua, als die ausführliche Sprache, die sie ist, schlägt die Python-Antwort nicht. Muss es aber nicht.

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

Ähnlich wie meine Referenzimplementierung, aber es wird tatsächlich auf das Golfen eingegangen, und einige Dinge werden etwas geschickter als zuvor ausgeführt. Trotzdem könnte man wahrscheinlich ein bisschen besser golfen.

Mit Kommentaren.

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
Ein Taco
quelle
-1

JavaScript (ES6), 175

Angenommen, die Eingabe wird mit Leerzeichen aufgefüllt, um ein Rechteck zu erstellen.

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

Weniger golfen

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

Test - Punkte anstelle von Leerzeichen für Klarheit

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
quelle