2010-06-07 27 views
2

Imaginez que j'ai défini le nom suivant dans J:Comment puis-je définir un verbe dans J qui applique alternativement un verbe différent à chaque atome d'une liste?

m =: >: i. 2 4 5

Cela ressemble à ce qui suit:

 1 2 3 4 5 
6 7 8 9 10 
11 12 13 14 15 
16 17 18 19 20 

21 22 23 24 25 
26 27 28 29 30 
31 32 33 34 35 
36 37 38 39 40

Je veux créer un verbe monadique de rang 1 qui s'applique à chaque liste dans cette liste des listes. Il va doubler (+:) ou ajouter 1 (>:) à chaque élément alternatif dans la liste. Si nous devions appliquer ce verbe à la première ligne, nous obtiendrions 2 3 6 5 10.

Il est assez facile d'obtenir une liste de booléens qui alternent avec chaque élément, par exemple, 0 1 $~{:$ m nous donne 0 1 0 1 0. Je pensais, aha! Je vais utiliser quelque chose comme +: ` >: @. suivi d'une expression, mais je ne pourrais jamais vraiment le faire fonctionner.

Des suggestions?

MISE À JOUR

qui suit semble fonctionner, mais peut-être il peut être quelque chose de plus remaniée avec élégance par un pro J.

poop =: monad define 
    (($ y) $ 0 1 $~{:$ y) ((]+:)`(]>:) @. [)"0 y 
)
+1

Merci à David, la réponse finale semble être, @ (+: '>: /.)" 1 –

Répondre

2

je voudrais utiliser le verbe oblique, avec le rang 1 (/."1) - de sorte qu'il applique aux éléments successifs de chaque liste à son tour.

Vous pouvez passer un gerund dans /. et il les applique dans l'ordre, en développant cycliquement.

+:`>: /."1 m 
2 
3 
6 
5 
10 

12 
8 
16 
10 
20 

22 
13 
26 
15 
30 

32 
18 
36 
20 
40 


42 
23 
46 
25 
50 

52 
28 
56 
30 
60 

62 
33 
66 
35 
70 

72 
38 
76 
40 
80 
+0

C'est presque ce dont j'ai besoin! Le seul problème est que j'ai besoin de la forme originale (2 4 5) de retour après. Je ne sais pas comment faire ça. –

+0

Je l'ai compris: ($ m) $, ^: _ +: '>: /."1 m –

+0

En fait, je n'ai même pas besoin de la conjonction de puissance, donc je peux juste dire: ($ m) $, +: '>: /." 1 m –

1

J'ai passé beaucoup de temps et je l'ai regardé, et je crois que je sais pourquoi ,@ travaille pour récupérer la forme de l'argument.

La forme des arguments de la phrase entre parenthèses est la forme de l'argument qui lui est passé à droite, même si le rang est modifié par le conjugué " (bien, c'est ce que la trace l'a appelé, je pensais que c'était un adverbe). Si , était monadique, ce serait un défilement, et le résultat serait un vecteur ou au moins d'un rang inférieur à l'entrée, basé sur des adverbes à défiler. C'est ce qui arrive si vous prenez la conjonction - vous obtenez un vecteur.

Donc ce que je crois se passe est que la conjonction fait , agir comme un , dyadique qui est appelé un append. L'append modifie ce qu'il ajoute à ce qu'il ajoute. Il n'a rien à ajouter mais cette chose a toujours une forme, et finit par modifier le vecteur intermédiaire en fonction de la forme de l'entrée.

Maintenant, je me trompe probablement. Mais $,"[email protected](+:>: /.) "1>: i 2 4 5 -> 2 4 5 1 1` que je pensais en quelque sorte prouvé mon cas

1

(, @ (+:`>: /.) " 1 a) fonctionne, mais notez que ((* 2 1 $ ~ $) @ (+ 0 1 $ ~ $) "1 a) aurait aussi fonctionné (et est environ 20 fois plus rapide, sur de grands réseaux, dans mes brefs tests