Quine multiple times
CJam, 28 26 bytes * 0.9 = 23.4
Thanks to Sp3000 for saving 2 bytes.
{`"_~"+rd_z26*,\g1|@%f=}_~
Test it here.
Explanation
{`"_~"+ e# Generalised quine framework. Leaves the source code on the stack.
rd e# Read input and parse as double.
_z e# Copy and get absolute value.
26* e# Multiply by 26, the length of the quine to get length N of the output.
, e# Get a range [0 1 ... floor(N-1)].
\g e# Swap with other copy and computer signum to determine direction of string.
1| e# This might be zero though, so take bitwise OR with 1 to avoid an error.
@% e# Pull up source string. Reverse it if the signum was -1 (no-op otherwise).
f= e# The range we pushed earlier corresponds to the (cyclic) indices of the source
e# which make up the desired result, so we map each index to the corresponding
e# character to get the final result.
}_~
Vitsy, 34 * 0.9 = 30.6 Bytes
Thanks to @Sp3000 for pointing out a flaw in my code!
Woo. My Physics teacher reminded me I had power functions to help me with this. Go figure.
'r(;Vd3*V2^12/^DvV/1+(rvl1-*\[DO{] ' Start recording as a string - this grabs everything and pushes it to the stack as a string. r Reverse the stack order. (; If the top item is zero, exit the program. V Grab the input as a final global variable. d3* Push the character ' to the stack. V2^12/^ Get the absolute value of the input value. Dv Duplicate and save in a temp variable. V Push the global variable to the stack. / Divide the top two items - this gets -1 or 1 depending on the polarity of the input. 1+( If it's -1, do the next instruction. Otherwise, don't. r Reverse the stack v Push the temporary variable to the stack. l1-* Multiply by the length of the stack minus 1. \[ ] Repeat everything in brackets top item of the stack times. DO{ Duplicate an item, pop it off the stack and output it, then move one item over in the stack.
Perl, 104 bytes - 10% = 93.6
perl -i-0.3 -e '$_=q{$_="\$_=q{$_};eval";$_=reverse if$^I<0;$n=abs$^I;print+($_ x$n).substr$_,0,y///c*($n-int$n)};eval'
102 bytes + 2 bytes for -i
- 10% for not being a palindrome. Input is passed as the argument to -i
(e.g. -0.3
above).
How it works
This solution is based on the following quine:
$_=q{print"\$_=q{$_};eval"};eval
This works as follows. First, set $_
to the string:
print"\$_=q{$_};eval"
Next, call eval
, which works on $_
by default. This calls print
with one argument, a string literal:
"\$_=q{$_};eval"
Since this string is double-quoted, variables are interpolated. After interpolating $_
, the value of the string is:
\$_=q{print"\$_=q{$_};eval"};eval
When printed, this outputs:
$_=q{print"\$_=q{$_};eval"};eval
which is the source code of the program itself.
The nice thing about this quine is that you can embed arbitrary code inside the string to be eval
'd.
Here's a breakdown of the full solution:
perl -i-0.3 -e'
$_=q{ # string to be eval'd
$_="\$_=q{$_};eval"; # append beginning and end of quine so the
# entire thing can be reversed if necessary
$_=reverse if $^I<0; # reverse if input < 0
$n=abs $^I; # set $n to absolute value of input
print # print
+($_ x $n) # $_ repeated $n times
. # concatenated with
substr $_, # substring of $_
0, # starting at the beginning
y///c # having length x, where x is length of $_
* # multiplied by
($n-int$n) # fractional part of $n
};
eval # eval $_
'