One pass, a buffer the size of the difference.
use strict; use warnings; use diagnostics; use Data::Dumper; my @buffer = qw[x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 y0 y1 y2 y3 y4 y5 y6]; my $bufsize = 10; my $diff = 2 * $bufsize - scalar(@buffer); my @smallbuf; for my $i (0..$#buffer) { if ($i < $bufsize - $diff) { swap($i, $i + $bufsize) } elsif ($i < $bufsize) { push @smallbuf, $buffer[$i]; mv($i+$diff, $i) } elsif ($i <= $#buffer - $diff) { mv($i+$diff, $i) } else { $buffer[$i] = shift @smallbuf; } } print Dumper @buffer; sub swap { my ($i, $j) = @_; $buffer[$i] = $buffer[$i] ^ $buffer[$j]; $buffer[$j] = $buffer[$i] ^ $buffer[$j]; $buffer[$i] = $buffer[$i] ^ $buffer[$j]; } sub mv { my ($from, $to) = @_; $buffer[$to] = $buffer[$from]; }
Assumptions: (1) you know the size of the buffer. (2) The "larger half" always comes first.
You may want to rewrite the swap algorithm, but it doesn't use a buffer, even of one character.
By the time I'd written this, you said you thought you had an answer, but I understand this one & don't know the language of graff's, so I'm posting it anyway.
Regards,
John Davies
Update: the more I look at this, the more sure I am that my if block can be rewritten to calculate the final position of a value from its original position. This means that with a two value buffer in memory, it should be possible to avoid swapping altogether, reducing the number of writes (possibly important for solid state devices). IOW, var1 (using Data::Dumper notation) goes to var8, so read var8 & write var1 there. Var8 goes to var15, so read var15 & write var8 to it and so on through the chain. The question is where to resume when you get to the end of the chain. Once I have sorted this out, I'll post back (or announce failure).
In reply to Re: [OT] Swapping buffers in place.
by davies
in thread [OT] Swapping buffers in place.
by BrowserUk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |