BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

How to generate the number on the bottom row, from the number on the top row?:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 12 13 14 15 8 9 10 11 4 5 6 7 0 1 2 3

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

Replies are listed 'Best First'.
Re: More simple math.
by hdb (Monsignor) on Mar 12, 2015 at 18:00 UTC
    printf "%2d ", $_ for 0..15; printf "\n"; printf "%2d ", $_^12 for 0..15; printf "\n";

      Huh! How on earth did you come up with that?

      Weirdly (or not) it adapts to the variables in my use case.

      Splitting the sequence into 2 parts or 8 parts is a logical extension:

      [0] Perl> print join ' ', map $_^14, 0..15;; 14 15 12 13 10 11 8 9 6 7 4 5 2 3 0 1 [0] Perl> print join ' ', map $_^8, 0..15;; 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7

      And works for longer sequences (provided they are powers of two; which is a distinct possibility for my purpose):

      [0] Perl> print join ' ', map $_^8, 0..31;; 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 24 25 26 27 28 29 30 31 16 17 18 + 19 20 21 22 23 [0] Perl> print join ' ', map $_^16, 0..31;; 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 [0] Perl> print join ' ', map $_^24, 0..31;; 24 25 26 27 28 29 30 31 16 17 18 19 20 21 22 23 8 9 10 11 12 13 14 15 +0 1 2 3 4 5 6 7 [0] Perl> print join ' ', map $_^28, 0..31;; 28 29 30 31 24 25 26 27 20 21 22 23 16 17 18 19 12 13 14 15 8 9 10 11 +4 5 6 7 0 1 2 3 [0] Perl> print join ' ', map $_^30, 0..31;; 30 31 28 29 26 27 24 25 22 23 20 21 18 19 16 17 14 15 12 13 10 11 8 9 +6 7 4 5 2 3 0 1

      Just a shame it produces out-of-bounds values for non-powers-of-two:

      [0] Perl> print join ' ', map $_^10, 0..19;; 10 11 8 9 14 15 12 13 2 3 0 1 6 7 4 5 26 27 24 25

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

        Step 1: this is obviously a problem to be solved in base 4, so translate both rows into base 4.

        Step 2: last digit is the same between rows, first one is reversed

        Step 3: reversing first digit is XOR with 0b1100 which is 12

Re: More simple math.
by choroba (Cardinal) on Mar 12, 2015 at 17:33 UTC
    #!/usr/bin/perl use warnings; use strict; use Test::More; sub f { my $n = shift; $n % 4 + 4 * int((15 - $n) / 4) } my @in = qw( 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15); my @out = qw(12 13 14 15 8 9 10 11 4 5 6 7 0 1 2 3); for my $i (0 .. $#in) { is(f($in[$i]), $out[$i], "_$i"); } done_testing(0 + @in);

    TDD FTW!

    Update: Also notice that f(f($x)) == $x.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Thank you. That adapts:

      sub f { my( $n, $g, $m ) = @_; $n % $g + $g * int(($m - $n) / $g); };;

      to every situation I can think I might need:

      [0] Perl> print join ' ', map f( $_, 8, 15 ), 0 .. 15;; 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 [0] Perl> print join ' ', map f( $_, 4, 15 ), 0 .. 15;; 12 13 14 15 8 9 10 11 4 5 6 7 0 1 2 3 [0] Perl> print join ' ', map f( $_, 2, 15 ), 0 .. 15;; 14 15 12 13 10 11 8 9 6 7 4 5 2 3 0 1 [0] Perl> print join ' ', map f( $_, 1, 15 ), 0 .. 15;; 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 [0] Perl> print join ' ', map f( $_, 12, 23 ), 0 .. 23;; 12 13 14 15 16 17 18 19 20 21 22 23 0 1 2 3 4 5 6 7 8 9 10 11 [0] Perl> print join ' ', map f( $_, 8, 23 ), 0 .. 23;; 16 17 18 19 20 21 22 23 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 [0] Perl> print join ' ', map f( $_, 6, 23 ), 0 .. 23;; 18 19 20 21 22 23 12 13 14 15 16 17 6 7 8 9 10 11 0 1 2 3 4 5 [0] Perl> print join ' ', map f( $_, 4, 23 ), 0 .. 23;; 20 21 22 23 16 17 18 19 12 13 14 15 8 9 10 11 4 5 6 7 0 1 2 3 [0] Perl> print join ' ', map f( $_, 2, 23 ), 0 .. 23;; 22 23 20 21 18 19 16 17 14 15 12 13 10 11 8 9 6 7 4 5 2 3 0 1 [0] Perl> print join ' ', map f( $_, 1, 23 ), 0 .. 23;; 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

      Even the basket cases:

      [0] Perl> print join ' ', map f( $_, 9, 26 ), 0 .. 26;; 18 19 20 21 22 23 24 25 26 9 10 11 12 13 14 15 16 17 0 1 2 3 4 5 6 7 8 [0] Perl> print join ' ', map f( $_, 6, 26 ), 0 .. 26;; 24 25 26 21 22 23 18 19 20 15 16 17 12 13 14 9 10 11 6 7 8 3 4 5 0 1 2 [0] Perl> print join ' ', map f( $_, 3, 26 ), 0 .. 26;; 24 25 26 21 22 23 18 19 20 15 16 17 12 13 14 9 10 11 6 7 8 3 4 5 0 1 2

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
Re: More simple math.
by Anonymous Monk on Mar 12, 2015 at 17:52 UTC

    sub f { 0x32107654ba98fedc >> (4*pop) & 0xf }

      Shame about its limits. (My fault for providing a simplified example!)


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
Re: More simple math.
by trippledubs (Deacon) on Mar 12, 2015 at 18:15 UTC
    YOLO
    print $_,":",$_ ^ 0b1100 ,"\n" for (0..15);