Six cases, four of them with explicit return values (at the edges), two of them recursive:
importText.PrintftypeSize=InttypeRow=InttypeColumn=Int-- top row: count down from sqr - 1 with col-- right column: count down from sqr - n with row-- bottom row: count up from sqr - n with col-- left column: count up from sqr - n - (n - 1) with rowelement::Size->Row->Column->Intelementnrowcol|evenn&&row==0=sqr-1-col|evenn&&col==n-1=sqr-n-row|evenn=element(n-1)(row-1)col|oddn&&row==n-1=sqr-n+col|oddn&&col==0=sqr-n-(n-1)+row|otherwise=element(n-1)row(col-1)wheresqr=n^2printElement::Size->Row->Column->IO()printElementnrowcol=printf("%*v"++end)len(elementnrowcol)wherelen=(length.show)(n^2-1)end=ifcol==n-1then"\n"else" "printSpiraln=sequence_$printElementn<$>[0..n-1]<*>[0..n-1]main=printSpiral10
I didn't expect printing elementwise to be so easy in Haskell. The classical nested for loop for printing 2-dimensional array in one line:
Lifting the printElement function into the list functor, getting a list of IO actions back and sequencing this list. That is more intuitive to read than what I used to do with the 'unwords' and 'unlines' functions in similar cases.
I do functorial lifting every day, but although I knew of the sequence function, I never found a use case. Until this puzzle came along. :-) Using sequence in similar cases is the lesson I learned here. :-)
But wait!
The sequence function takes a list of IO actions, one for each element of the spiral. So there's a list of size n2 in memory! :-)
The logic of the element function is O(1), the printing function is not.
So, at first, I'm doing it in good old C:
Instead of functorial lifting into the list (resulting in O( n2 )) I use the loop function iterateUntilM to iterate the slightly modified printElement function until the spiral is printed: O(1)
In the printElement function, elements are indexed by a counter from 0 to n2 - 1, their position in the spiral can be derived from the index by division modulo n: (row,col) = quotRem counter n.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Six cases, four of them with explicit return values (at the edges), two of them recursive:
I didn't expect printing elementwise to be so easy in Haskell. The classical nested for loop for printing 2-dimensional array in one line:
Lifting the printElement function into the list functor, getting a list of IO actions back and sequencing this list. That is more intuitive to read than what I used to do with the 'unwords' and 'unlines' functions in similar cases.
I do functorial lifting every day, but although I knew of the sequence function, I never found a use case. Until this puzzle came along. :-) Using sequence in similar cases is the lesson I learned here. :-)
But wait!
The sequence function takes a list of IO actions, one for each element of the spiral. So there's a list of size n2 in memory! :-)
The logic of the element function is O(1), the printing function is not.
So, at first, I'm doing it in good old C:
What was most fun to learn for me, here, was a failure regarding the problem. :-D
Instead of functorial lifting into the list (resulting in O( n2 )) I use the loop function iterateUntilM to iterate the slightly modified printElement function until the spiral is printed: O(1)
In the printElement function, elements are indexed by a counter from 0 to n2 - 1, their position in the spiral can be derived from the index by division modulo n: (row,col) = quotRem counter n.