![]() |
In a numerical spiral such as below the question was given to determine the sum of both diagonals in a 1001 by 1001 spiral.
:
73 74 75 76 77 78 79 80 81I'm curious what algorithm others would have chosen. Mine follows. I noticed a pattern with the diagonal numbers - every 4th iteration add 2 :
2 2 2 2 4 4 4 4 6 6 6 6 8 8 8 8 :
mov ecx, 1 ; first diagonal spiral number |
That is really the only way to tackle this problem that I can think of, and what is even cooler is that you tackled the problem in ASM :P
It looks good though. |
Here's a C version just for you. ;)
:
#include <stdio.h>:
int main():
gcc -o spiral spiral.c -masm=intel |
An intriguing problem, and after about 4 hours and about 5 pages of calculation I think I've finally got another solution for you...
You're itterative approach is awesome and it finds the solution quite nicely, but I couldn't help but wonder if it was possible to derive a simple plug-and-chug formula that can derive the solution in a single pass (something more efficient than the loop approach when working with higher numbers). Here's what I came up with: :
Now, this isn't very useful if you're programming in assembly so applying Horner's Algorithm we get: :
I know this formula looks a little random, but I assure you it works. Try it! :D If you're still skeptical, my explanation... Start by looking back at the problem visually. First, remove all the unnecessary values. :
Now, think of each new row as a new layer with four new corner values. Something like this.. :
Looking at the values in each new layer a usable pattern forms: :
value 4 (top right) = n^2 Note that the first layer, with only one value, is excluded from here on because it has only one value and so doesn't apply (we'll add it back on later). Using these rules and a little algebra we can find the total value of any layer with: :
The total sum of the whole figure (minus one) then is the series summation from r = 3 to the width of the widest layer (that is, the whole figure). Don't forget though that only odd numbers apply to this problem, this series should skip over even values of r. To compensate for this I converted the formula to work off layer number rather than layer size and converted it back when I was done. From there things get even more complicated, with some fancy sigma manipulation and sum identities, but trust me, it works. The finished result is the formula you get at the top. If anyone really want to see the whole thing worked out, let me know and I'll post it, but for now this'll do.. B) P.S. I've been fiddling with this all afternoon and my eyes have glazed over some time ago. So, I wouldn't be supprised if my writing is a little scattered or full of typos. Feel free to point those out to me. ^_^ |
Wow. A programmer that isn't a lazy bugger. Nice work, mate.
|
Well done! Very impressive analytical skills. It works and is very fast. My math background is weak but I'll be looking forward to future math lessons. :)
|
Heh. It was pretty impressive. If anyone has to work out the value of steps (don't ask), I have a maths paper I wrote at the beginning of the year you can have.
|
Hello,
I am trying to compile a program with inline assembler like yours, but failing. When I try to compile your code I get the messages: perkinel-e586cd:~/cfiles/HIS> gcc -o spiral spiral.c -masm=intel spiral.c:15:6: missing terminating " character spiral.c: In function `myasm': spiral.c:16: error: parse error before "mov" spiral.c:31:2: missing terminating " character perkinel-e586cd:~/cfiles Where line 15 is asm(" 16 is mov ecx, 1 32 is "); I take it you are using linux? what version of gcc have you got. Linda |
Linda,
I compiled the code on Win98 using MingW version 3.2 and sadly the only machine I have any flavor of unix on is in pieces atm. I'm not certain if there is a way to write code using intel syntax on Linux. I'm sure Big_K or some of the others who use unix exclusively may know. I dislike at&t syntax and usually code either inline in C with MingW or straight assembler using MASM and recently FASM on Win98 or XP. So I suppose your quick solution is to simply convert the code to at&t syntax. http://linuxassembly.org/articles/linasm.html#Syntax |
Thanks, you may be right.
Linda |
| All times are GMT -5. The time now is 5:38 PM. |
Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC