Code Golf: Zigzag pattern scanning - language-agnostic

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.
The Challenge
The shortest code by character count that takes a single input integer N (N >= 3) and returns an array of indices that when iterated would traverse an NxN matrix according to the JPEG "zigzag" scan pattern. The following is an example traversal over an 8x8 matrixsrc:
Examples
(The middle matrix is not part of the input or output, just a representation of the NxN matrix the input represents.)
1 2 3
(Input) 3 --> 4 5 6 --> 1 2 4 7 5 3 6 8 9 (Output)
7 8 9
1 2 3 4
(Input) 4 --> 5 6 7 8 --> 1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16 (Output)
9 10 11 12
13 14 15 16
Notes
The resulting array's base should be appropriate for your language (e.g., Matlab arrays are 1-based, C++ arrays are 0-based).
This is related to this question.
Bonus
Extend your answer to take two inputs N and M (N, M >=3) and perform the same scan over an NxM matrix. (In this case N would be the number of columns and M the number of rows.)
Bonus Examples
1 2 3 4
(Input) 4 3 --> 5 6 7 8 --> 1 2 5 9 6 3 4 7 10 11 8 12 (Output)
9 10 11 12
1 2 3
(Input) 3 4 --> 4 5 6 --> 1 2 4 7 5 3 6 8 10 11 9 12 (Output)
7 8 9
10 11 12

J, 13 15 characters
;<#|.`</.i.2$
Usage:
;<#|.`</.i.2$ 3
0 1 3 6 4 2 5 7 8
;<#|.`</.i.2$ 4
0 1 4 8 5 2 3 6 9 12 13 10 7 11 14 15
Explanation
(NB. is J's comment indicator)
; NB. Link together...
<#|.`< NB. ... 'take the reverse of' and 'take normally'
/. NB. ... applied to alternating diagonals of...
i. NB. ... successive integers starting at 0 and counting up to fill an array with dimensions of...
2$ NB. ... the input extended cyclically to a list of length two.
J, bonus, 13 characters
;<#|.`</.i.|.
Usage:
;<#|.`</.i.|. 3 4
0 1 3 6 4 2 5 7 9 10 8 11
;<#|.`</.i.|. 9 6
0 1 9 18 10 2 3 11 19 27 36 28 20 12 4 5 13 21 29 37 45 46 38 30 22 14 6 7 15 23 31 39 47 48 40 32 24 16 8 17 25 33 41 49 50 42 34 26 35 43 51 52 44 53

Python, 92, 95, 110, 111, 114, 120, 122, 162, 164 chars
N=input()
for a in sorted((p%N+p/N,(p%N,p/N)[(p%N-p/N)%2],p)for p in range(N*N)):print a[2],
Testing:
$ echo 3 | python ./code-golf.py
0 1 3 6 4 2 5 7 8
$ echo 4 | python ./code-golf.py
0 1 4 8 5 2 3 6 9 12 13 10 7 11 14 15
This solution easily generalizes for NxM boards: tweak the input processing and replace N*N with N*M:
N,M=map(int,raw_input().split())
for a in sorted((p%N+p/N,(p%N,p/N)[(p%N-p/N)%2],p)for p in range(N*M)):print a[2],
I suspect there's some easier/shorter way to read two numbers.
Testing:
$ echo 4 3 | python ./code-golf.py
0 1 4 8 5 2 3 6 9 10 7 11

Ruby, 69 89 chars
n=gets.to_i
puts (0...n*n).sort_by{|p|[t=p%n+p/n,[p%n,p/n][t%2]]}*' '
89 chars
n=gets.to_i
puts (0...n*n).map{|p|[t=p%n+p/n,[p%n,p/n][t%2],p]}.sort.map{|i|i[2]}.join' '
Run
> zigzag.rb
3
0 1 3 6 4 2 5 7 8
> zigzag.rb
4
0 1 4 8 5 2 3 6 9 12 13 10 7 11 14 15
Credits to doublep for the sort method.

F#, 126 chars
let n=stdin.ReadLine()|>int
for i=0 to 2*n do for j in[id;List.rev].[i%2][0..i]do if i-j<n&&j<n then(i-j)*n+j|>printf"%d "
Examples:
$ echo 3 | fsi --exec Program.fsx
0 1 3 6 4 2 5 7 8
$ echo 4 | fsi --exec Program.fsx
0 1 4 8 5 2 3 6 9 12 13 10 7 11 14 15

Golfscript, 26/30 32/36 45 59 characters
Shortest non-J solution so far:
Updated sort (don't tell the others!) - 30 chars:
~:1.*,{..1/\1%+.2%.+(#*]}$' '* #solution 1
#~:\.*,{.\/1$\%+.1&#.~if]}$' '* #solution 2
#~\:1*,{..1/\1%+.2%.+(#*]}$' '* #(bonus)
#~\:\*,{.\/1$\%+.1&#.~if]}$' '* #(bonus)
Straight implementation - 36 chars:
~:#.*,{[.#%:|\#/:^+|^- 2%^|if]}$' '*
#~\:#*,{[.#%:|\#/:^+|^- 2%^|if]}$' '* #(bonus)
If you can provide output as "013642578" instead of "0 1 3 6 4 2 5 7 8", then you can remove the last 4 characters.
Credit to doublep for the sorting technique.
Explanation:
~\:#* #read input, store first number into #, multiply the two
, #put range(#^2) on the stack
{...}$ #sort array using the key in ...
" "* #join array w/ spaces
and for the key:
[ #put into an array whatever is left on the stack until ]
.#%:| #store #%n on the stack, also save it as |
\#/:^ #store #/n on the stack, also save it as ^
+ #add them together. this remains on the stack.
|^- 2%^|if #if (| - ^) % 2 == 1, then put ^ on stack, else put | on stack.
] #collect them into an array

MATLAB, 101/116 chars
Its basically a condensed version of the same answer given here, to be run directly on the command prompt:
N=input('');i=fliplr(spdiags(fliplr(reshape(1:N*N,N,N)')));i(:,1:2:end)=flipud(i(:,1:2:end));i(i~=0)'
and an extended one that read two values from the user:
S=str2num(input('','s'));i=fliplr(spdiags(fliplr(reshape(1:prod(S),S)')));i(:,1:2:end)=flipud(i(:,1:2:end));i(i~=0)'
Testing:
3
ans =
1 2 4 7 5 3 6 8 9
and
4 3
ans =
1 2 5 9 6 3 4 7 10 11 8 12

Ruby 137 130 138 characters
n=gets.to_i
def g(a,b,r,t,s);x=[s*r]*t;t==r ?[a,x,a]:[a,x,g(b,a,r,t+1,-s),x,a];end
q=0;puts ([1]+g(1,n,n-1,1,1)).flatten.map{|s|q+=s}*' '
$ zz.rb
3
1 2 4 7 5 3 6 8 9
$ zz.rb
4
1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16

C89 (280 bytes)
I guess this can still be optimized - I use four arrays to store the possible movement
vectors when hitting a wall. I guess it can be done, saving some chars at the definition, but I think it will cost more to implement the logic further down. Anyway, here you go:
t,l,b,r,i,v,n;main(int c,char**a){n=atoi(*++a);b=n%2;int T[]={n-1,1},L[]={1-n,n}
,B[]={1-n,1},R[]={n-1,n};for(c=n*n;c--;){printf("%d%c",i,c?32:10);if(i>=n*(n-1))
v=B[b=!b];else if(i%n>n-2){if(!(n%2)&&i<n)goto g;v=R[r=!r];}else if(i<n)g:v=T[t=
!t];else if(!(i%n))v=L[l=!l];i+=v;}}
compiles with a few warnings, but as far as I know it is portable C89. I'm actually not sure
whether my algorithm is clever at all, maybe you can get way shorter with a better one
(haven't taken the time to understand the other solutions yet).

Haskell 117 characters
i s=concatMap(\q->d q++(reverse.d$q+1))[0,2..s+s]
where d r=[x+s*(r-x)|x<-[0..r],x<s&&(r-x)<s]
main=readLn>>=print.i
Runs:
$ echo 3 | ./Diagonals
[0,1,3,6,4,2,5,7,8]
$ echo 4 | ./Diagonals
[0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15]
The rectangular variant is a little longer, at 120 characters:
j(w,h)=concatMap(\q->d q++(reverse.d$q+1))[0,2..w+h]
where d r=[x+w*(r-x)|x<-[0..r],x<w&&(r-x)<h]
main=readLn>>=print.j
Input here requires a tuple:
$ echo '(4,3)' | ./Diagonals
[0,1,4,8,5,2,3,6,9,10,7,11]
$ echo '(3,4)' | ./Diagonals
[0,1,3,6,4,2,5,7,9,10,8,11]
Answers are all 0-based, and returned as lists (natural forms for Haskell).

Perl 102 characters
<>=~/ /;print map{$_%1e6," "}sort map{($x=($%=$_%$`)+($/=int$_/$`))*1e9+($x%2?$/:$%)*1e6+$_}0..$'*$`-1
usage :
echo 3 4 | perl zigzag.pl
0 1 3 6 4 2 5 7 9 10 8 11

Related

What is the problem with the size of the moving window (movfun) in octave?

I'm trying to use movfun (moving window) in octave
x = -1000:0.1:1000
y = sin(x)
movfun(#(arg) printf("%d\n", size(arg)), y(1:100), 4)
I expect to see all 4s
However, surprisingly (to me) I get:
4
1
4
97
2
1
3
1
3
1
ans =
Columns 1 through 29:
4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
Columns 30 through 58:
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
Columns 59 through 87:
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
Columns 88 through 100:
5 5 5 5 5 5 5 5 5 5 5 5 4
What is wrong with my expectations?
This sheds a bit more light (I've increased window size to 8 for more clarity):
movfun( #(x) size(x, 1), y(1:100), 8 )
movfun( #(x) size(x, 2), y(1:100), 8 )
These produce the following outputs respectively:
4 5 6 7 8 8 8 8 [...] 8 8 8 8 7 6 5
1 1 1 1 93 93 93 93 [...] 93 93 93 93 1 1 1
This tells us that, presumably, under the hood, movfun makes sure to pass each 8-element vector in vertical form for processing, and that it treats the edges specially as single inputs, but then grabs all the 'non-edge' elements and performs some form of vectorised calculation involving all 93 columns at the same time.
We can confirm the 'edge' behaviour from the documentation:
"Endpoints"
This property controls how results are calculated at the
boundaries (endpoints) of the window. Possible values are:
"shrink" (default)
The window is truncated at the beginning and end of the array to exclude elements for which there is no source data. For example, with a window of length 3, 'Y(1) = FCN (X(1:2))', and 'Y(end) = FCN (X(end-1:end))'.

Reading Date from CSV file in Octave

I want to read a CSV file in Octave which has a date column and 4 columns which are integers. I have used.
[num,txt,raw] = dlmread('Mitteilungen_data.csv');
ID = num(:,1) ;
DATE = datestr (date, yyyy-mm-dd) ;
FK_OBSERVERS= num(:,2) ;
GROUPS = num(:,3) ;
SUNSPOTS = num(:,4) ;
WOLF = num(:,5) ;
dn=datenum(DATE,'YYYY-MM-DD');
plot(dn,WOLF)
Sample Data:
ID DATE FK_OBSERVERS GROUPS SUNSPOTS WOLF
4939 1612-01-17 11 5 11 61
83855 1612-01-18 85 2 2 22
4940 1612-01-20 11 4 5 45
4941 1612-01-21 11 4 7 47
4942 1612-01-23 11 3 5 35
4943 1612-01-24 11 3 6 36
4944 1612-01-25 11 6 13 73
4945 1612-01-27 11 3 6 36
83856 1612-01-28 85 NULL NULL NULL
4946 1612-01-29 11 3 6 36
4947 1612-01-30 11 4 8 48
4948 1612-02-02 11 5 8 58
4949 1612-02-05 11 4 7 47
4950 1612-02-06 11 3 7 37
4951 1612-02-10 11 5 7 57
4952 1612-02-12 11 3 4 34
4953 1612-02-13 11 2 2 22
4954 1612-02-14 11 3 3 33
The Date column is showing an error: element number 2 undefined in return list. How can I fix this?
You are using
[num, txt, raw] = dlmread( %...
but dlmread does not return three outputs. Type help dlmread in your console to see the syntax.
What does seem to return these three arguments is the xlsread command. Perhaps you copied code that used xlsread?
However, even so, I would still use csv2cell. Type csv2cell('data.csv') (where data.csv is the name of your file) to see what kind of output it gives
Before you can use any of the commands defined in the io package, you need to load it on your workspace.
pkg load io

compare cell entries and return values In SAS

just would like to compare cell entries and return values.
coustmer_NO id A1 A2 A3 A4
1 5 10 20 45 0
1 13 0 45 2 5
2 4 0 10 7 8
2 3 7 9 55 0
2 10 0 0 0 0
3 4 90 8 14 3
3 10 20 7 4 15
how to count the ID that has (value > 030) for each customer_no
then, the min number of values before 030 appears.
The expected output would be something like:
cosutmer_no , count_ac_num , values
1 2 1
2 1 1
3 1 3
I would recommend converting to a more vertical structure. Then you can begin trying to apply your business logic, although I am having a hard time understanding what that is.
Assuming that the quotes are not meaningful (looks like someone had a string like "xxx" that had actual quote characters in it that was written to a CSV file and so extra quotes where added to protect the existing quotes so it became """xxx""") you could just use compress() function to remove them.
You could then just split the resulting string into 3 character substrings.
data want ;
set have ;
array h history1 history2 ;
do history=1 to dim(h);
h(history)=compress(h(history),'"');
length index 8 value $3 ;
do index=1 by 1 until (value=' ');
value=substrn(h(history),3*(index-1)+1,3);
if value ne ' ' then output;
end;
end;
drop history1 history2;
run;
So you end up with something like this:
Obs id type history index value
1 1 13 1 1 STD
2 1 13 1 2 STD
3 1 13 1 3 058
4 1 13 1 4 030
5 1 13 2 1 STD
6 1 13 2 2 030
7 1 13 2 3 066
8 1 13 2 4 036
9 1 13 2 5 030
10 1 13 2 6 STD
11 1 13 2 7 STD
12 1 13 2 8 STD
13 1 13 2 9 STD
14 1 13 2 10 STD
15 1 3 1 1 STD
16 1 3 1 2 STD
17 1 3 1 3 STD
18 1 3 1 4 XXX
19 1 3 1 5 STD
20 1 3 1 6 XXX
21 1 3 1 7 S

Read file in Octave

I need to read a data file into Octave that may have different numbers of
elements in each line, while retaining the line separation.
For example, read in:
1 2 3 4 5
6 7 8 9
1 2 3
4 5 6 7 8
How can I use scanf to obtain something like:
1 2 3 4 5
6 7 8 9 0
1 2 3 0 0
4 5 6 7 8
Your crosspost on the help mailinglist was answered from Przemek: http://permalink.gmane.org/gmane.comp.gnu.octave.general/57521
dlmread("filename")
will do what you want.

Puzzle: find number in a given row and column in 2-dimensional array where no number may occur twice

We have a two-dimensional array with the number 0 in the upper left corner. The rest of the array is then filled with numbers so that each index contains the smallest positive integer possible that already exists neither on the same row or column.
Example:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
1 0 3 2 5 4 7 6 9 8 11 10 13 12 15 14 17 16
2 3 0 1 6 7 4 5 10 11 8 9 14 15 12 13 18 19
3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12 19 18
4 5 6 7 0 1 2 3 12 13 14 15 8 9 10 11 20 21
5 4 7 6 1 0 3 2 13 12 15 14 9 8 11 10 21 20
6 7 4 5 2 3 0 1 14 15 12 13 10 11 8 9 22 23
7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 23 22
8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 24 25
9 8 11 10 13 12 15 14 1 0 3 2 5 4 7 6 25 24
10 11 8 9 14 15 12 13 2 3 0 1 6 7 4 5 26 27
11 10 9 8 15 14 13 12 3 2 1 0 7 6 5 4 27 26
12 13 14 15 8 9 10 11 4 5 6 7 0 1 2 3 28 29
13 12 15 14 9 8 11 10 5 4 7 6 1 0 3 2 29 28
14 15 12 13 10 11 8 9 6 7 4 5 2 3 0 1 30 31
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 31 30
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0 1
17 16 19 18 21 20 23 22 25 24 27 26 29 28 31 30 1 0
Given the row and the column in such array, I need to be able to find the number in the specified index in less than one second on a relatively new desktop PC (for row and column less than a million). My brute-force attempts so far have been so futile that it's clearly not the way I want to go with this. Presumably there must be a way to find out the number in question, in linear time (?), that doesn't require computing all the preceding numbers in the array.
Observation shows that the operator is the bitwise XOR (represent each operand as a binary number, XOR together the corresponding bits, read as binary).
Now on to prove it is the XOR:
Since the XOR with one argument fixed is a bijection on the other argument, the "that exists neither on the same row or column" is satisfied.
Now it just suffices to prove the "smallest" part, namely that any lower value already occurs if we reduce either operand:
foreach A >= 0, B >= 0, F >= 0:
(A xor B > F) => (exists D: D xor B = F) or (exists E: A xor E = F)
or equivalently
foreach 0 <= A, 0 <= B, 0 <= F < (A XOR B)
(exists D: D xor B = F) or (exists E: A xor E = F)
Note that we are no longer concerned about our operator, we're proving the minimality of XOR.
Define C = A xor B
if A = 0, B = 0, then minimality is satisfied.
Now, if A and B have the same magnitude (the same bit length), then clearing the top bit of both will not change C. Clearing the top bit is a translation towards the origin in the matrix, so if a smaller value exists above or to the left after translation, it is at the same relative position before the translation.
A and B must have a different magnitude to be a counter-example. XOR (as well as the operator under consideration) are symmetric, so assume A > B.
If F is of greater magnitude than A, then it's not smaller, and thus it's not a counter-example.
If F has the same magnitude as A, then clear the highest bit in A and in F. This is a translation in the table. It changes the values, but not their ordering, so if a smaller value exists above or to the left after translation, it is at the same relative position before the translation.
If F has a smaller magnitude than A, then, by the pigeonhole principle and the properties of XOR, there exists a D with a smaller magnitude than A such that D xor B = F.
summary: The proof that XOR satisfies the conditions imposed onto the solution follows from the symmetries of XOR, its magnitude-preserving properties and its bijection properties. We can find each smaller element than A xor B by reducing A, B and the challenge until they're all zero or of different magnitude (at which point we apply the pigeonhole principle to prove the challenge can be countered without actually countering it).