0

I'm trying to create a simple criss cross solver, but I can't even get through the reading of the data. Input are two files, legend and main. From legend I create a simple array with words (which works). However, when I try to make a 2D array of letters from the puzzle itself, I end up with empty array in the END section.

{
   if(FILENAME=="legend") {
      l[NR]=$1
   }

   else{
      mw=NF
      for(i=1;i<=NF;i++)
         m[i,NR]=$i
      mh++

      for(i=1;i<=NF;i++)
         printf "%s ", m[i,NR]
   }
}

END{
   print "LEGEND:"
   for(i=1;i<length(l);i++)
      print l[i]

   print "MAIN:"
   for(h=1;h<=mh;h++){
      print "For line ",h
      for(w=1;w<=mw;w++){
         print "For element ",w
         if(m[w,h]!=""){
            print m[w,h]
         }
      }
   }
}

Edit: Creating only matrix-reader by itself works correctly, however it doesn't work right when in one code with the other reader. It does work, because printing in the code line-by-line works. The array only empties in the END section and I just can't wrap my head around why... Are they interfering in some way? The "legend" is read first and yet the array stays untouched in the END. The "main" goes second, gets read and written properly, and then disappears in the END. Have you any idea why?

1 Answer 1

1

You use NR as an index when you put data into m:

m[i,NR]=$i

After reading the legend file, NR is not reset, which means that the index does not start at 1,1. You may want to use FNR instead, or mh + 1.

I have not looked at the rest of the code.


Some suggestions for improvements:

I don't know what your data looks like so I've been guessing. NF and FNR are left untouched from the last line of input in the END block, so as long as the last line of you last file was correct and fully specified, this ought to work. This gets rid of the mh and mw variables.

The easy way to loop over a simple array is to use for (i in arr). This sets i to each index in the array in turn. Note though, that the indexes may well be presented to the loop "out of order".

The first block reads the legend file. This means that this has to be the first file operand on the command line.

NR == FNR { l[FNR] = $1; next }

{
    for (i = 1; i <= NF; i++) {
        m[i,FNR] = $i
    }
    print
}

END {
    print "LEGEND:"
    for (i in l) print l[i]

    print "MAIN:"
    for (h = 1; h <= FNR; h++) {
        printf("For line %d\n", h)
        for (w = 1; w <= NF; w++) {
            printf("For element %d\n", w)
            if (m[w,h]) print m[w,h]
        }
    }
}

For that last double loop, you could also do

for (i in m) print i, m[i]

but you miss the ordering and the extra informational output.

1
  • Exactly. I was just slowly realising changing the order of input files makes more weird stuff happen. Changing NR with FNR fixed it all. Many thanks.
    – MintSam
    May 7, 2018 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.