Results 1 to 13 of 13

Thread: making a 2DTIntArray to IntArray

  1. #1
    Join Date
    Apr 2007
    Posts
    373
    Mentioned
    2 Post(s)
    Quoted
    24 Post(s)

    Default making a 2DTIntArray to IntArray

    Hello all,

    This is for OSRS
    i have tried
    "ComibineIntArray"
    It gave me all 0 in my array.

    i tried this

    Simba Code:
    for I := 0 to High(d2ColorsBmp) do
      begin
        for J := 0 to High(d2ColorsBMP[I]) do
        begin
          Inc(Loop);
          SetLength(ColorsBmp, Loop);
          writeln('adding color ' + tostr(d2ColorsBMP[I][J]));
          colorsBmp[Loop] :=  d2ColorsBMP[I][J];
          writeln(ColorsBmp);
        end;
      end;

    It also return all 0's

    Any help is appreciated

    [SOLVED]
    colorsBmp[Loop - 1] := d2ColorsBMP[I][J];
    Last edited by fre; 12-15-2016 at 12:58 PM.
    ~Fre

  2. #2
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by fre View Post
    [SOLVED]colorsBmp[Loop - 1] := d2ColorsBMP[I][J];
    That's because you are incrementing "Loop" BEFORE that line instead of AFTER. Simba probably has range checking turned off by default.

    I don't think that [I][J] is correct either but I may be wrong.. If Simba's Bitmaps and Arrays are Row-Major-Order, then you have to do iteration from TopDown. Meaning that the first for loop is the height and the second would be the width so "J" would represent the index horizontally and "I" would represent the index vertically. However, if it is Column-Major-Order, then your loop would be correct.


    Simba Code:
    for I := 0 to High(d2ColorsBmp) do //Height?
      begin
        for J := 0 to High(d2ColorsBMP[I]) do  //Width?
        begin
          SetLength(ColorsBmp, Loop);
          //I don't think below is the right indexing algorithm??? Should be d2ColorsBMP[J][I]??
          writeln('adding color ' + tostr(d2ColorsBMP[I][J]));
          colorsBmp[Loop] :=  d2ColorsBMP[I][J];
          writeln(ColorsBmp);
          Inc(Loop);  //moved this line. Post-Increment.
        end;
      end;


    However this seems very expensive. Why? Because a 2D array of colours representing a Bitmap most definitely has a KNOWN width and height. Thus you can rewrite it as:

    Simba Code:
    Height := High(d2ColorsBmp);
      Width := High(d2ColorsBmp[0]); //Has to be.
      SetLength(ColorsBmp, Width * Height);  //One time resize instead of every loop. Resizing an array is expensive. It creates a larger one and then copies the smaller one to it.

      for I := 0 to Height do
      begin
        for J := 0 to Width do
        begin
          writeln('adding color ' + tostr(d2ColorsBMP[J][I]));
          colorsBmp[Width * I + J] :=  d2ColorsBMP[J][I];  //Indexing.  //Can still use Inc(Loop); if you want instead..
          writeln(ColorsBmp);
        end;
      end;


    Then there's the other way (possibly a bit more expensive than the above but still less expensive than your solution):

    Simba Code:
    Height := High(d2ColorsBmp);
      Width := High(d2ColorsBmp[0]);
      SetLength(ColorsBmp, Width * Height);

      for I := 0 to Width * Height do
      begin
        colorsBmp[I] := d2ColorsBMP[I mod Width][I div Width]; //Mapping a 2D array to 1D array with a single loop.
        writeln(colorsBmp[I]);
      end;
    Last edited by Brandon; 12-15-2016 at 01:48 PM.
    I am Ggzz..
    Hackintosher

  3. #3
    Join Date
    Apr 2007
    Posts
    373
    Mentioned
    2 Post(s)
    Quoted
    24 Post(s)

    Default

    Thanks for the help.
    I started the increment in Loop before before that line because i wanted to drop the first color.
    Don't need that loop an

    I changed your code to this to make it work.
    Simba Code:
    Height := High(d2ColorsBmp[0]);//Has to be.
      writeln(Height);
      Width := High(d2ColorsBmp);
      writeln(width);
      ColorsBMP := [];
      SetLength(ColorsBmp, ((Width+1) * (Height+1)));  //One time resize instead of every loop. Resizing an array is expensive. It creates a larger one and then copies the smaller one to it.

      for I := 0 to Width do
      begin
        for J := 0 to Height do
        begin
          writeln('adding color ' + tostr(d2ColorsBMP[I][J]));
          writeln(tostr(width) +'' +tostr(I) +''+ tostr(J));
          writeln(Width * I + J);
          colorsBmp[(Width-1) * I + J] :=  d2ColorsBMP[I][J];  //Indexing.  //Can still use Inc(Loop); if you want instead..
          writeln(ColorsBmp);
        end;
      end;
    ~Fre

  4. #4
    Join Date
    Apr 2007
    Posts
    373
    Mentioned
    2 Post(s)
    Quoted
    24 Post(s)

    Default

    Nah still don't work properly
    something is wrong with the loops.
    Simba Code:
    Height := High(d2ColorsBmp[0]);//Has to be.
      writeln(Height);
      Width := High(d2ColorsBmp);
      writeln(width);
      ColorsBMP := [];
      SetLength(ColorsBmp, ((Width+1) * (Height+1)));  //One time resize instead of every loop. Resizing an array is expensive. It creates a larger one and then copies the smaller one to it.

      for I := 0 to Width do
      begin
        for J := 0 to Height do
        begin
          writeln('adding color ' + tostr(d2ColorsBMP[I][J]));
          colorsBmp[Loop] :=  d2ColorsBMP[I][J];  //Indexing.  //Can still use Inc(Loop); if you want instead..
    Inc(Loop);
          writeln(ColorsBmp);
        end;
      end;

    Changed it back to 'loop' increments and works fine now.
    Last edited by fre; 12-15-2016 at 03:58 PM.
    ~Fre

  5. #5
    Join Date
    Feb 2006
    Location
    Helsinki, Finland
    Posts
    1,395
    Mentioned
    30 Post(s)
    Quoted
    107 Post(s)

    Default

    Quote Originally Posted by fre View Post
    Nah still don't work properly
    something is wrong with the loops.
    Simba Code:
    Height := High(d2ColorsBmp[0]);//Has to be.
      writeln(Height);
      Width := High(d2ColorsBmp);
      writeln(width);
      ColorsBMP := [];
      SetLength(ColorsBmp, ((Width+1) * (Height+1)));  //One time resize instead of every loop. Resizing an array is expensive. It creates a larger one and then copies the smaller one to it.

      for I := 0 to Width do
      begin
        for J := 0 to Height do
        begin
          writeln('adding color ' + tostr(d2ColorsBMP[I][J]));
          colorsBmp[Loop] :=  d2ColorsBMP[I][J];  //Indexing.  //Can still use Inc(Loop); if you want instead..
    Inc(Loop);
          writeln(ColorsBmp);
        end;
      end;

    Changed it back to 'loop' increments and works fine now.
    @fre, here you go.. Several ways below.

    Single loop version:
    Simba Code:
    function T2DIntegerArray.Merge(): TIntegerArray; overload;
    var
      i, j: Integer;
    begin
      j := Length(self[0]);
      SetLength(Result, (j * Length(self)));
      for i := 0 to High(Result) do
        Result[i] := self[(i div j)][(i mod j)];
    end;

    var
      matrix: T2DIntegerArray;
      arr: TIntegerArray;

    begin
      ClearDebug;
      matrix := [[0,1], [2,3], [4,5], [6,7], [8,9]];
      arr := matrix.Merge();
      WriteLn(arr, ' <= ', matrix);
      matrix := [[0,1,2,3,4], [5,6,7,8,9]];
      arr := matrix.Merge();
      WriteLn(arr, ' <= ', matrix);
      matrix := [[1,2,3], [4,5,6], [7,8,9]];
      arr := matrix.Merge();
      WriteLn(arr, '    <= ', matrix);
    end;

    Double loop without incrementing:
    Simba Code:
    function T2DIntegerArray.Merge(): TIntegerArray; overload;
    var
      w, h, x, y: Integer;
    begin
      h := Length(self);
      w := Length(self[0]);
      SetLength(Result, (w * h));
      for y := 0 to (h - 1) do
        for x := 0 to (w - 1) do
          Result[(x + (y * w))] := self[y][x];
    end;

    var
      matrix: T2DIntegerArray;
      arr: TIntegerArray;

    begin
      ClearDebug;
      matrix := [[0,1], [2,3], [4,5], [6,7], [8,9]];
      arr := matrix.Merge();
      WriteLn(arr, ' <= ', matrix);
      matrix := [[0,1,2,3,4], [5,6,7,8,9]];
      arr := matrix.Merge();
      WriteLn(arr, ' <= ', matrix);
      matrix := [[1,2,3], [4,5,6], [7,8,9]];
      arr := matrix.Merge();
      WriteLn(arr, '    <= ', matrix);
    end;

    Double loop version with incrementing:
    Simba Code:
    function T2DIntegerArray.Merge(): TIntegerArray; overload;
    var
      w, h, x, y, z: Integer;
    begin
      h := Length(self);
      w := Length(self[0]);
      z := 0;
      SetLength(Result, (w * h));
      for y := 0 to (h - 1) do
        for x := 0 to (w - 1) do
        begin
          Result[z] := self[y][x];
          z := (z + 1);
        end;
    end;

    var
      matrix: T2DIntegerArray;
      arr: TIntegerArray;

    begin
      ClearDebug;
      matrix := [[0,1], [2,3], [4,5], [6,7], [8,9]];
      arr := matrix.Merge();
      WriteLn(arr, ' <= ', matrix);
      matrix := [[0,1,2,3,4], [5,6,7,8,9]];
      arr := matrix.Merge();
      WriteLn(arr, ' <= ', matrix);
      matrix := [[1,2,3], [4,5,6], [7,8,9]];
      arr := matrix.Merge();
      WriteLn(arr, '    <= ', matrix);
    end;

    Edit: Noticed you already had similar solutions worked out.
    Last edited by Janilabo; 12-15-2016 at 05:22 PM. Reason: Cleaned post

  6. #6
    Join Date
    Feb 2012
    Location
    Norway
    Posts
    995
    Mentioned
    145 Post(s)
    Quoted
    596 Post(s)

    Default

    Simba Code:
    program Merge;

    function MergeATIA(arr:T2DIntArray): TIntegerArray;
    var i,top,size:Int32;
    begin
      for i:=0 to High(arr) do
      begin
        size := Length(arr[i]);
        if size > 0 then
        begin
          top := Length(Result);
          SetLength(Result, top+size);
          MemMove(arr[i][0], Result[top], size*SizeOf(arr[i][0]));
        end;
      end;
    end;

    var
      a:T2DIntArray;
    begin
      a := [[0,1,2,3,4],[5,6],[7,8,9]];
      WriteLn(MergeATIA(a));
    end.

    @Janilabo; none of the ways you describe there will work for 2D array that has elements of different lengths, they will only work for "matrices".


    @fre; The only mistake in your first post is that you increase "loop" early on, so that it's never 0, so lets go through the first iteration (the first time it enters that block):
    Simba Code:
    Inc(Loop);                                    //loop is now _1_
    SetLength(ColorsBmp, Loop);                   //length of array is now _1_
    writeln('adding color ' + tostr(d2ColorsBMP[I][J]));
    colorsBmp[Loop] :=  d2ColorsBMP[I][J];        //we index colorsBmp at _1_ -- ERROR, should be 0!!!!
    writeln(ColorsBmp);
    So with the current logic you only have to make one change in your code:
    >> colorsBmp[Loop-1] := d2ColorsBMP[I][J];
    Last edited by slacky; 12-15-2016 at 05:45 PM.
    !No priv. messages please

  7. #7
    Join Date
    Feb 2006
    Location
    Helsinki, Finland
    Posts
    1,395
    Mentioned
    30 Post(s)
    Quoted
    107 Post(s)

    Default

    Quote Originally Posted by slacky View Post
    Simba Code:
    program Merge;

    function MergeATIA(arr:T2DIntArray): TIntegerArray;
    var i,top,size:Int32;
    begin
      for i:=0 to High(arr) do
      begin
        size := Length(arr[i]);
        if size > 0 then
        begin
          top := Length(Result);
          SetLength(Result, top+size);
          MemMove(arr[i][0], Result[top], size*SizeOf(arr[i][0]));
        end;
      end;
    end;

    var
      a:T2DIntArray;
    begin
      a := [[0,1,2,3,4],[5,6],[7,8,9]];
      WriteLn(MergeATIA(a));
    end.

    @Janilabo; none of the ways you describe there will work for 2D array that has elements of different lengths, they will only work for "matrices".
    @slacky Yeah I know, but I thought he was working with matrices?

    Edit: My versions in "old fashion" style:

    Single loop:
    Simba Code:
    function T2DIntegerArray_Merge(const arr: T2DIntegerArray): TIntegerArray; overload;
    var
      i, j: Integer;
    begin
      j := Length(arr[0]);
      SetLength(Result, (j * Length(arr)));
      for i := 0 to High(Result) do
        Result[i] := arr[(i div j)][(i mod j)];
    end;

    var
      matrix: T2DIntegerArray;
      arr: TIntegerArray;

    begin
      ClearDebug;
      matrix := [[0,1], [2,3], [4,5], [6,7], [8,9]];
      arr := T2DIntegerArray_Merge(matrix);
      WriteLn(arr, ' <= ', matrix);
      matrix := [[0,1,2,3,4], [5,6,7,8,9]];
      arr := T2DIntegerArray_Merge(matrix);
      WriteLn(arr, ' <= ', matrix);
      matrix := [[1,2,3], [4,5,6], [7,8,9]];
      arr := T2DIntegerArray_Merge(matrix);
      WriteLn(arr, '    <= ', matrix);
    end.

    Double loop, without incrementing:
    Simba Code:
    function T2DIntegerArray_Merge(const arr: T2DIntegerArray): TIntegerArray; overload;
    var
      w, h, x, y: Integer;
    begin
      h := Length(arr);
      w := Length(arr[0]);
      SetLength(Result, (w * h));
      for y := 0 to (h - 1) do
        for x := 0 to (w - 1) do
          Result[(x + (y * w))] := arr[y][x];
    end;

    var
      matrix: T2DIntegerArray;
      arr: TIntegerArray;

    begin
      ClearDebug;
      matrix := [[0,1], [2,3], [4,5], [6,7], [8,9]];
      arr := T2DIntegerArray_Merge(matrix);
      WriteLn(arr, ' <= ', matrix);
      matrix := [[0,1,2,3,4], [5,6,7,8,9]];
      arr := T2DIntegerArray_Merge(matrix);
      WriteLn(arr, ' <= ', matrix);
      matrix := [[1,2,3], [4,5,6], [7,8,9]];
      arr := T2DIntegerArray_Merge(matrix);
      WriteLn(arr, '    <= ', matrix);
    end.

    Double loop, with incrementing:
    Simba Code:
    function T2DIntegerArray_Merge(const arr: T2DIntegerArray): TIntegerArray; overload;
    var
      w, h, x, y, z: Integer;
    begin
      h := Length(arr);
      w := Length(arr[0]);
      z := 0;
      SetLength(Result, (w * h));
      for y := 0 to (h - 1) do
        for x := 0 to (w - 1) do
        begin
          Result[z] := arr[y][x];
          z := (z + 1);
        end;
    end;

    var
      matrix: T2DIntegerArray;
      arr: TIntegerArray;

    begin
      ClearDebug;
      matrix := [[0,1], [2,3], [4,5], [6,7], [8,9]];
      arr := T2DIntegerArray_Merge(matrix);
      WriteLn(arr, ' <= ', matrix);
      matrix := [[0,1,2,3,4], [5,6,7,8,9]];
      arr := T2DIntegerArray_Merge(matrix);
      WriteLn(arr, ' <= ', matrix);
      matrix := [[1,2,3], [4,5,6], [7,8,9]];
      arr := T2DIntegerArray_Merge(matrix);
      WriteLn(arr, '    <= ', matrix);
    end.
    Last edited by Janilabo; 12-15-2016 at 05:46 PM.

  8. #8
    Join Date
    Feb 2012
    Location
    Norway
    Posts
    995
    Mentioned
    145 Post(s)
    Quoted
    596 Post(s)

    Default

    Quote Originally Posted by Janilabo View Post
    @slacky Yeah I know, but I thought he was working with matrices?
    He didn't mention that, so I would not be to sure about that. Perhaps.
    !No priv. messages please

  9. #9
    Join Date
    Feb 2006
    Location
    Helsinki, Finland
    Posts
    1,395
    Mentioned
    30 Post(s)
    Quoted
    107 Post(s)

    Default

    Quote Originally Posted by slacky View Post
    He didn't mention that, so I would not be to sure about that. Perhaps.
    That is a good point mate (now that I checked hes post again...), there is no clue if he was after dynamic or static version for doing this particular task.

    Well, I am sure he does appreciate all the answers with working solutions, so we are both fine.

  10. #10
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    If it is a matrix (as it should be because it's a bitmap of fixed width & height), he can memcpy which would be the fastest without a doubt. Plus wouldn't have to worry about Row-Major vs. Column-Major.

    Simba Code:
    procedure memcpy(dest, src : pointer; size : size_t);
    begin
      move(src^, dest^, size);
    end;

    var
      colorsBmp: TIntegerArray;
      d2ColorsBmp: T2DIntArray;
    begin
      setLength(colorsBmp, Length(d2ColorsBmp) * Length(d2ColorsBmp[0]));
      memcpy(@colorsBmp[0], @d2ColorsBmp[0][0], Length(colorsBmp) * sizeof(Integer));
    end.

    and since he doesn't want the very first colour then:

    Simba Code:
    procedure memcpy(dest, src : pointer; size : size_t);
    begin
      move(src^, dest^, size);
    end;

    var
      colorsBmp: TIntegerArray;
      d2ColorsBmp: T2DIntArray;
      size: Integer;
    begin
      size := (Length(d2ColorsBmp) * Length(d2ColorsBmp[0])) - 1;

      setLength(colorsBmp, size);
      memcpy(@colorsBmp[0], @d2ColorsBmp[0][0] + 1, size * sizeof(Integer));
    end.
    Last edited by Brandon; 12-15-2016 at 09:43 PM.
    I am Ggzz..
    Hackintosher

  11. #11
    Join Date
    Feb 2012
    Location
    Norway
    Posts
    995
    Mentioned
    145 Post(s)
    Quoted
    596 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    If it is a matrix (as it should be because it's a bitmap of fixed width & height), he can memcpy which would be the fastest without a doubt. Plus wouldn't have to worry about Row-Major vs. Column-Major.

    Simba Code:
    procedure memcpy(dest, src : pointer; size : size_t);
    begin
      move(src^, dest^, size);
    end;

    var
      colorsBmp: TIntegerArray;
      d2ColorsBmp: T2DIntArray;
    begin
      setLength(colorsBmp, Length(d2ColorsBmp) * Length(d2ColorsBmp[0]));
      memcpy(@colorsBmp[0], @d2ColorsBmp[0][0], Length(colorsBmp) * sizeof(Integer));
    end.
    Hmm, I think you were a bit too quick-thinking here.
    This concept would only work if 2d arrays was in fact 1 dimensional arrays behind the scene, but they contain separately allocated arrays - spread out to different places in memory (where ever they fit). It would also require that arrays has no headers (refcount, length).

    I think the generic solution I posted is roughly as efficient as you get it in lape - Only iterating over the array (not the inner ones), the rest is done by MemMove.
    Last edited by slacky; 12-16-2016 at 07:08 AM.
    !No priv. messages please

  12. #12
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by slacky View Post
    Hmm, I think you were a bit too quick-thinking here.
    This concept would only work if 2d arrays was in fact 1 dimensional arrays behind the scene, but they contain separately allocated arrays - spread out to different places in memory (where ever they fit). It would also require that arrays has no headers (refcount, length).

    I think the generic solution I posted is roughly as efficient as you get it in lape - Only iterating over the array (not the inner ones), the rest is done by MemMove.

    Well that's good to know but also pretty awful. Didn't think Lape would inherit that directly from Pascal & Delphi. I thought it'd be contiguous but I guess now that you mention it, you can SetLength each index.
    Last edited by Brandon; 12-16-2016 at 07:29 AM.
    I am Ggzz..
    Hackintosher

  13. #13
    Join Date
    Apr 2007
    Posts
    373
    Mentioned
    2 Post(s)
    Quoted
    24 Post(s)

    Default

    I used
    Simba Code:
    GetBitmapAreaColors

    to get the 2DTIntegerArray.
    So not per se a matrices.

    I do appreciate all the answers. Whenever i write a piece of function i know there are 99 other ways to do it.
    Always good to look at how other people would write a piece of code.

    I appreciate all the answers.
    ~Fre

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •