Apache POI rate formula not working if data is big - function

Rate Formula is not working as expected for big values...
RATE(85.77534246575343, -1589.0, -18664.0, 5855586.0) in physical file it returns 0.05819488005
if the same formula we tried to set through POI returns 0.009056339275922086..
Even we tried to save the excel and open same 0.009056339275922086 is returned..
Code used to set in POI :
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFRow row = sheet.createRow(1);
XSSFCell cell = row.createCell(1);
cell.setCellType(CellType.NUMERIC);
cell.setCellFormula("RATE(85.77534246575343, -1589.0, -18664.0, 5855586.0)");
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
evaluator.evaluateInCell(cell);
cell.getNumericCellValue();

The Rate function of apache poi states that it "// find root by Newton secant method". That's nonsense since Secant method is only a Quasi-Newton method. And "If the initial values are not close enough to the root, then there is no guarantee that the secant method converges.".
So the default guess of 0.1 seems not "close enough" and so if we are using cell.setCellFormula("RATE(85.77534246575343, -1589.0, -18664.0, 5855586.0, 0, 0.06)"); - note the explicit setting of type and guess properties and having the guess property "close enough" to the result of 0.05819488005- then the formula evaluates properly.
If apache poi really would use Newton's method, then the function would evaluate properly also using the default guess of 0.1. The disadvantage of Newton's method is that it requires the evaluation of both f and its derivative f′ at every step. So it may be slower than the Secant method in some cases.
Example:
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
public class ExcelRATEFunction {
private static double calculateRateNewton(double nper, double pmt, double pv, double fv, double type, double guess) {
int FINANCIAL_MAX_ITERATIONS = 20;
double FINANCIAL_PRECISION = 0.0000001;
double y, y1, xN = 0, f = 0, i = 0;
double rate = guess;
//find root by Newtons method (https://en.wikipedia.org/wiki/Newton%27s_method), not secant method!
//Formula see: https://wiki.openoffice.org/wiki/Documentation/How_Tos/Calc:_Derivation_of_Financial_Formulas#PV.2C_FV.2C_PMT.2C_NPER.2C_RATE
f = Math.pow(1 + rate, nper);
y = pv * f + pmt * ((f - 1) / rate) * (1 + rate * type) + fv;
//first derivative:
//y1 = (pmt * nper * type * Math.pow(rate,2) * f - pmt * f - pmt * rate * f + pmt * nper * rate * f + pmt * rate + pmt + nper * pv * Math.pow(rate,2) * f) / (Math.pow(rate,2) * (rate+1));
y1 = (f * ((pmt * nper * type + nper * pv) * Math.pow(rate,2) + (pmt * nper - pmt) * rate - pmt) + pmt * rate + pmt) / (Math.pow(rate,3) + Math.pow(rate,2));
xN = rate - y/y1;
while ((Math.abs(rate - xN) > FINANCIAL_PRECISION) && (i < FINANCIAL_MAX_ITERATIONS)) {
rate = xN;
f = Math.pow(1 + rate, nper);
y = pv * f + pmt * ((f - 1) / rate) * (1 + rate * type) + fv;
//first derivative:
//y1 = (pmt * nper * type * Math.pow(rate,2) * f - pmt * f - pmt * rate * f + pmt * nper * rate * f + pmt * rate + pmt + nper * pv * Math.pow(rate,2) * f) / (Math.pow(rate,2) * (rate+1));
y1 = (f * ((pmt * nper * type + nper * pv) * Math.pow(rate,2) + (pmt * nper - pmt) * rate - pmt) + pmt * rate + pmt) / (Math.pow(rate,3) + Math.pow(rate,2));
xN = rate - y/y1;
++i;
System.out.println(rate+", "+xN+", "+y+", "+y1);
}
rate = xN;
return rate;
}
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
Row row = sheet.createRow(1);
Cell cell = row.createCell(1);
cell.setCellFormula("RATE(85.77534246575343, -1589.0, -18664.0, 5855586.0, 0, 0.06)");
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
CellType celltype = evaluator.evaluateFormulaCellEnum(cell);
double value = 0.0;
if (celltype == CellType.NUMERIC) {
value = cell.getNumericCellValue();
System.out.println(value);
}
workbook.setForceFormulaRecalculation(true);
value = calculateRateNewton(85.77534246575343, -1589.0, -18664.0, 5855586.0, 0, 0.1);
System.out.println(value);
workbook.write(new FileOutputStream("ExcelRATEFunction.xlsx"));
workbook.close();
}
}

Related

Octave goes in Waiting... when solve() function is used

I've installed and loaded the symbolic package that becomes available from optim package to obtain the syms function (like in MATLAB) but when I use solve() function the command window goes in Waiting mode like
Waiting..........
My code is given below:
syms s T K D1 D2 D3 theta1 theta2 theta3 J1 J2 J3
eq1 = (s * D1 + K + J1 * s ^ 2)* theta1 - K * theta2 == T;
eq2 = -K * theta1 + (J2 * s ^ 2 + K + D2 * s) * theta2 - D2 * s * theta3 == 0;
eq3 = -D2 * s * theta2 + (D3 * s + J3 * s ^ 2 + D2 * s) * theta3 == 0;
S = solve(eq1, eq2, eq3)
but if I manually solve it by inverse method, it gives the answer instantly. Kindly help to solve this bug.

CUDA kernel fails to launch after making simple code changes inside the kernel

I have a templated CUDA kernel for calculating and setting values at the interface between 2 computational meshes. The values are calculated using 3 separate contributions, obtained from class member functions with class instances passed to the kernel. If I obtain any one of these contributions alone to set in the output the kernel works. As soon as I add 2 (or all) of these contributions to set in the output the kernel simply does not launch at all.
I've inserted the full kernel code at the end, but I'll try to exemplify the above first.
First define the first 2 contributions:
//contribution 1
VType value1 = (V_m2 * 2 * b_val_sec / 3 + V_2 * (b_val_pri + b_val_sec / 3)) / (b_val_sec + b_val_pri);
//contribution 2
VType value2 = (Vdiff2_sec * b_val_sec * hL * hL - Vdiff2_pri * b_val_pri * hR * hR) / (b_val_sec + b_val_pri);
Now set output:
Case 1 - kernel launches and sets expected values:
V_pri[cell1_idx] = value1;
Case 2 - kernel launches and sets expected values:
V_pri[cell1_idx] = value2;
Case 3 - kernel does not launch:
V_pri[cell1_idx] = value1 + value2;
I am completely stumped as this seems to defy logic and would really like to understand what is happening. Has anyone encountered anything similar, or any idea what could be causing this?
I'm using CUDA 9.2 with Visual Studio 2017 and I've tested the code on GTX 980 Ti (compute 5.2) and GTX 1060 (compute 6.1) with identical results.
Here is the full kernel code:
template <typename VType, typename Class_CMBND>
__global__ void set_cmbnd_values_kernel(
cuVEC_VC<VType>& V_sec, cuVEC_VC<VType>& V_pri,
Class_CMBND& cmbndFuncs_sec, Class_CMBND& cmbndFuncs_pri,
CMBNDInfoCUDA& contact)
{
int box_idx = blockIdx.x * blockDim.x + threadIdx.x;
cuINT3 box_sizes = contact.cells_box.size();
if (box_idx < box_sizes.dim()) {
int i = (box_idx % box_sizes.x) + contact.cells_box.s.i;
int j = ((box_idx / box_sizes.x) % box_sizes.y) + contact.cells_box.s.j;
int k = (box_idx / (box_sizes.x * box_sizes.y)) + contact.cells_box.s.k;
cuReal hL = contact.hshift_secondary.norm();
cuReal hR = contact.hshift_primary.norm();
cuReal hmax = (hL > hR ? hL : hR);
int cell1_idx = i + j * V_pri.n.x + k * V_pri.n.x*V_pri.n.y;
if (V_pri.is_empty(cell1_idx) || V_pri.is_not_cmbnd(cell1_idx)) return;
int cell2_idx = (i + contact.cell_shift.i) + (j + contact.cell_shift.j) * V_pri.n.x + (k + contact.cell_shift.k) * V_pri.n.x*V_pri.n.y;
cuReal3 relpos_m1 = V_pri.rect.s - V_sec.rect.s + ((cuReal3(i, j, k) + cuReal3(0.5)) & V_pri.h) + (contact.hshift_primary + contact.hshift_secondary) / 2;
cuReal3 stencil = V_pri.h - cu_mod(contact.hshift_primary) + cu_mod(contact.hshift_secondary);
VType V_2 = V_pri[cell2_idx];
VType V_m2 = V_sec.weighted_average(relpos_m1 + contact.hshift_secondary, stencil);
//a values
VType a_val_sec = cmbndFuncs_sec.a_func_sec(relpos_m1, contact.hshift_secondary, stencil);
VType a_val_pri = cmbndFuncs_pri.a_func_pri(cell1_idx, cell2_idx, contact.hshift_secondary);
//b values adjusted with weights
cuReal b_val_sec = cmbndFuncs_sec.b_func_sec(relpos_m1, contact.hshift_secondary, stencil) * contact.weights.i;
cuReal b_val_pri = cmbndFuncs_pri.b_func_pri(cell1_idx, cell2_idx) * contact.weights.j;
//V'' values at cell positions -1 and 1
VType Vdiff2_sec = cmbndFuncs_sec.diff2_sec(relpos_m1, stencil);
VType Vdiff2_pri = cmbndFuncs_pri.diff2_pri(cell1_idx);
//Formula for V1
V_pri[cell1_idx] = (V_m2 * 2 * b_val_sec / 3 + V_2 * (b_val_pri + b_val_sec / 3)
- Vdiff2_sec * b_val_sec * hL * hL - Vdiff2_pri * b_val_pri * hR * hR
+ (a_val_pri - a_val_sec) * hmax) / (b_val_sec + b_val_pri);
}
}
It's almost as if kernels with too many lines of code in them (in the above kernel there's additional code in the various functions used) fail to launch under certain conditions.
Right, seems I found the answer to my problem.
Looking at the generated errors I get "Too many resources requested for launch".
I've reduced the number of threads per block from 512 to 256 and the kernel runs fine now.

Canvas quadraticCurve center point

I want need to know how detect center coordinates of quadraticCurve in HTML5 canvas. I want to draw arrow in this center point of curve.
There is my draw curve method:
function draw_curve(Ax, Ay, Bx, By, M, context) {
var dx = Bx - Ax,
dy = By - Ay,
dr = Math.sqrt(dx * dx + dy * dy);
// side is either 1 or -1 depending on which side you want the curve to be on.
// Find midpoint J
var Jx = Ax + (Bx - Ax) / 2
var Jy = Ay + (By - Ay) / 2
// We need a and b to find theta, and we need to know the sign of each to make sure that the orientation is correct.
var a = Bx - Ax
var asign = (a < 0 ? -1 : 1)
var b = By - Ay
var bsign = (b < 0 ? -1 : 1)
var theta = Math.atan(b / a)
// Find the point that's perpendicular to J on side
var costheta = asign * Math.cos(theta)
var sintheta = asign * Math.sin(theta)
// Find c and d
var c = M * sintheta
var d = M * costheta
// Use c and d to find Kx and Ky
var Kx = Jx - c
var Ky = Jy + d
// context.bezierCurveTo(Kx, Ky,Bx,By, Ax, Ax);
context.quadraticCurveTo(Kx, Ky, Bx, By);
// draw the ending arrowhead
var endRadians = Math.atan((dx) / (dy));
context.stroke();
var t = 0.5; // given example value
var xx = (1 - t) * (1 - t) * Ax + 2 * (1 - t) * t * Kx + t * t * Bx;
var yy = (1 - t) * (1 - t) * Ay + 2 * (1 - t) * t * Ky + t * t * By;
var k = {};
k.x = xx;
k.y = yy;
SOLVED BY THIS CODE, T is parameter which set position on the curve:
var t = 0.5; // given example value
var xx = (1 - t) * (1 - t) * Ax + 2 * (1 - t) * t * Kx + t * t * Bx;
var yy = (1 - t) * (1 - t) * Ay + 2 * (1 - t) * t * Ky + t * t * By;
var k = {};
k.x = xx;
k.y = yy;

Actionscript: Pseudo-Random Number creation with seeds

I am creating a function that returns a Perlin Noise Number in Flash.
For this function I must have a function that returns a random number from a static seed. Unfortunately the default Math.random in Actionscript can't do this..
I searched for a long time on the internet and I couldn't find a solution that fits my perlin-noise function.
I tried the following codes:
public static var seed:int = 602366;
public static function intNoise(x:int, y:int):Number {
var n:Number = seed * 16127 + (x + y * 57);
n = n % 602366;
seed = n | 0;
if (seed <= 0) seed = 1;
return (seed * 0.00000166) * 2 - 1;
}
This function does create a Random number, but the seed changes all the time so this doesn't work with perlin noise.
public static function intNoise(x:int, y:int):Number {
var n:Number = x + y * 57;
n = (n<<13) ^ n;
return ( 1 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
I got this function from the Perlin Noise tutorial I followed: Perlin Noise, but it only seems to return 1.
How can I create a function that always returns the same Pseudo-Random number when called with the same seed?
I looked at the random number generator mentioned in the link and it looks like this:
function IntNoise(32-bit integer: x)
x = (x<<13) ^ x;
return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end IntNoise function
I translated it thus:
package
{
import flash.display.*;
public class Main extends Sprite {
private var seeds:Array =
[ -1000, -999, -998, 7, 11, 13, 17, 999, 1000, 1001 ];
public function Main() {
for ( var i:int = 0; i < 10; i++ )
trace( intNoise( seeds[ i ] ) );
// Outputs: 1, 0, 0, -0.595146656036377, -0.1810436248779297,
// 0.8304634094238281, -0.9540863037109375, 0, 0, 1
}
// returns floating point numbers between -1.0 and 1.0
// returns 1 when x <= -1000 || x >= 1001 because b becomes 0
// otherwise performs nicely
public function
intNoise( x:Number ):Number {
x = ( uint( x << 13 ) ) ^ x;
var a:Number = ( x * x * x * 15731 + x * 789221 );
var b:Number = a & 0x7fffffff;
return 1.0 - b / 1073741824.0;
}
}
}

Code Golf: Easter Spiral

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
What's more appropriate than a Spiral for Easter Code Golf sessions? Well, I guess almost anything.
The Challenge
The shortest code by character count to display a nice ASCII Spiral made of asterisks ('*').
Input is a single number, R, that will be the x-size of the Spiral. The other dimension (y) is always R-2. The program can assume R to be always odd and >= 5.
Some examples:
Input
7
Output
*******
* *
* *** *
* * *
***** *
Input
9
Output
*********
* *
* ***** *
* * * *
* *** * *
* * *
******* *
Input
11
Output
***********
* *
* ******* *
* * * *
* * *** * *
* * * * *
* ***** * *
* * *
********* *
Code count includes input/output (i.e., full program).
Any language is permitted.
My easily beatable 303 chars long Python example:
import sys;
d=int(sys.argv[1]);
a=[d*[' '] for i in range(d-2)];
r=[0,-1,0,1];
x=d-1;y=x-2;z=0;pz=d-2;v=2;
while d>2:
while v>0:
while pz>0:
a[y][x]='*';
pz-=1;
if pz>0:
x+=r[z];
y+=r[(z+1)%4];
z=(z+1)%4; pz=d; v-=1;
v=2;d-=2;pz=d;
for w in a:
print ''.join(w);
Now, enter the Spiral...
Python (2.6): 156 chars
r=input()
def p(r,s):x=(i+1)/2;print "* "*x+("*" if~i%2 else" ")*(r-4*x)+" *"*x+s
for i in range(r/2):p(r,"")
for i in range((r-1)/2-1)[::-1]:p(r-2," *")
Thanks for the comments. I've removed extraneous whitespace and used input(). I still prefer a program that takes its argument on the command-line, so here's a version still using sys.argv at 176 chars:
import sys
r=int(sys.argv[1])
def p(r,s):x=(i+1)/2;print "* "*x+("*" if~i%2 else" ")*(r-4*x)+" *"*x+s
for i in range(r/2):p(r,"")
for i in range((r-1)/2-1)[::-1]:p(r-2," *")
Explanation
Take the spiral and chop it in two almost-equal parts, top and bottom, with the top one row bigger than the bottom:
***********
* *
* ******* *
* * * *
* * *** * *
* * * * *
* ***** * *
* * *
********* *
Observe how the top part is nice and symmetrical. Observe how the bottom part has a vertical line down the right side, but is otherwise much like the top. Note the pattern in every second row at the top: an increasing number of stars on each side. Note that each intervening row is exactly the saw as the one before except it fills in the middle area with stars.
The function p(r,s) prints out the ith line of the top part of the spiral of width r and sticks the suffix s on the end. Note that i is a global variable, even though it might not be obvious! When i is even it fills the middle of the row with spaces, otherwise with stars. (The ~i%2 was a nasty way to get the effect of i%2==0, but is actually not necessary at all because I should have simply swapped the "*" and the " ".) We first draw the top rows of the spiral with increasing i, then we draw the bottom rows with decreasing i. We lower r by 2 and suffix " *" to get the column of stars on the right.
Java
328 characters
class S{
public static void main(String[]a){
int n=Integer.parseInt(a[0]),i=n*(n-2)/2-1,j=0,t=2,k;
char[]c=new char[n*n];
java.util.Arrays.fill(c,' ');
int[]d={1,n,-1,-n};
if(n/2%2==0){j=2;i+=1+n;}
c[i]='*';
while(t<n){
for(k=0;k<t;k++)c[i+=d[j]]='*';
j=(j+1)%4;
if(j%2==0)t+=2;
}
for(i=0;i<n-2;i++)System.out.println(new String(c,i*n,n));
}
}
As little as 1/6 more than Python seems not too bad ;)
Here's the same with proper indentation:
class S {
public static void main(String[] a) {
int n = Integer.parseInt(a[0]), i = n * (n - 2) / 2 - 1, j = 0, t = 2, k;
char[] c = new char[n * n];
java.util.Arrays.fill(c, ' ');
int[] d = { 1, n, -1, -n };
if (n / 2 % 2 == 0) {
j = 2;
i += 1 + n;
}
c[i] = '*';
while (t < n) {
for (k = 0; k < t; k++)
c[i += d[j]] = '*';
j = (j + 1) % 4;
if (j % 2 == 0)
t += 2;
}
for (i = 0; i < n - 2; i++)
System.out.println(new String(c, i * n, n));
}
}
F#, 267 chars
A lot of answers are starting with blanks and adding *s, but I think it may be easier to start with a starfield and add whitespace.
let n=int(System.Console.ReadLine())-2
let mutable x,y,d,A=n,n,[|1;0;-1;0|],
Array.init(n)(fun _->System.Text.StringBuilder(String.replicate(n+2)"*"))
for i=1 to n do for j=1 to(n-i+1)-i%2 do x<-x+d.[i%4];y<-y+d.[(i+1)%4];A.[y].[x]<-' '
Seq.iter(printfn"%O")A
For those looking for insight into how I golf, I happened to save a lot of progress along the way, which I present here with commentary. Not every program is quite right, but they're all honing in on a shorter solution.
First off, I looked for a pattern of how to paint the white:
*********
* *
* ***** *
* * * *
* *** * *
* * *
******* *
*********
*6543216*
*1*****5*
*2*212*4*
*3***1*3*
*41234*2*
*******1*
***********
* *
* ******* *
* * * *
* * *** * *
* * * * *
* ***** * *
* * *
********* *
***********
*876543218*
*1*******7*
*2*43214*6*
*3*1***3*5*
*4*212*2*4*
*5*****1*3*
*6123456*2*
*********1*
Ok, I see it. First program:
let Main() =
let n=int(System.Console.ReadLine())
let A=Array2D.create(n-2)n '*'
let mutable x,y,z,i=n-2,n-2,0,n-2
let d=[|0,-1;-1,0;0,1;1,0|] // TODO
while i>0 do
for j in 1..i-(if i%2=1 then 1 else 0)do
x<-x+fst d.[z]
y<-y+snd d.[z]
A.[y,x]<-'0'+char j
z<-(z+1)%4
i<-i-1
printfn"%A"A
Main()
I know that d, the tuple-array of (x,y)-diffs-modulo-4 can later be reduced by x and y both indexing into different portions of the same int-array, hence the TODO. The rest is straightforward based on the visual insight into 'whitespace painting'. I'm printing a 2D array, which is not right, need an array of strings, so:
let n=int(System.Console.ReadLine())
let s=String.replicate n "*"
let A=Array.init(n-2)(fun _->System.Text.StringBuilder(s))
let mutable x,y,z,i=n-2,n-2,0,n-2
let d=[|0,-1;-1,0;0,1;1,0|]
while i>0 do
for j in 1..i-(if i%2=1 then 1 else 0)do
x<-x+fst d.[z]
y<-y+snd d.[z]
A.[y].[x]<-' '
z<-(z+1)%4
i<-i-1
for i in 0..n-3 do
printfn"%O"A.[i]
Ok, now let's change the array of tuples into an array of int:
let n=int(System.Console.ReadLine())-2
let mutable x,y,z,i,d=n,n,0,n,[|0;-1;0;1;0|]
let A=Array.init(n)(fun _->System.Text.StringBuilder(String.replicate(n+2)"*"))
while i>0 do
for j in 1..i-i%2 do x<-x+d.[z];y<-y+d.[z+1];A.[y].[x]<-' '
z<-(z+1)%4;i<-i-1
A|>Seq.iter(printfn"%O")
The let for A can be part of the previous line. And z and i are mostly redundant, I can compute one in terms of the other.
let n=int(System.Console.ReadLine())-2
let mutable x,y,d,A=n,n,[|0;-1;0;1|],
Array.init(n)(fun _->System.Text.StringBuilder(String.replicate(n+2)"*"))
for i=n downto 1 do for j in 1..i-i%2 do x<-x+d.[(n-i)%4];y<-y+d.[(n-i+1)%4];A.[y].[x]<-' '
Seq.iter(printfn"%O")A
downto is long, re-do the math so I can go (up) to in the loop.
let n=int(System.Console.ReadLine())-2
let mutable x,y,d,A=n,n,[|1;0;-1;0|],
Array.init(n)(fun _->System.Text.StringBuilder(String.replicate(n+2)"*"))
for i=1 to n do for j in 1..(n-i+1)-i%2 do x<-x+d.[i%4];y<-y+d.[(i+1)%4];A.[y].[x]<-' '
Seq.iter(printfn"%O")A
A little more tightening yields the final solution.
Python : 238 - 221 - 209 characters
All comments welcome:
d=input();r=range
a=[[' ']*d for i in r(d-2)]
x=y=d/4*2
s=d%4-2
for e in r(3,d+1,2):
for j in r(y,y+s*e-s,s):a[x][j]='*';y+=s
for j in r(x,x+s*e-(e==d)-s,s):a[j][y]='*';x+=s
s=-s
for l in a:print''.join(l)
Groovy, 373 295 257 243 chars
Tried a recursive approach that builds up squares starting from the most extern one going inside.. I used Groovy.
*********
*********
*********
*********
*********
*********
******* *
*********
* *
* *
* *
* *
* * *
******* *
*********
* *
* ***** *
* ***** *
* *** * *
* * *
******* *
*********
* *
* ***** *
* * * *
* *** * *
* * *
******* *
and so on..
r=args[0] as int;o=r+1;c='*'
t=new StringBuffer('\n'*(r*r-r-2))
e(r,0)
def y(){c=c==' '?'*':' '}
def e(s,p){if (s==3)t[o*p+p..o*p+p+2]=c*s else{l=o*(p+s-3)+p+s-2;(p+0..<p+s-2).each{t[o*it+p..<o*it+p+s]=c*s};y();t[l..l]=c;e(s-2,p+1)}}
println t
readable one:
r=args[0] as int;o=r+1;c='*'
t=new StringBuffer('\n'*(r*r-r-2))
e(r,0)
def y(){c=c==' '?'*':' '}
def e(s,p){
if (s==3)
t[o*p+p..o*p+p+2]=c*s
else{
l=o*(p+s-3)+p+s-2
(p+0..<p+s-2).each{
t[o*it+p..<o*it+p+s]=c*s}
y()
t[l..l]=c
e(s-2,p+1)
}
}
println t
EDIT: improved by just filling squares and then overriding them (check new example): so I avoided to fill just the edge of the rect but the whole one.
Ruby, 237 chars
I'm new to code golf, so I'm way off the mark, but I figured I'd give it a shot.
x=ARGV[0].to_i
y=x-2
s,h,j,g=' ',x-1,y-1,Array.new(y){Array.new(x,'*')}
(1..x/2+2).step(2){|d|(d..y-d).each{|i|g[i][h-d]=s}
(d..h-d).each{|i|g[d][i]=s}
(d..j-d).each{|i|g[i][d]=s}
(d..h-d-2).each{|i|g[j-d][i]=s}}
g.each{|r|print r;puts}
Long version
Java, 265 250 245 240 chars
Rather than preallocating a rectangular buffer and filling it in, I just loop over x/y coordinates and output '*' or ' ' for the current position. For this, we need an algorithm which can evaluate arbitrary points for whether they're on the spiral. The algorithm I used is based on the observation that the spiral is equivalent to a collection of concentric squares, with the exception of a set of positions which all happen along a particular diagonal; these positions require a correction (they must be inverted).
The somewhat readable version:
public class Spr2 {
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int cy = (n - 5) / 4 * 2 + 1;
int cx = cy + 2;
for (int y = n - 3; y >= 0; y--) {
for (int x = 0; x < n; x++) {
int dx = cx - x;
int dy = cy - y;
int adx = Math.abs(dx);
int ady = Math.abs(dy);
boolean c = (dx > 0 && dx == dy + 1);
boolean b = ((adx % 2 == 1 && ady <= adx) || (ady % 2 == 1 && adx <= ady)) ^ c;
System.out.print(b ? '*' : ' ');
}
System.out.println();
}
}
}
A brief explanation for the above:
cx,cy = center
dx,dy = delta from center
adx,ady = abs(delta from center)
c = correction factor (whether to invert)
b = the evaluation
Optimized down. 265 chars:
public class S{
public static void main(String[]a){
int n=Integer.parseInt(a[0]),c=(n-5)/4*2+1,d=c+2,e,f,g,h,x,y;
for(y=0;y<n-2;y++){
for(x=0;x<=n;x++){
e=d-x;f=c-y;g=e>0?e:-e;h=f>0?f:-f;
System.out.print(x==n?'\n':(g%2==1&&h<=g||h%2==1&&g<=h)^(e>0&&e==f+1)?'*':' ');
}}}}
Updated. Now down to 250 chars:
class S{
public static void main(String[]a){
int n=Integer.parseInt(a[0]),c=(n-5)/4*2+1,d=c+2,g,h,x,y;
for(y=-c;y<n-2-c;y++){
for(x=-d;x<=n-d;x++){
g=x>0?x:-x;h=y>0?y:-y;
System.out.print(x==n-d?'\n':(g%2==1&&h<=g||h%2==1&&g<=h)^(x<0&&x==y-1)?'*':' ');
}}}}
Shaved just a few more characters. 245 chars:
class S{
public static void main(String[]a){
int n=Integer.parseInt(a[0]),c=(n-5)/4*2+1,d=c+2,g,h,x,y=-c;
for(;y<n-2-c;y++){
for(x=-d;x<=n-d;x++){
g=x>0?x:-x;h=y>0?y:-y;
System.out.print(x==n-d?'\n':(g%2==1&h<=g|h%2==1&g<=h)^(x<0&x==y-1)?'*':' ');
}}}}
Shaved just a few more characters. 240 chars:
class S{
public static void main(String[]a){
int n=Byte.decode(a[0]),c=(n-5)/4*2+1,d=c+2,g,h,x,y=-c;
for(;y<n-2-c;y++){
for(x=-d;x<=n-d;x++){
g=x>0?x:-x;h=y>0?y:-y;
System.out.print(x==n-d?'\n':(g%2==1&h<=g|h%2==1&g<=h)^(x<0&x==y-1)?'*':' ');
}}}}
OCaml, 299 chars
Here is a solution in OCaml, not the shortest but I believe quite readable.
It only uses string manipulations using the fact the you can build a spiral by mirroring the previous one.
Let's say you start at with n = 5:
55555
5 5
555 5
Now with n = 7:
7777777
7 7
5 555 7
5 5 7
55555 7
Did you see where all the 5's went ?
Here is the unobfuscated code using only the limited library provided with OCaml:
(* The standard library lacks a function to reverse a string *)
let rev s =
let n = String.length s - 1 in
let r = String.create (n + 1) in
for i = 0 to n do
r.[i] <- s.[n - i]
done;
r
;;
let rec f n =
if n = 5 then
[
"*****";
"* *";
"*** *"
]
else
[
String.make n '*';
"*" ^ (String.make (n - 2) ' ') ^ "*"
] # (
List.rev_map (fun s -> (rev s) ^ " *") (f (n - 2))
)
;;
let p n =
List.iter print_endline (f n)
;;
let () = p (read_int ());;
Here is the obfuscated version which is 299 characters long:
open String
let rev s=
let n=length s-1 in
let r=create(n+1)in
for i=0 to n do r.[i]<-s.[n-i]done;r
let rec f n=
if n=5 then["*****";"* *";"*** *"]else
[make n '*';"*"^(make (n-2) ' ')^"*"]
#(List.rev_map(fun s->(rev s)^" *")(f(n-2)));;
List.iter print_endline (f(read_int ()))
C#, 292 262 255 chars
Simple approach: draw the spiral line by line from the outside in.
using C=System.Console;class P{static void Main(string[]a){int A=
1,d=1,X=int.Parse(a[0]),Y=X-2,l=X,t=0,i,z;while(l>2){d*=A=-A;l=l<
4?4:l;for(i=1;i<(A<0?l-2:l);i++){C.SetCursorPosition(X,Y);C.Write
("*");z=A<0?Y+=d:X+=d;}if(t++>1||l<5){l-=2;t=1;}}C.Read();}}
Ruby (1.9.2) — 126
f=->s{s<0?[]:(z=?**s;[" "*s]+(s<2?[]:[z]+f[s-4]<<?*.rjust(s))).map{|i|"* #{i} *"}<<z+"** *"}
s=gets.to_i;puts [?**s]+f[s-4]
Perl, where are you? )