Où suis-je maintenant?

21

Où suis-je maintenant?

Étant donné une chaîne d , contenant uniquement les lettres NSWE, déterminez les coordonnées que j'ai parcourues (de gauche à droite, en consommant goulûment) et la coordonnée finale où je réside.

Les règles de lecture des coordonnées de gauche à droite:

  • Si le caractère suivant est NouS :
    • Si le caractère après le Nou Sest un autre NouS :
      • Consommez seulement le premier N ou S.
      • Production [0,1] pourN
      • Sortie [0,-1]pourS
    • Si le caractère après le Nou Sest WouE :
      • Consommez à la fois le Nou Set le Wou E.
      • Sortie [1,1]ou [-1,1]pour NEet NW, respectivement.
      • Sortie [1,-1]ou [-1,-1]pour SEet SW, respectivement.
  • Si le caractère est un Eou Wnon précédé d'un SouN :
    • Consommez le Eou W.
    • Sortie [1,0]pour E.
    • Sortie [-1,0]pour W.

Exemple travaillé

NSWE

[0,1]   (North      N)
[-1,-1] (South-west SW)
[1,0]   (East       E)
[0,0]   (N+SW+E = Didn't actually move)

Notez que cela peut être dans n'importe quel format, voici d'autres exemples de sortie valide:

[[0,1],[-1,-1],[1,0],[0,0]]


[[[0,1],[-1,-1],[1,0]],[0,0]]


"0,1\n0,-1\n-1,0\n1,0\n0,0"

Etc...


Plus d'exemples

SWSENNESWNE

[-1,-1]
[1,-1]
[0,1]
[1,1]
[-1,-1]
[1,1]
[1,0]

NNEESESSWWNW

[0,1]
[1,1]
[1,0]
[1,-1]
[0,-1]
[-1,-1]
[-1,0]
[-1,1]
[0,0]

NENENEE

[1,1]
[1,1]
[1,1]
[1,0]
[4,3]

NEN

[1,1]
[0,1]
[1,2]

EEE

[1,0]
[1,0]
[1,0]
[3,0]

Règles

  • Vous pouvez produire dans n'importe quel format pratique qui ne viole pas les failles.
  • Il faut consommer goulûment, ce NWEn'est jamais N,W,E, c'est toujours NW,E.
    • Ceci est valable pour: SW*, SE*, NW*, NE*.
    • Vous consommez de gauche à droite, avidement.
  • C'est le , le plus petit nombre de victoires.
Urne de poulpe magique
la source
"déterminer les coordonnées que j'ai parcourues" : je ne sais pas si cela correspond vraiment à ce qui est décrit par la suite. C'est plus comme "déterminer les vecteurs de tous mes mouvements" . Seule la sortie finale est des coordonnées réelles.
Arnauld
1
Un cas de test qui marche vers [4, 3]ou ainsi faciliterait un peu plus facilement ce qui se passe dans la sortie de test.
Lynn
3
Sont des nombres complexes en forme comme 1, -1j, (-1+1j)etc un format de sortie valide?
Lynn
2
Sur la base de l'absence de ce cas dans les règles et les exemples donnés, je suppose que la chaîne d'entrée ne se terminera jamais par un «N» ou un «S»?
Kevin Cruijssen
1
Est-ce que consommer goulûment est réellement différent du contraire? Puisque NEc'est juste, N+Eça ne devrait pas avoir d'importance?
Wheat Wizard

Réponses:

7

Python 2 , 116 octets

import re
a=[(int(s,35)%5-3,('N'in s)-('S'in s))for s in re.findall('[NS][EW]?|.',input())]
print a,map(sum,zip(*a))

Essayez-le en ligne!

Avec sortie as [(3+4j), 1, -1j, …], 91 octets

lambda x:[sum(1j**(ord(c)%8%5)for c in s)for s in[x]+re.findall('[NS][EW]?|.',x)]
import re

Essayez-le en ligne!

Ce lambda renvoie une liste d' entiers gaussiens : le premier est la coordonnée finale, et toutes les autres sont les étapes nécessaires pour y arriver.

Lynn
la source
5

Attaché , 80 octets

V#Sum##{Chop[1-ToBase[22260446188,3],2][Sum@Ords=>MatchAll[_,/"[NS][WE]|."]%11]}

Essayez-le en ligne!

Il s'agit d'une fonction anonyme qui prend un argument de chaîne.

Explication

La première tâche consiste à implémenter la phase d'analyse de cette question. J'ai trouvé plus court d'utiliser une simple regex pour analyser l'entrée ( _):

MatchAll[_,/"[NS][WE]|."]

Cela correspond à toutes les occurrences de l'expression régulière [NS][WE]|., comme on le voit dans de nombreuses autres réponses. Cela donne goulûment les directions demandées.

Maintenant, nous allons appliquer une fonction de hachage à chaque direciton. Nous prenons les points de code de chaque direction et les additionnons. Cela donne le mappage suivant:

Direction       Ord-sum
E               69
N               78
S               83
W               87
NE              147
SE              152
NW              165
SW              170

Nous allons essayer de mapper ces valeurs à un domaine plus petit; modulo est utile pour cela, et nous pouvons démontrer que le plus petit modulo qui donne des valeurs uniques pour toutes les entrées données est 11. Le tri par reste, cela nous donne le tableau suivant:

Direction       Ord-sum         % 11
NW              165             0
N               78              1
E               69              3
NE              147             4
SW              170             5
S               83              6
SE              152             9
W               87              10

Maintenant, nous avons une correspondance d'entrée, comme le codage par Sum@Ords=>[...]%11. Ensuite, nous devons transformer ces restes en points. Nous allons essayer de dériver une autre cartographie, ce qui signifie qu'il sera utile d'insérer des «valeurs de remplissage clairsemé» dans des hachages qui ne correspondent pas aux directions:

Direction       Hash        Coordinates
NW              0           [-1, 1]
N               1           [0, 1]
--             (2)          [0, 0]
E               3           [1, 0]
NE              4           [1, 1]
SW              5           [-1, -1]
S               6           [0, -1]
--             (7)          [0, 0]
--             (8)          [0, 0]
SE              9           [1, -1]
W               10          [-1, 0]

Nous avons actuellement une série de points, ce qui peut donner une liste indexable par le hachage:

[-1, 1] [0, 1] [0, 0] [1, 0] [1, 1] [-1, -1] [0, -1] [0, 0] [0, 0] [1, -1] [-1, 0]

Maintenant, nous allons compresser cela, vu que son seul composé de -1s, 0s et 1s. Puisque la liste représente des paires, nous pouvons aplatir la liste sans perdre de données. Ensuite, si nous prenons chaque nombre xet calculons 1-x, nous obtenons la liste suivante:

2 0 1 0 1 1 0 1 0 0 2 2 1 2 1 1 1 1 0 2 2 1

Nous pouvons le convertir en un nombre de base 3:

20101101002212111102213

Conversion en base 10:

20101101002212111102213 ≡ 2226044618810

Pour résumer, nous avons pris nos points, les découplés, pris chaque élément soustrait 1et converti de la base 3, ce qui nous donne 22260446188. On peut décompresser comme tel:

  1. Convertir en base 3: ToBase[22260446188,3]
  2. Prenez chaque nombre soustrait d'un (auto-inverse): 1-ToBase[22260446188,3]
  3. Re-coupler la liste: Chop[1-ToBase[22260446188,3],2]

Cela nous donne notre ensemble de paires d'origine. Ensuite, nous pouvons effectuer l'indexation susmentionnée comme ceci:

(chopped value)[hashes]

Puisque, dans Attache, l'indexation par un tableau renvoie tous les éléments correspondant à ces indices. (Donc [1,2,3,4][ [0,0,-1,1] ] = [1,1,4,2],.) Maintenant, nous avons les directions du chemin parcouru par l'OP. Il ne reste plus qu'à calculer la somme.

Nous capturons donc ce résultat dans un lambda {...}et le mettons comme première fonction dans une composition de fonction ( a##b), la seconde étant V#Sum. Ceci est un fork, qui, étant donné l'entrée x, se développe pour être:

V[x, Sum[x]]

Sum, lorsqu'il est donné un tableau 2D, arrive à additionner chaque colonne du tableau (à la suite de la sommation vectorisée). Donc, cela associe les directions avec la destination finale, et nous avons notre résultat final.

Conor O'Brien
la source
4

JavaScript (ES6), 102 octets

Renvoie une chaîne.

s=>s.replace(/[NS][EW]|./g,s=>(D=d=>!!s.match(d),x+=h=D`E`-D`W`,y+=v=D`N`-D`S`,[h,v]+`
`),x=y=0)+[x,y]

Essayez-le en ligne!

Arnauld
la source
J'aime l'utilisation des fonctions de modèle! : D
Conor O'Brien
@ ConorO'Brien Oui, ils sont assez pratiques ici. Tous les sorts de rituel de hachage que j'ai invoqués jusqu'à présent sont au moins un peu plus longs.
Arnauld
4

MATL , 45 octets

'NS' 'WE'Z*Z{2MhX{h'eklihfmj'X{YX9\3_2&YAqts

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication (avec exemple)

Considérez la saisie 'NSWE'comme exemple.

'NS' 'WE'  % Push these two strings
           % STACK: 'NS', 'WE'
Z*         % Cartesian product. Gives a 4×2 char matrix
           % STACK: ['NW'; 'NE'; 'SW'; 'SE']
Z{         % Cell array of rows (strings)
           % STACK: {'NW', 'NE', 'SW', 'SE'}
2M         % Push again the inputs of the second-last function call
           % STACK: {'NW', 'NE', 'SW', 'SE'}, 'NS', 'WE'
h          % Concatenate horizontally
           % STACK: {'NW', 'NE', 'SW', 'SE'}, 'NSWE'
X{         % Cell array of individual elements (chars)
           % STACK: {'NW', 'NE', 'SW', 'SE'}, {'N', 'S', 'W', 'E'}
h          % Concatenate horizontally
           % STACK: {'NW', 'NE', 'SW', 'SE', 'N', 'S', 'W', 'E'}
'eklihfmj' % Push this string
           % STACK: {'NW', 'NE', 'SW', 'SE', 'N', 'S', 'W', 'E'}, 'eklihfmj'
X{         % Cell array of individual elements (chars)
           % STACK: {'NW','NE','SW','SE','N','S','W','E'},{'e','k','l','i','h','f','m','j'}
YX         % Implicit input. Regexp replace: replaces 'NW' by 'e', then 'NE' by 'k', etc.
           % Note that the two-letter combinations are replaced first, which implements
           % the greediness; and the target letters do not appear in the source, which
           % avoids unwanted interactions between replacements
           % STACK: 'hlj'
9\         % Modulo 9 (of codepoints), element-wise
           % STACK: [5, 0, 7]
3_2&YA     % Convert to base 3 with 2 digits. Gives a 2-column matrix
           % STACK: [1, 2; 0, 0; 2, 1]
q          % Subtract 1, element-wise
           % STACK: [0, -1; -1, -1; 1, 0]
tXs        % Duplicate. Sum of each column
           % STACK: [0, -1; -1, -1; 1, 0], [0, 0]
           % Implicit display
Luis Mendo
la source
4

Java (JDK 10) , 171 octets

s->{var r="";int i=0,l=s.length,c,x=0,y=0,Y,X;for(;i<l;X=c>1||i<l&&(c=~-s[i]/6%4)>1&&++i>0?c*2-5:0,r+=X+","+Y+" ",x+=X,y+=Y)Y=(c=~-s[i++]/6%4)<2?1-c*2:0;return r+x+","+y;}

Essayez-le en ligne!

Explications

Grâce à c=~-s[i]/6%4, la cartographie suivante est effectuée:

'N' -> ascii: 78 -> -1 = 77 -> /6 = 12 -> %4 = 0
'S' -> ascii: 83 -> -1 = 83 -> /6 = 13 -> %4 = 1
'W' -> ascii: 87 -> -1 = 86 -> /6 = 14 -> %4 = 2
'E' -> ascii: 69 -> -1 = 68 -> /6 = 11 -> %4 = 3
  • NSest vérifié avec c<2et mappé à +1/ en -1utilisant 1-c*2;
  • EWest vérifié avec c>1et mappé à +1/ en -1utilisant c*2-5.

Crédits

Olivier Grégoire
la source
Ah, vous avez posté votre réponse Java pendant que je tapais l'explication de la mienne. :) Puisque nous utilisons tous les deux une approche complètement différente, je vais laisser la mienne pour l'instant. Dommage que les variables utilisées dans lambdas doivent être effectivement définitives, sinon vous auriez pu renvoyer une chaîne au lieu d'une liste pour enregistrer les octets.
Kevin Cruijssen
Merci, cela n'a sauvé que quelques octets (4), mais c'est mieux que rien;)
Olivier Grégoire
@KevinCruijssen Merci, cela semblait plutôt évident au début, mais je travaillais sur une autre approche qui a réduit mon nombre d'octets de plus de 30. Une analyse "," pas une "correspondance".
Olivier Grégoire
1
Soupir .. 172 octets
Kevin Cruijssen
1
@KevinCruijssen Désolé, c'est un gâchis d'intégrer vos changements ... Je suis pris au travail et j'oublie de rafraîchir cette page ... Merci pour tout de même ^^ 'Le décompte de crédits est très probablement inférieur à votre crédit réel. Désolé pour ça aussi: s
Olivier Grégoire
3

Retina 0.8.2 , 93 octets

.+
$&¶$&
\G[NS]?[EW]?
$&¶
G`.
W
J
%O`.
+`EJ|NS

m`^((J)?[EJ]*)((S)?[NS]*)
$#2$*-$.1,$#4$*-$.3

Essayez-le en ligne! Explication:

.+
$&¶$&

Dupliquez l'entrée.

\G[NS]?[EW]?
$&¶

Divisez la première copie en directions.

G`.

Supprimez les lignes vierges étrangères créées par le processus ci-dessus.

W
J

Changez Wen Jpour qu'il trie entre Eet N. (Passer Eentre Set Wfonctionnerait aussi.)

%O`.

Triez chaque ligne dans l'ordre.

+`EJ|NS

Supprimez les paires de directions opposées (cela n'affecte que la dernière ligne bien sûr).

m`^((J)?[EJ]*)((S)?[NS]*)
$#2$*-$.1,$#4$*-$.3

Comptez le nombre de mouvements horizontaux et verticaux, en ajoutant des panneaux si nécessaire.

Ceux d'entre vous qui connaissent les différences entre Retina 0.8.2 et Retina 1 voudront souligner que je peux enregistrer 2 octets dans Retina 1 car il utilise à la *place de $*. Pendant que j'étais là, j'ai essayé de simplifier le processus de fractionnement, mais je n'ai pas pu réduire davantage le nombre d'octets, je ne pouvais que l'égaler avec ceci:

L$`$(?<=(.*))|[NS]?[EW]?
$&$1
Neil
la source
3

Java 10, 269 265 243 octets

s->{var r="";int x=0,y=0,t,X,Y,a;for(;!s.isEmpty();r+=X+"|"+Y+" ",s=s.substring(++t),x+=X,y+=Y){a=s.charAt(t=0);if(s.matches("[SN][WE].*")){X=s.charAt(1)<70?1:-1;Y=1-a%2*2;t++;}else{X=a<70?1:a>86?-1:0;Y=a>69&a<87?1-a%2*2:0;}}return r+x+"|"+y;}

Certainement pas la bonne langue pour ce défi ..

Essayez-le en ligne.

Explication:

s->{                  // Method with String as both parameter and return-type
  var r="";           //  Result-String, starting empty
  int x=0,            //  Ending `x`-coordinate, starting at 0
      y=0,            //  Ending `y`-coordinate, starting at 0
      t,X,Y,a;        //  Temp-integers
  for(;!s.isEmpty()   //  Loop as long as the input-String is not empty yet
      ;               //    After every iteration:
       r+=X+"|"+Y+" ",//     Append the current steps to the result-String
       s=s.substring(t),
                      //     Remove the first `t` characters from the input-String
       x+=X,y+=Y){   //      Append the ending `x`,`y` coordinates with the steps
    a=s.charAt(0);   //    Set `a` to the first character of the input-String to save bytes
    t=1;             //    Set `t` to 1
    if(s.matches("[SN][WE].*")){
                     //   Else-if the input-String starts with N/S followed by E/W:
      X=s.charAt(1)<70?1:-1;
                     //    Set `X` to 1 if 'E', -1 if 'W'
      Y=1-a%2*2;     //    Set `Y` to 1 if 'N', -1 if 'S'
      t++;}          //    Increase `t` by 1
    else{            //   Else:
      X=a<70?1:a>86?-1:0;
                     //    Set `X` to 1 if 'E', -1 if 'W', 0 if 'N' or 'S'
      Y=a>69&a<87?1-a%2*2:0;}}
                     //    Set `Y` 1 if 'N', -1 if 'S', 0 if 'E' or 'W'
  return r+x+"|"+y;} //  Append the ending coordinates, and return the result-String
Kevin Cruijssen
la source
1
Les réponses Java obtiennent des points car tout le monde les obtient :).
Urne de poulpe magique du
@MagicOctopusUrn True. :) Et j'aime toujours jouer au golf à Java, même si vous ne serez jamais le plus court .. Sauf si vous êtes le seul à répondre (j'ai obtenu deux réponses Java acceptées .. XD). Pour ce défi cependant, la réponse Java d'OlivierGrégoire est environ 70 octets plus courte, donc la plupart des votes positifs devraient aller vers lui.
Kevin Cruijssen
2

Perl 5 -n , 94 octets

$x=$y=0;%X=qw/E ++ W --/;%Y=qw/N ++ S --/;s%(N|S)?(E|W)?%"say $X{$2}\$x.','.$Y{$1}\$y"if$&%gee

Essayez-le en ligne!

Xcali
la source
2

JavaScript (ES6), 102 octets

f=
s=>s.replace(/((N)|(S))?((E)|(W))?/g,(m,v,n,s,h,e,w)=>(x+=h=!w-!e,y+=v=!s-!n,m?[h,v]+`
`:[x,y]),x=y=0)
<input oninput=o.textContent=/[^NSEW]/.test(this.value)?``:f(this.value)><pre id=o>0,0

Renvoie une chaîne.

Neil
la source
1

Rubis , 75 71 octets

->x{[*x.scan(/[NS][EW]?|./),x].map{|s|s.chars.sum{|c|1i**(c.ord%8%5)}}}

Essayez-le en ligne!

-4 octets grâce à benj2240.

Étant donné que le retour de nombres complexes semble être un format de sortie acceptable, je suppose que cela ne deviendra pas beaucoup plus golfique que de simplement faire un portage de la très belle réponse de Lynn .

Kirill L.
la source
Très agréable. vous pouvez économiser quelques octets en sautant l'intérieur map, en passant directement son bloc à sum: Essayez-le en ligne!
benj2240
1

F # (Mono) , 269 octets

let f s=
 let l,h=(string s).Replace("NW","A").Replace("NE","B").Replace("SW","C").Replace("SE","D")|>Seq.map(function 'N'->0,1|'S'->0,-1|'W'-> -1,0|'E'->1,0|'A'-> -1,1|'B'->1,1|'C'-> -1,-1|'D'->1,-1)|>Seq.mapFold(fun(x,y) (s,t)->(s,t),(x+s,y+t))(0,0)
 Seq.append l [h]

Essayez-le en ligne!

Henrik Hansen
la source
Salut, bienvenue à PPCG. Malheureusement, il vous manque le dernier élément de votre sortie, qui devrait être la position où vous avez terminé. Donc , pour le NSWEvous restituent (0,1), (-1,-1), (1,0)mais une quatrième sortie devrait être la somme de ces coordonnées, donc (0,0)(car 0+-1+1 = 0et 1+-1+0 = 0).
Kevin Cruijssen
@KevinCruijssen OK, je n'ai pas compris ça. Fait une mise à jour.
Henrik Hansen
1
Semble fonctionner très bien maintenant, alors +1 de moi. Profitez de votre séjour! :) Et au cas où vous ne l'auriez pas encore vu, des conseils pour jouer au golf en F # et des conseils pour jouer au golf dans <toutes les langues> pourraient être intéressants à lire.
Kevin Cruijssen
1

sed, 125

La prise de libertés avec la version du format de sortie :

Le score inclut +1 pour le -rparamètre à sed.

s/(N|S)(E|W)/\L\2,\1 /g
s/N|S/,& /g
s/E|W/&, /g
s/N|E/A/gi
s/S|W/a/gi
p
:
s/(\S*),(\S*) (\S*),(\S*)/\1\3,\2\4/
t
s/Aa|aA//
t

Essayez-le en ligne .

La sortie est la suivante:

  • les éléments de coordonnées sont séparés par des virgules
  • chaque ensemble de coordonnées est séparé par TAB
  • la coordonnée finale est sur une nouvelle ligne
  • tous les nombres sont en ℤ-unaire:
    • une chaîne de Acaractères représente le nombre entier + velen(string)
    • une chaîne de acaractères représente l'entier -ve-len(string)
    • la chaîne vide représente 0

Par exemple:

  • , est [0,0]
  • ,AA est [0,2]
  • aaa, est [-3,0]

sed 4.2.2 avec extension GNU exec , 147

La version de format de sortie sensible :

Le score inclut +1 pour le -rparamètre à sed.

s/(N|S)(E|W)/\L\2 \1\n/g
s/N|S/0 &\n/g
s/E|W/& 0\n/g
s/N|E/1/gi
s/S|W/-1/gi
p
:
s/(\S+) (\S+)\n(\S+) (\S+)/\1+\3 \2+\4/
t
s/\S+/$[&]/g
s/^/echo /e

La sortie est donnée sous forme de coordonnées séparées par des espaces, une par ligne. Il y a une nouvelle ligne supplémentaire entre l'avant-dernier et les ensembles ultimes de coordonnées - je ne sais pas si c'est problématique ou non.

Essayez-le en ligne!

Traumatisme numérique
la source
0

PHP, 153 octets

laissez un regex faire le fractionnement; parcourir les correspondances, imprimer et résumer les résultats intermédiaires:

preg_match_all("/[NS][EW]?|E|W/",$argn,$m);foreach($m[0]as$s){$x+=$p=strtr($s[-1],NEWS,1201)-1;$y+=$q=strtr($s[0],NEWS,2110)-1;echo"$p,$q
";}echo"$x,$y";

Exécuter en tant que pipe avec -nRou l' essayer en ligne .

Titus
la source
0

C (gcc) , 173 octets

C'est intéressant de faire celui-ci dans une langue sans support regex!

f(char*s){char*t="[%d,%d]\n";int x[4]={0},i;for(;*s;*x=x[1]=!printf(t,x[1],*x))for(i=-1;i<5;)if(*s=="S NW E"[++i]){x[i/3+2]+=x[i/3]=i%3-1;i+=2-i%3;s++;}printf(t,x[3],x[2]);}

Essayez-le en ligne!

ErikF
la source
164 octets
plafondcat