2
$\begingroup$

Background: I create geometric patterns by applying many linear transformations on geometries, I need functions to weed out the exponentially increasing number of ( unnecessary ) points involved which slow down the production of Graphics code.

The problem: Suppose I have the following array of arrays, for example two 2D vectors, a 2-by-2 matrix and one 3D vector in an array as follows: This format is not fixed however. ( Originates from reading data stored in Excel which can be 'dirty'. )

  { {1,2},{1,3}, {{1,0},{0,1}}, {10,20,30} } This format is invalid.
  ( Because it contains {10,20,30} , a 3D vector at the lowest level. )

  { {1,2},{1,3}, {{1,0},{0,1}}, {1,2} } This format is valid
  ( Because it contains only 2-D vectors at the lowest level, note the 2-by-2 matrix )

I want to replace the valid array with:

  { {1,2},{1,3},{1,0},{0,1} } 
  ( a list of 2D vectors. )
  { 1, 2, {3,4}, 1 }
  a list with the position of the row vectors in the list above.

Key part of the problem =>: Note that (1,2) is stored only once in the first list while it occurs twice in the original array. <=

Ideally I seek a validQ function that validates the input and a toGraph function that splits a valid row into two new rows. ( Although not a Graph Theory problem, there are similarities. I attempt to make the geometric pattern independent from its ( Cartesian ) coordinates. )

A complication is that the numbers are real ( square roots ) or involve Pi, and / or originate from spreadsheet calculations. Rounding or cutting to two places behind the decimal point is not a problem.

My attempts to solve this involved Map and Position, but my attempts failed, I can show no working snippet to start with. I hope that the example data suffices.

Question: Is there a clean functional style code to tackle this problem ?

$\endgroup$
1
  • $\begingroup$ ndroock1, please consider cleaning up any outdated comments to the answers below. $\endgroup$
    – Mr.Wizard
    Commented Apr 14, 2012 at 18:02

2 Answers 2

3
$\begingroup$

Assuming valid data, I think this does what you need:

valid = {{1, 2}, {1, 3}, {{1, 0}, {0, 1}}, {1, 2}}

a={};
b=valid/.{x:List[_?NumericQ,_?NumericQ]:>(Position[a,x]/.{}:>{{Length[AppendTo[a,x]]}})[[1,1]]};
a
b
$\endgroup$
0
2
$\begingroup$
  1. Regarding validation, you can replace every construct of type List[number,number] and see if there are other types of items remaining (after flattening). That should validate your input:

    isValid[l_] := Length[DeleteCases[
      Flatten[l /. List[_Real | _Integer, _Real | _Integer] :> Null /. List[] :> 0], Null]] == 0
    
  2. Once you know the list is valid, you can recover your list of 2D vectors by flattening then partitioning:

    Partition[Flatten[{{1, 2}, {1, 3}, {{{1, 0}}}, {0, 1}, {1, 2}}], 2]
    
$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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