2
votes

Additionner séparément les indices pairs et impairs d'un tableau - Perl

J'ai un tableau de 11 éléments. Où je veux additionner les éléments impairs, y compris le premier et le dernier élément comme un scalaire et les evens comme un autre.

Voici mon code J'essaie d'utiliser la carte en ajoutant 2 à chaque index pour obtenir le résultat mais je pense que j'ai s'est trompé.

use strict;
use warnings;
use Data::Dumper;

print 'Enter the 11 digiet serial number: ';
chomp( my @barcode = //, <STDIN> );

my @sum1 = map { 2 + $_ } $barcode[1] .. $barcode[11];
my $sum1 = sum Dumper( \@sum1 );

# sum2 = l2 + l4 + l6 + r8 + r10;
printf "{$sum1}";

Quel est le bon moyen d'y parvenir?


2 commentaires

Il s'agit d'une question «Déboguer mon code pour moi», qui n'est pas ici. Pouvez-vous nous expliquer votre code et expliquer ce que l'instruction map est censée faire? Surtout, que doit faire $ barcode [1] .. $ barcode [11] ? Regardez le cas de $ barcode [1] = 99 et $ barcode [11] = 0 .


normalement tableau de 11 éléments, les éléments sont indexés de 0 à 10; @barcode [0..10] notez le préfixe @ pour obtenir un tableau découpé


5 Réponses :


9
votes

Somme des indices pairs / impairs (ce que vous avez demandé, mais pas ce que vous voulez [1] ):

use List::Util qw( sum );   # Or: sub sum { my $acc; $acc += $_ for @_; $acc }

my $sum_of_vals_at_even_idxs = sum @nums[0,2,4,6,8,10];
my $sum_of_vals_at_odd_idxs  = sum @nums[1,3,5,7,9];

Somme des valeurs paires / impaires ( ce que vous avez également demandé, mais pas ce que vous voulez [1] ):

use List::Util qw( sum );   # Or: sub sum { my $acc; $acc += $_ for @_; $acc }

my $sum_of_vals_at_even_idxs = sum @nums[ grep { $_ % 2 == 0 } 0..$#nums ];
my $sum_of_vals_at_odd_idxs  = sum @nums[ grep { $_ % 2 == 1 } 0..$#nums ];

Somme des valeurs aux index pairs / impairs (ce que vous voyez à vouloir):

use List::Util qw( sum );   # Or: sub sum { my $acc; $acc += $_ for @_; $acc }

my $sum_of_even_vals = sum grep { $_ % 2 == 0 } @nums;
my $sum_of_odd_vals  = sum grep { $_ % 2 == 1 } @nums;

Étant donné que vous savez combien d'éléments vous avez, vous pouvez utiliser ce qui suit:

use List::Util qw( sum );   # Or: sub sum { my $acc; $acc += $_ for @_; $acc }

my $sum_of_even_idxs = sum grep { $_ % 2 == 0 } 0..$#nums;
my $sum_of_odd_idxs  = sum grep { $_ % 2 == 1 } 0..$#nums;

  1. Je les ai inclus au cas où quelqu'un aurait besoin de ces terres sur cette question et réponse.


2 commentaires

Vous pouvez réduire vos deux greps à, dans l'ordre grep {$ _% 2} et gerep {! ($ _% 2)}


1) Je ne l'ai pas fait pour la symétrie (qui produit un code plus clair). 2) Bien que cela réduise le nombre de jetons pour les cotes, cela augmente en fait le nombre de jetons pour les évens.



4
votes

Vous pouvez utiliser le fait que l'opérateur ?: est assignable

print 'Enter the 11 digiet serial number: ';
chomp( my @barcode = //, <STDIN> );

my $odd = 0;
my $even = 0;
for (my $index = 0; $index < @barcode; $index++) {
    ($index % 2 ? $even : $odd) += $barcode[$index];
}

Cela fonctionne en indexant sur @barcode et en prenant le mod 2 de l'index, c'est-à-dire en divisant l'index par 2 et en prenant le reste, et si le reste est 1 ajouter cet élément de @barcode à $ even sinon à $ impair .

Cela semble étrange jusqu'à ce que vous vous souveniez que les tableaux sont basés sur 0, donc votre premier numéro du code-barres est stocké dans $ barcode [0] qui est un index pair.


0 commentaires

5
votes

Additionnez les valeurs aux indices pairs et impairs

perl -wE'@ary = 1..6;  
    for (0..$#ary) { $_ & 1 ? $odds += $ary[$_] : $evens += $ary[$_] }; 
    say "odds: $odds, evens: $evens"
'

Remarque pour les tests: avec des indices pairs (0,2,4) nous avons des valeurs (impaires!) (1,3,5 ), dans cet exemple ( 1..6 )


1 commentaires

belle utilisation de l'opérateur ternaire pour attribuer des cotes / égales .. J'ai aussi posté une réponse pour cela ..



3
votes

chomp (my @barcode = //, ); était probablement censé avoir un split avant le // ?

@barcode aura tous les caractères de la ligne lus, y compris la nouvelle ligne. Le chomp changera l'élément final d'une nouvelle ligne en une chaîne vide.

Mieux vaut d'abord chomp pour avoir juste vos chiffres dans le tableau:

chomp(my $barcode = <STDIN>);
my @barcode = split //, $barcode;

p>


0 commentaires

3
votes

Un autre Perl, si la chaîne est de longueur 11 et ne contient que des chiffres

$ perl -le ' $_="12121212121"; s/(.)(.)|(.)$/$odd+=$1+$3;$even+=$2/ge; print "odd=$odd; even=$even" '
odd=6; even=10

$

avec une entrée différente

$ perl -le ' $_="12345678911"; s/(.)(.)|(.)$/$odd+=$1+$3;$even+=$2/ge; print "odd=$odd; even=$even" '
odd=26; even=21

$


1 commentaires

Une façon intéressante de faire pair / impair dans une chaîne! Nits à choisir: il est destructeur pour la chaîne d'origine (d'une manière qui n'est pas utile), et il utilise l'expression régulière avec / e pour son effet secondaire; peut peut-être faire la même chose mais comme while (/.../g) {$ odd + = ...} ? Je ne sais pas comment cela se passe en termes d'efficacité: le s /// fonctionne sous / e mais est une expression régulière tandis que while démarre le moteur chacun temps (sauf si ce cas est optimisé?). Je ne suggère pas de changer cela, juste une note à considérer à l'avenir.