Para onde a flecha está apontando?

32

Para onde a flecha está apontando?

Neste desafio, seu objetivo é seguir uma seta e exibir o personagem para o qual está apontando.

Exemplos

Entrada:

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

Saída: a


Entrada:

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

Saída: b

A seta não está apontando cporque está dividida por a, o que significa que esse caminho nunca leva a uma ponta de seta.


Entrada:

a S      s
  |      |
  V      V
  b      c

Saída: b


Entrada:

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

Saída: Q

Esse caminho começa no S, desce, à direita, sobe, à direita e depois aponta para o Q. Observe que o caminho não vai direto de Spara +.


Entrada:

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

Saída: A


Entrada:

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

Saída: B

Porque a linha válida nunca levará a um caractere de espaço em branco. A única linha que não leva a um caractere de espaço em branco leva a umB

Desafio

A entrada será uma sequência de várias linhas na qual você precisará encontrar o caractere para o qual a seta está apontando. Haverá apenas uma seta válida. A seta válida apontará apenas para caracteres alfanuméricos, exceto S. Uma linha nunca se sobrepõe. por exemplo-|-

  • S (capital) representa onde a seta começa.
  • - representa uma linha horizontal
  • +representa uma possível mudança no eixo. Uma seta válida nunca começará com a +.
  • | representa uma linha vertical
  • > < V ^qualquer um deles representa a ponta da seta. Estes nunca se conectam a um +.

Haverá apenas um Sna string. A entrada também será preenchida para ser um retângulo (não necessariamente um quadrado).

Downgoat
fonte
11
"Isso nunca aparecerá adjacente a um S." Provavelmente deve ser reformulado para "Este nunca será o primeiro caractere da seta". (Como o Qexemplo tem um +adjacente a um S.) " +Representa uma mudança no eixo". pode ser " +representa uma possível alteração no eixo". (Como o Bexemplo mostra que você pode avançar +sem mudar de direção.) Caso contrário, é um bom desafio. :)
Martin Ender
Fiz uma alteração em um dos seus casos de teste. Eu acho que vai torná-lo mais difícil de escrever programas que só acontecem para obter a resposta certa, como o meu fez em primeiro lugar.
El'endia Starman
A ponta da seta pode mudar de direção, ou seja ---^? Em outras palavras, se no exemplo B, o B poderia permanecer na primeira linha?
Edc65
@ edc65, como no exemplo Q?
Downgoat 20/09/2015
11
Uma ponta de seta não será conectada a '+'. Mas poderia estar conectado ao 'S'? É S>aválido?
Edc65 22/09/2015

Respostas:

9

JavaScript (ES6), 195 245 231 242 246 250

Edit4 Agora, uma única função recursiva. Provavelmente não pode mais jogar golfe

Edit3 Teste para linha reta e teste para ponta de seta mesclada na função T, funções S e H removidas.

Edit2 Revisado e mais :( depois disso, este esclarecimento

Editar Pequenas melhorias, cortando alguns caracteres aqui e ali, esperando o CJammers intervir

Teste a execução do snippet abaixo em um navegador compatível com EcmaScript 6. (funciona no Firefox. Chrome ainda está sem o operador de propagação ...)

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>

edc65
fonte
5

JavaScript 2016, 264263249240235234 bytes

Execute-o no 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<----+`)

Espalhados em algumas das minhas anotações:

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
bopjesvla
fonte
Você pode economizar alguns bits fazendo o = 'indexOf'e fazendo q[o](e)quando quiser usá-lo.
Não que Charles
Além disso, no código golf, os for(;;)loops são geralmente mais eficientes. Pode estar errado neste caso, mas tente.
Não que Charles
11
caso de teste a<-+S->beu acho que deveria dar bapenas, como uma seta válido nunca vai começar com um +
edc65
Corrigido isso e transformou f em uma linha. A propósito, gostei muito da sua abordagem para esse problema.
bopjesvla
Uma observação: eu realmente amo a compreensão de array, mas não está mais em nenhuma versão do padrão EcmaScript. Sugiro para marcá-lo anser JavaScript 2016(stiil uma resposta válida e bom, não problema com ele)
edc65
3

VBA Excel 2007, 894 bytes

Bem, isso começou muito melhor do que acabou. Tenho a sensação de que minha lógica é falha e eu poderia ter economizado uma tonelada de bytes se eu reorganizasse parte da minha lógica, mas já se passou muito tempo nisso = P

A entrada para isso é a coluna A de qualquer planilha em que você esteja. Esse método usa o fato de que o Excel possui essa grade agradável e divide tudo para que você possa ver o que está fazendo com mais clareza.

Sub m()está apenas pegando os dados colados Copiar da coluna A e dividindo-os por char. Se permitirmos uma entrada modificada, se você pré-formatar o labirinto em 1 caractere por célula, poderá salvar alguns bytes removendosub m()

Cole um labirinto no Excel de qualquer tamanho, com até 99 linhas por 27 caracteres. Se você deseja labirintos maiores, seus apenas 2 bytes extras aumentam o escopo para 999 linhas e colunas ZZ

Também pode ser necessário que os juízes liguem se uma planilha do Excel é "Entrada padrão" válida para uma resposta do VBA. Caso contrário, é praticamente impossível fornecer a entrada VBA Multi-line via janela imediata

Para executar esse código, cole-o em um módulo do Excel, cole um labirinto em A1 e execute 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
JimmyJazzx
fonte
2

Python 3, 349 bytes

Ugh, tantos bytes.

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

Essencialmente, uma pesquisa pela primeira vez. Bônus: isso realmente sai normalmente, em vez de usar exit(), que é mais longo de qualquer maneira.

El'endia Starman
fonte
Isso não implementa cerca de metade das restrições de busca, cara. ideone.com/OzoWRX
bopjesvla
@bopjesvla: Drat, você está certo. Bom local!
El'endia Starman
Como você é capaz de usar uma seqüência de linhas múltiplas input()? É problemático para mim.
The_Basset_Hound
@The_Basset_Hound: você não pode inserir manualmente as novas linhas; você precisa copiar e colar a coisa toda de uma só vez.
El'endia Starman 22/09/2015
@ El'endiaStarman Estou copiando / colando e ainda está lendo a primeira linha que parece.
The_Basset_Hound
2

Perl 5

A solução ficou mais tempo do que outras soluções.
Mesmo depois de jogar golfe. Portanto, esta é a versão não destruída.
Ele imprime o mapa para que você possa seguir o cursor.

Como funciona? A cada passo, coloca possíveis movimentos na pilha. E continua funcionando até não sobrar mais nada na pilha ou encontrar uma solução.
Pode ser facilmente modificado para encontrar todas as soluções e escolher o mais próximo -> 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;
}

Teste

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

$ perl arrows.pl < test_arrows6.txt
.-----+
.     +-^
......XB
    .....
B
LukStorms
fonte
2
Eu vi o título e pensei "Perl" e "feito em 5 bytes". ataque cardíaco
Conor O'Brien
2

Versão PHP (os comentários são em francês, desculpe)

<?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;
}
gnieark
fonte
1

Haskell, 268 bytes

Parabéns aos Javascripters! Desisti da recompensa, mas aqui está o que eu tenho. Pode não funcionar em todos os casos, mas na verdade lida com as setas iniciando e as pontas de flechas conectando-se a +es, até onde eu sei. Nem sequer incluiu a pesquisa do S, é apenas (0,0)por enquanto.

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
Leif Willerts
fonte
0

Gostaria de ver uma versão da APL em espírito de https://www.youtube.com/watch?v=a9xAKttWgP4

Para começar, uma solução Julia vetorizada que eu acho que pode ser traduzida 1: 0,3 para APL ou J. É necessária uma string R representando um diagrama de seta L x K. Ele primeiro converte a matriz de símbolos em uma matriz de pequenas matrizes 3x3 cujos padrões são as expansões binárias das letras da string "\ 0 \ x18 \ fH \ t]] \ x1cI". Por exemplo, '+' é codificado como remodelado ([0, dígitos (int (']'), 2,8)], 3,3)

  0 2 0
  2 2 2
  0 2 0

Nesta representação, o caminho consiste em 2 e é inundado por 3 a partir do ponto de partida.

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

Testar,

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

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


   include("arrow.jl")

a

A propósito, acho que a cláusula "Outro + pode estar adjacente, mas a flecha deve priorizar a entrada em - ou | primeiro". coloca uma abordagem vetorial em desvantagem. Enfim, eu simplesmente ignorei.

mschauer
fonte