¿Cómo expresar la secuencia de suma doble doble variable en Perl 6?
Para ver un ejemplo de secuencia de suma doble doble variable , vea esto
Debe expresarse como es, es decir, sin reducir matemáticamente la suma doble en una sola suma. Gracias.
El X
(operador cruzado) y el [+]
(metaoperador de reducción [ ]
con operador aditivo +
) hacen que esto sea sorprendentemente fácil:
Para representar 1 la suma doble ∑³ x = 1 ∑⁵ y = 1 2x + y , puede hacer lo siguiente:
[+] do for 1..3 X 1..5 -> ($x, $y) { 2 * $x + $y }
# for 1..3 X 1..5 # loop cross values
# -> ($x, $y) # plug into x/y
# { 2 * $x + $y } # calculate each iteration
# do # collect loop return vals
# [+] # sum them all
Si desea crear un sub
para esto, puede escribirlo como los siguientes 2
sub ΣΣ (
Int $aₒ, Int $aₙ, # to / from for the outer
Int $bₒ, Int $bₙ, # to / from for the inner
&f where .arity = 2 # 'where' clause guarantees only two params
) {
[+] do for $aₒ..$aₙ X $bₒ..$bₙ -> ($a, $b) { &f(a,b) }
}
say ΣΣ 1,3, 1,5, { 2 * $^x + $^y }
O incluso simplificar las cosas más para
sub ΣΣ (
Iterable \a, # outer values
Iterable \b, # inner values
&f where .arity = 2) { # ensure only two parameters
[+] do f(|$_) for a X b
}
# All of the following are equivalent
say ΣΣ 1..3, 1..5, -> $x, $y { 2 * $x + $y }; # Anonymous block
say ΣΣ 1..3, 1..5, { 2 * $^x + $^y }; # Alphabetic args
say ΣΣ 1..3, 1..5, 2 * * + * ; # Overkill, but Whatever ;-)
Tenga en cuenta que al escribirlo, podemos garantizar que se pasan los rangos, pero al escribirlo en Iterable
lugar de Range
permitir secuencias de suma más interesantes, como, por ejemplo,ΣΣ (1..∞).grep(*.is-prime)[^99], 1..10, { … }
eso nos permitiría usar la secuencia de los primeros 100 primos.
De hecho, si realmente quisiéramos, podríamos ir por la borda y permitir un operador arbitrario de suma de profundidad, que se hace más fácil moviendo la función a la izquierda:
sub ΣΣ (
&function,
**@ranges where # slurp in the ranges
.all ~~ Iterable && # make sure they're Iterables
.elems == &function.arity # one per argument in the function
) {
[+] do function(|$_) for [X] @ranges;
};
Al igual que [+]
resume todos los valores de nuestra f()
función, [X]
calcula la cruz iterativamente, por ejemplo, [X] 0..1, 3..4, 5..6
primero does 0..1 X 3..4
o (0,3),(0,4),(1,3),(1,4)
, y luego does (0,3),(0,4),(1,3),(1,4) X 5..6
, o (0,3,5),(0,4,5),(1,3,5),(1,4,5),(0,3,6),(0,4,6),(1,3,6),(1,4,6)
.
1. Lo siento, SO no me deja hacer LaTeX, pero debes tener la idea. 2. Sí, sé que es una letra de subíndice O no un cero, los números de subíndice no son identificadores válidos normalmente, pero puede usar Slang :: Subscripts para habilitarlos.