Dov'è la freccia che punta?


32

Dov'è la freccia che punta?

In questa sfida, il tuo obiettivo è seguire una freccia e generare il personaggio a cui punta.

Esempi

Ingresso:

d  S------+    b
          |     
          |     
   c      +--->a

Produzione: a


Ingresso:

S-----+---a->c
      |       
      V       
      b       

Produzione: b

La freccia non punta cperché è divisa per a, il che significa che questo percorso non conduce mai a una freccia.


Ingresso:

a S      s
  |      |
  V      V
  b      c

Produzione: b


Ingresso:

d s<+S+--V
    |||  Q
    -++   

Produzione: Q

Questo percorso inizia da S, scende, a destra, sale, a destra, quindi punta verso il basso in Q. Nota che il percorso non va dritto da Sa +.


Ingresso:

d s-+   +-S  +--+
    +-->b |  |  |
     |  | +--+  |
     +--+ A<----+

Produzione: A


Ingresso:

S-----+   
|     +-^ 
+---+->B  
    +---^ 

Produzione: B

Perché la linea valida non porterà mai a un carattere di spazi bianchi. L'unica riga che non porta a un carattere di spazio bianco porta aB

Sfida

L'input sarà una stringa a più righe in cui è necessario trovare il carattere a cui punta la freccia. Ci sarà solo una freccia valida. La freccia valida indicherà solo i caratteri alfanumerici esclusi S. Una linea non si sovrapporrà mai. per esempio-|-

  • S (maiuscolo) rappresenta il punto in cui inizia la freccia.
  • - rappresenta una linea orizzontale
  • +rappresenta una possibile modifica dell'asse. Una freccia valida non inizierà mai con a +.
  • | rappresenta una linea verticale
  • > < V ^uno di questi rappresenta la punta della freccia. Questi non si collegheranno mai a +.

Ce ne sarà solo uno Snella stringa. L'input verrà inoltre riempito per essere un rettangolo (non necessariamente un quadrato).


1
"Questo non apparirà mai adiacente a un S." Probabilmente dovrebbe essere riformulato in "Questo non sarà mai il primo carattere della freccia". (Perché l' Qesempio ha un +adiacente a un S.) " +Rappresenta un cambio di asse." potrebbe essere meglio " +rappresenta un possibile cambiamento nell'asse". (Perché l' Besempio mostra che puoi spostarti attraverso una +senza cambiare direzione.) Altrimenti, bella sfida. :)
Martin Ender,

Ho apportato una modifica a uno dei tuoi casi di test. Penso che ciò renderà più difficile la scrittura di programmi a cui capita solo di ottenere la risposta giusta, come la mia all'inizio.
El'endia Starman,

La testa della freccia può cambiare direzione, ovvero ---^? In altre parole, se nell'esempio B, la B potesse rimanere in prima fila?
edc65,

@ edc65 intendi come nell'esempio Q?
Downgoat,

1
Una punta di freccia non sarà collegata a '+'. Ma potrebbe essere collegato a 'S'? È S>avalido?
edc65,

Risposte:


9

JavaScript (ES6), 195 245 231 242 246 250

Edit4 Ora, una singola funzione ricorsiva. Probabilmente non si può più giocare a golf

Modifica3 Test per la linea retta e test per la freccia unita nella funzione T, le funzioni S e H rimosse.

Edit2 Rivisto e più a lungo :( dopo questo questo chiarimento

modificare Piccoli miglioramenti, tagliando alcuni caratteri qua e là, aspettando che CJammers intervenga

Prova a eseguire lo snippet di seguito in un browser compatibile con EcmaScript 6. (funziona su Firefox. Chrome manca ancora l'operatore di diffusione ...)

f=(s,p=s[I='indexOf']`S`,w=m=[o=~s[I]`
`,1,-o,-1],q,v,r)=>m.some((d,i)=>{for(v=w,q=p;r=s[q+=d],r=='|-'[i&1];)v='+';return r=r==v?f(s,q,v):/\w/.test(r=s[q+m['^>V<'[I](r)]])&&r},s=[...s],s[p]=0)&&r


// Less golfed
// U: recursive scan function
U = (s, // input string or array
     p = s.indexOf`S`, // current position, defult to position of S into string (at first call)
     w = // char to compare looking for a '+', at first call default to garbage as you can't follow '+' near 'S'
       m = [// m, global, offset array form movements. 
         o = ~s.indexOf`\n`, // o, global, row line +1 (negated)
         1, -o, -1], // complete the values of m array
     // m and o are assigned again and again at each recursive call, but that is harmless
     // params working as local variables as the function is recursive
     q,v,r) => 
{
   s = [...s]; //convert to array, as I have to modify it while scanning
     //the conversion is done again and again at each recursive call, but that is harmless
   s[p] = 0; // make s[p] invalid to avoid bouncing back and forth
  
   m.some( // for each direction, stop if endpoint found
      (d,i ) => {
        q = p; // start at current position, then will add the offset relative to current direction
        v = w; // for each direction, assign the starting value that can be '+' or garbage at first call
        // compare char at next position with the expected char based on direction (- for horiz, | for vertical)
        // in m array, values at even positon are vertical movements, odds are horizontal
        while (s[q+=d] == '|-'[i&1]) // while straight direction, follow it until it ends
          v = '+'; // from now on '+' is allowed
        r = s[q];
        if (r == v) // check if found a '+'
          r = U(s, q, v) // recursive call to check all directions from current position
        else
        {
          r = s[q + m['^>V<'.indexOf(r)]], // pointed char in p (if arrowhead, else will return undefined)
          r = /\w/.test(r) && r // if alphanumeric, then we found our result - else r = false
        }  
        return r; // returning r to .some; if r is truthy, the .some function will stop
      }
   ) 
   return r; // result if found, else undefined or null
}

// TEST
out=x=>O.innerHTML+=x.replace(/</g,'&#60;')+'\n'

// Using explicit newlines '\n' to ensure the padding to a rectangle
;[
 ['z<+S-+->a','a'] 
,['a<-+S>b','b']
,['S-+\n  |\n  V\n  a','a']
,['a S      s\n  |      |\n  V      V\n  b      c  ','b']
,['S-----+  \n|     +-^  \n+---+->B \n    +---^','B']
,['d s<+S+--V\n    |||  Q\n    -++    ','Q']
,['d s-+   +-S  +--+\n    +-->b |  |  |\n     |  | +--+  |\n     +--+ A<----+  ','A']
,['S-----+   \n|     +-^ \n+---+->B  \n    +---^ ','B']
].forEach(t=>{
  r=f(t[0])
  k=t[1]
  out('Test '+(r==k?'OK':'Fail')+'\n'+t[0]+'\nResult: '+ r +'\nCheck: '+k+'\n')
})
<pre id=O></pre>


5

JavaScript 2016, 264 263 249 240 235 234 byte

Eseguilo in Firefox:

m=l=>{o=(q,e)=>q.indexOf(e)
s=[-1,1,c=~o(l,`
`),-c]
f=i=>!o[i]&(!(r=l[i+s[o(a="<>^V",o[i]=c=l[i])]])|r<"0"|r>"z"|r=="S"||alert(s=r))&&c&&[for(j of (c!='+'?a:"")+"-|+")for(k of s)l[i+k]!=j|~o(l[i]+j,k*k>1?"-":"|")||f(i+k)]
f(o(l,'S'))}

m(`d s-+   +-S  +--+
    +-->b |  |  |
     |  | +--+  |
     +--+ A<----+`)

Sparsi in alcuni dei miei appunti:

m=l=>{o=(q,e)=>q.indexOf(e) //shorthand for indexOf
s=[-1,1,c=o(l,`
`)+1,-c] // get all possible moves in 1d
w=[] // to keep track of the already-visited indexes
f=i=>{c=l[i] // current character
if(!w[i]&&c) // only continue if the index wasn't already visited and we aren't out of bounds
{r=l[i+s[o(a="<>^V",w[i]=c)]] // sets w[i] to a truthy value and maps the arrows to their corresponding moves in s. If c is an arrow, r is the character it's pointing to.
if(!r||r<"0"||r>"z"||r=="S"||alert(r)) // if r is an alphanumeric character that isn't r, show it and return. If not, continue.
for(j of (c!='+'?a:"")+"-|+") // iterate over all characters to make sure plusses are checked out last, which is necessary at the start.
for(k of s) // check out all possible moves
l[i+k]!=j|| // check if the move leads to the character we're looking for
~o(l[i]+j,k*k>1?"-":"|")|| // make sure the current nor that character goes against the direction of the move
f(i+k)}} // make the move, end of f
f(o(l,'S'))} // start at S

Puoi salvare alcuni bit facendo o = 'indexOf'e poi facendo q[o](e)quando vuoi usarlo.
Non che Charles, il

Inoltre, nel golf di codice, i for(;;)loop sono generalmente più efficienti. Potrebbe essere sbagliato in questo caso, ma provalo.
Non che Charles, il

1
test case a<-+S->bPenso che dovrebbe dare bsolo, dato che una freccia valida non inizierà mai con un +
edc65

Risolto il problema e trasformato f in una riga. A proposito, mi è piaciuto molto il tuo approccio a questo problema.
bopjesvla,

Una nota a margine: adoro la comprensione di array, ma non è più presente in nessuna versione dello standard EcmaScript. Suggerisco di JavaScript 2016taggarti come risposta (stiil una risposta valida e buona, non un problema)
edc65

3

VBA Excel 2007, 894 byte

Bene, questo è iniziato molto meglio poi è finito. Ho la sensazione che la mia logica sia difettosa e avrei potuto salvare una tonnellata di byte se avessi riordinato parte della mia logica, ma troppo tempo è stato sprofondato in questo già = P

L'input per questo è la colonna A di qualunque foglio ti trovi. Questo metodo usa il fatto che Excel ha questa bella griglia e rompe tutto in modo da poter vedere cosa sta facendo più chiaramente.

Sub m()sta semplicemente prendendo i dati incollati Copia dalla colonna A e li sta distruggendo per carattere. Se consentiamo un input modificato, se preformi il labirinto in 1 carattere per cella puoi salvare qualche byte rimuovendosub m()

Incolla un labirinto in Excel di qualsiasi dimensione fino a 99 righe di 27 caratteri. Se vuoi labirinti più grandi, i suoi soli 2 byte extra aumentano l'ambito a 999 righe e colonne ZZ

Inoltre potrebbe essere necessario un appello dei giudici per stabilire se un foglio Excel è "Input standard" valido per una risposta VBA. In caso contrario, è praticamente impossibile fornire VBA multi-line input VIA la finestra immediata

Per eseguire questo codice basta incollare questo codice in un modulo Excel, incollare un labirinto in A1 ed eseguire sub j()

Sub m()
For k=1 To 99
u=Cells(k,1).Value
For i=1 To Len(u)
Cells(k,i+1).Value=Mid(u,i,1)
Next
Next
Columns(1).Delete
End Sub
Sub j()
m
With Range("A:Z").Find("S",,,,,,1)
h .row,.Column,0
End With
End Sub
Sub h(r,c,t)
If t<>1 Then l r-1,c,1,0,r
If t<>-1 Then l r+1,c,-1,0,r
If t<>2 Then l r,c-1,2,0,r
If t<>-2 Then l r,c+1,-2,0,r
End Sub
Sub l(r,c,y,p,i)
On Error GoTo w
q=Cells(r,c).Text
If q="V" Or q="^" Or q="<" Or q=">" Then
p=1
End If
f="[^V<>]"
If p=1 And q Like "[0-9A-UW-Za-z]" Then
MsgBox q: End
Else
If q="^" Then p=1: GoTo t
If q="V" Then p=1: GoTo g
If q="<" Then p=1: GoTo b
If q=">" Then p=1: GoTo n
Select Case y
Case 1
t:If q="|" Or q Like f Then l r-1,c,y,p,q
Case -1
g:If q="|" Or q Like f Then l r+1,c,y,p,q
Case 2
b:If q="-" Or q Like f Then l r,c-1,y,p,q
Case -2
n:If q="-" Or q Like f Then l r,c+1,y,p,q
End Select
If q="+" And i<>"S" Then h r,c,y*-1
p=0
End If
w:
End Sub

2

Python 3, 349 byte

Uh, così tanti byte.

S=input().split('\n')
Q=[[S[0].find('S'),0]]
D=[[1,0],[0,1],[-1,0],[0,-1]]
A='-S--++-'
B='|S||++|'
P='>V<^'
i=0
while D:
 a,b=Q[i];i+=1
 j=S[b][a]
 for x,y in D:
  try:
   c,d=a+x,b+y;k=S[d][c]
   if k in P:
    z=P.index(k);print(S[d+D[z][1]][c+D[z][0]]);D=[]
   if (j+k in A and x)+(j+k in B and y)*~([c,d]in Q):Q+=[[c,d]]
  except IndexError: pass

Sostanzialmente una prima ricerca. Bonus: questo in realtà esce con grazia invece di usare exit(), che è comunque più lungo.


Questo non implementa circa la metà dei vincoli di ricerca, amico. ideone.com/OzoWRX
bopjesvla,

@bopjesvla: Drat, hai ragione. Buon posto!
El'endia Starman,

Come puoi usare una stringa multilinea con input()? È problematico per me.
The_Basset_Hound

@The_Basset_Hound: non è possibile inserire manualmente le nuove righe; devi copiare e incollare tutto in una volta.
El'endia Starman

@ El'endiaStarman Sto copiando / incollando e sembra ancora leggere solo la prima riga.
The_Basset_Hound

2

Perl 5

La soluzione si è rivelata più lunga di altre soluzioni.
Anche dopo averlo giocato a golf. Quindi questa è la versione non golfata.
Stampa la mappa in modo da poter seguire il cursore.

Come funziona? Ad ogni passo mette in pila possibili mosse. E continua a funzionare fino a quando non è rimasto nulla nello stack o non viene trovata una soluzione.
Può essere facilmente modificato per trovare tutte le soluzioni e scegliere il più vicino -> while (@_) {...

while(<>){
  chomp;
  @R=split//;
  $j++;$i=0;
  for(@R){$nr++;$i++;$A[$i][$j]=$_;if('S'eq$_){$x=$i;$y=$j}}
  $xm=$i,if$xm<$i;$ym=$j;
}
push(@_,[($x,$y,'S',0)]);
$cr='';
while(@_&&''eq$cr){
 @C=pop@_;
 ($x,$y,$d,$n)=($C[0]->[0],$C[0]->[1],$C[0]->[2],$C[0]->[3]);
 $c=$A[$x][$y];
 $A[$x][$y]='.';
 if($c=~m/[S+]/){
    if('L'ne$d&&$A[$x+1][$y]=~m/[+-]/){push(@_,[($x+1,$y,'R',$n+1)])}
    if('D'ne$d&&$A[$x][$y-1]=~m/[+|]/){push(@_,[($x,$y-1,'U',$n+1)])}
    if('R'ne$d&&$A[$x-1][$y]=~m/[+-]/){push(@_,[($x-1,$y,'L',$n+1)])}
    if('U'ne$d&&$A[$x][$y+1]=~m/[+|]/){push(@_,[($x,$y+1,'D',$n+1)])}
 }
 if($c eq'|'){
    if($d ne'U'&&$A[$x][$y+1]=~m/[+|<>^V]/){push(@_,[($x,$y+1,'D',$n+1)])}
    if($d ne'D'&&$A[$x][$y-1]=~m/[+|<>^V]/){push(@_,[($x,$y-1,'U',$n+1)])}
 }
 if($c eq'-'){
    if($d ne'L'&&$A[$x+1][$y]=~m/[+-<>^V]/){push(@_,[($x+1,$y,'R',$n+1)])}
    if($d ne'R'&&$A[$x-1][$y]=~m/[+-<>^V]/){push(@_,[($x-1,$y,'L',$n+1)])}
 }
 if($c=~m/[<>^V]/&&$n<$nr){
    if($c eq'>'&&$A[$x+1][$y]=~m/\w/){$cr=$A[$x+1][$y];$nr=$n}
    if($c eq'<'&&$A[$x-1][$y]=~m/\w/){$cr=$A[$x-1][$y];$nr=$n}
    if($c eq'V'&&$A[$x][$y+1]=~m/\w/){$cr=$A[$x][$y+1];$nr=$n}
    if($c eq'^'&&$A[$x][$y-1]=~m/\w/){$cr=$A[$x][$y-1];$nr=$n}
 }
 print_map()
}
print "$cr\n";
sub print_map {
    print "\033[2J"; #clearscreen
    print "\033[0;0H"; #cursor at 0,0
    for$j(1..$ym){for$i(1..$xm){print (($x==$i&&$y==$j)?'X':$A[$i][$j])}print"\n"}
    sleep 1;
}

Test

$ cat test_arrows6.txt
S-----+
|     +-^
+---+->B
    +---^

$ perl arrows.pl < test_arrows6.txt
.-----+
.     +-^
......XB
    .....
B

2
Ho visto il titolo e ho pensato "Perl" e "fatto in 5 byte". attacco di cuore
Conor O'Brien,

2

Versione PHP (i commenti sono in francese, scusate)

<?php
/*
* By Gnieark https://blog-du-grouik.tinad.fr oct 2015
* Anwser to "code golf" http://codegolf.stackexchange.com/questions/57952/where-is-the-arrow-pointing in PHP
*/
//ouvrir le fichier contenant la "carte et l'envoyer dans un array 2 dimmension
$mapLines=explode("\n",file_get_contents('./input.txt'));
$i=0;
foreach($mapLines as $ligne){
    $map[$i]=str_split($ligne,1);
    if((!isset($y)) && in_array('S',$map[$i])){
        //tant qu'à parcourir la carte, on cherche le "S" s'il n'a pas déjà été trouvé.
        $y=$i;
        $x=array_search('S',$map[$i]);
    }
    $i++;
}
if(!isset($y)){
    echo "Il n'y a pas de départ S dans ce parcours";
    die;
}
echo "\n".file_get_contents('./input.txt')."\nLe départ est aux positions ".$map[$y][$x]." [".$x.",".$y."]. Démarrage du script...\n";
$previousX=-1; // Contiendra l'ordonnée de la position précédente. (pour le moment, une valeur incohérente)
$previousY=-1; // Contiendra l'absycede la position précédente. (pour le moment, une valeur incohérente)
$xMax=count($map[0]) -1;
$yMax=count($map) -1;
$previousCrosses=array(); //On ne gardera en mémoire que les croisements, pas l'ensemble du chemin.
while(1==1){ // C'est un défi de codagee, pas un script qui sera en prod. j'assume.
    switch($map[$y][$x]){
        case "S":
            //même fonction que "+"
        case "+":
            //on peut aller dans les 4 directions
            $target=whereToGoAfterCross($x,$y,$previousX,$previousY);
            if($target){
          go($target[0],$target[1]);
            }else{
          goToPreviousCross();
            }
            break;
        case "s":
            goToPreviousCross();
            break;
        case "-":
        //déplacement horizontal
        if($previousX < $x){
          //vers la droite
          $targetX=$x+1;
          if(in_array($map[$y][$targetX],array('-','+','S','>','^','V'))){
        go($targetX,$y);
          }else{
        //On est dans un cul de sac
        goToPreviousCross();
          }
        }else{
          //vers la gauche
          $targetX=$x-1;
          if(in_array($map[$y][$targetX],array('-','+','S','<','^','V'))){
        go($targetX,$y);
          }else{
        //On est dans un cul de sac
        goToPreviousCross();
          }
        }
            break;
        case "|":
        //déplacement vertical
        if($previousY < $y){
          //on descend (/!\ y augmente vers le bas de la carte)
          $targetY=$y+1;
          if(in_array($map[$targetY][$x],array('|','+','S','>','<','V'))){
        go ($x,$targetY);
          }else{
        goToPreviousCross();
          }
        }else{
        //on Monte (/!\ y augmente vers le bas de la carte)
          $targetY=$y - 1;
          if(in_array($map[$targetY][$x],array('|','+','S','>','<','V'))){
        go ($x,$targetY);
          }else{
        goToPreviousCross();
          } 
        }
            break;
    case "^":
    case "V":
    case ">":
    case "<":
      wheAreOnAnArrow($map[$y][$x]);
      break;
    }
}
function wheAreOnAnArrow($arrow){
  global $x,$y,$xMax,$yMax,$map;
  switch($arrow){
    case "^":
      $targetX=$x;
      $targetY=$y -1;
      $charsOfTheLoose=array(" ","V","-","s");
      break;
    case "V":
      $targetX=$x;
      $targetY=$y + 1;
      $charsOfTheLoose=array(" ","^","-","s");
      break;
    case ">":
      $targetX=$x + 1;
      $targetY=$y;
      $charsOfTheLoose=array(" ","<","|","s");   
      break;
    case "<":
      $targetX=$x - 1;
      $targetY=$y;
      $charsOfTheLoose=array(" ",">","|","s");   
      break;
    default:     
      break;
  }
  if(($targetX <0) OR ($targetY<0) OR ($targetX>$xMax) OR ($targetY>$yMax) OR (in_array($map[$targetY][$targetX],$charsOfTheLoose))){
      //on sort du cadre ou on tombe sur un caractere inadapté
      goToPreviousCross();
  }else{
    if(preg_match("/^[a-z]$/",strtolower($map[$targetY][$targetX]))){
      //WIN
      echo "WIN: ".$map[$targetY][$targetX]."\n";
      die;
     }else{
      //on va sur la cible
      go($targetX,$targetY);
     }
  }
}
function whereToGoAfterCross($xCross,$yCross,$previousX,$previousY){

            //haut
            if(canGoAfterCross($xCross,$yCross +1 ,$xCross,$yCross,$previousX,$previousY)){
                return array($xCross,$yCross +1);
            }elseif(canGoAfterCross($xCross,$yCross -1 ,$xCross,$yCross,$previousX,$previousY)){
                //bas
                return array($xCross,$yCross -1);
            }elseif(canGoAfterCross($xCross-1,$yCross,$xCross,$yCross,$previousX,$previousY)){
                //gauche
                return array($xCross-1,$yCross);
            }elseif(canGoAfterCross($xCross+1,$yCross,$xCross,$yCross,$previousX,$previousY)){
                //droite
                return array($xCross+1,$yCross);
            }else{
          //pas de direction possible
          return false;
            }  
}
function canGoAfterCross($xTo,$yTo,$xNow,$yNow,$xPrevious,$yPrevious){
    global $previousCrosses,$xMax,$yMax,$map;
    if(($xTo < 0) OR ($yTo < 0) OR ($xTo >= $xMax) OR ($yTo >= $yMax)){return false;}// ça sort des limites de la carte
    if(
    ($map[$yTo][$xTo]==" ") // on ne va pas sur un caractere vide
    OR (($xTo==$xPrevious)&&($yTo==$yPrevious)) //on ne peut pas revenir sur nos pas (enfin, ça ne servirait à rien dans cet algo)
    OR (($xTo==$xNow)&&($map[$yTo][$xTo]=="-")) //Déplacement vertical, le caractere suivant ne peut etre "-"
    OR (($yTo==$yNow)&&($map[$yTo][$xTo]=="|")) // Déplacement horizontal, le caractère suivant ne peut être "|"
    OR ((isset($previousCrosses[$xNow."-".$yNow])) && (in_array($xTo."-".$yTo,$previousCrosses[$xNow."-".$yNow]))) //croisement, ne pas prendre une direction déjà prise
   ){    
      return false;
    }
    return true;    
}
function go($targetX,$targetY){
    global $previousX,$previousY,$x,$y,$previousCrosses,$map;
    if(($map[$y][$x]=='S')OR ($map[$y][$x]=='+')){
        //on enregistre le croisement dans lequel on renseigne la direction prise et la direction d'origine
        $previousCrosses[$x."-".$y][]=$previousX."-".$previousY;
        $previousCrosses[$x."-".$y][]=$targetX."-".$targetY; 
    }
    $previousX=$x;
    $previousY=$y;
    $x=$targetX;
    $y=$targetY;
    //debug
    echo "deplacement en ".$x.";".$y."\n";   
}
function goToPreviousCross(){
  global $x,$y,$previousX,$previousY,$xMax,$yMax,$previousCrosses;

  /*
  * On va remonter aux précédents croisements jusqu'à ce 
  * qu'un nouveau chemin soit exploitable
  */
  foreach($previousCrosses as $key => $croisement){
    list($crossX,$crossY)=explode("-",$key);
    $cross=whereToGoAfterCross($crossX,$crossY,-1,-1);
    if($cross){
      go($crossX,$crossY);
      return true;
    } 
  }
  //si on arrive là c'est qu'on est bloqués
  echo "Aucun chemin n'est possible\n";
  die;
}

1

Haskell, 268 byte

Congratulazioni ai Javascripters! Ho rinunciato alla generosità, ma ecco cosa ho ottenuto. Può / Potrebbe non funzionare in tutti i casi, ma gestisce effettivamente le frecce che iniziano e le punte di freccia che si connettono a +es, per quanto ne so. Non ha nemmeno incluso la ricerca di S, è solo (0,0)per ora.

import Data.List
x%m=length m<=x||x<0
a s(x,y)z|y%s||x%(head s)=[]|0<1=b s(x,y)z$s!!y!!x
b s(x,y)z c|g c>[]=filter(>' ')$concat[a s(x+i k,y+i(3-k))k|k<-g c,k-z`mod`4/=2]|0<1=[c]
i=([0,-1,0,1]!!)
g c=findIndices(c`elem`)$words$"V|+S <-+S ^|+S >-+S"
f s=a(lines s)(0,0)0

0

Mi piacerebbe vedere una versione di APL nello spirito di https://www.youtube.com/watch?v=a9xAKttWgP4

Per iniziare, una soluzione Julia vettorializzata che penso possa essere tradotta 1: 0,3 in APL o J. Prende una stringa R che rappresenta un diagramma a freccia L x K. Innanzitutto traduce la matrice di simboli in una matrice di piccole matrici 3x3 i cui modelli sono le espansioni binarie delle lettere della stringa "\ 0 \ x18 \ fH \ t]] \ x1cI". Ad esempio '+' è codificato come rimodella ([0, cifre (int (']'), 2,8)], 3,3)

  0 2 0
  2 2 2
  0 2 0

In questa rappresentazione, il percorso è composto da 2 e viene sommerso da 3 dal punto di partenza.

A=zeros(Int,L*3+3,K*3+3)
s(i,j=i,n=2)=A[i:end+i-n,j:end+j-n]
Q=Int['A':'Z';'a':'z']
for k=0:K-1,l=0:L-1
r=R[K*l+k+1]
q=search(b"V^><+S|-",r)
d=reverse(digits(b"\0\x18\fH\t]]\x1cI"[q+1],2,8))
A[1+3l:3l+3,1+3k:3k+3]=2*[d;0]
A[3l+2,3k+2]+=r*(r in Q&&r!='V'&&r!='^')+(1-r)*(r=='S')+3(5>q>0)
end
m=0
while sum(A)>m
m=sum(A)
for i=0:1,j=1:2,(f,t)=[(3,6),(11,15)]
A[j:end+j-2,j:end+j-2]=max(s(j),f*(s(j).*s(2-i,1+i).==t))
end
end
for i=[1,4],k=Q
any(s(1,1,5).*s(5-i,i,5).==11*k)&&println(Char(k))
end

Testare,

   R=b"""
       d  S------+    b
                 |     
                 |     
          c      +--->a
       """;

   K=search(R,'\n') # dimensions
   L=div(endof(R),K)


   include("arrow.jl")

a

A proposito, penso che la clausola "Un altro + potrebbe essere adiacente ma la freccia dovrebbe dare la priorità andando su un - o | prima". mette un approccio vettoriale in svantaggio. Comunque, l'ho appena ignorato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.