FreeBASIC syntax challenge games

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Post by Tourist Trap »

To make the reading easier, here is the last post from fxm (last page):
fxm wrote:Preparation for the next challenge (for enigma #18, using now dynamics arrays)

The similitude between raw arrays and encapsulated arrays in a Type is more difficult to code when it concerns dynamic arrays (compared to non-dynamic arrays):
- The Type structure contains only the array descriptor.
- For dynamic multi-dimensional arrays, there is no possibility of field composition with Types containing a one-dimensional array because a multi-dimensional array descriptor is not a composition of several one-dimensional array descriptors.

Therefore:
- Only one Type containing the dynamic multi-dimensional array can be used.
- The new difficulty is to get the descriptor address of a raw dynamic array.

The following example shows how to access a raw dynamic array through the structure of an encapsulated dynamic array in a Type.
The principle to get the descriptor address of the raw array is to pass the array to a procedure:
- Under the hood, its descriptor is passed by reference, so the descriptor address is passed by value as a pointer.
- For more information, see at http://www.freebasic.net/forum/viewtopi ... =3&t=23792.

Code: Select all

Dim As Integer array()
Redim array(1 To 5, 1 To 9)
For I As Integer = 1 To 5
  For J As Integer = 1 To 9
    array(I, J) = I*10 + J
  Next J
Next I

Type MyArray
   As Integer array(Any, Any)
End Type
Function arrayDescriptorPtrFunction (Byval p As Any Ptr) As Any Ptr
  Return p
End function
#Define arrayDescriptorPtr(array) Cast(Function (() As Typeof((array))) As Any Ptr, @arrayDescriptorPtrFunction)(array())

'-----------------------------------------
Dim Byref As MyArray a = *Cptr(MyArray Ptr, arrayDescriptorPtr(array))
'-----------------------------------------

For I As Integer = 1 To 5
  For J As Integer = 1 To 9
    Print a.array(I, J);
  Next J
  Print
Next I
Print

Sleep

Maybe I can propose an additional challenge, even if I'm still trying to solve it:
  • Provide a UDT that wraps a multidimensional array so that success=TRUE in an example like below:

    Code: Select all

    dim as integer	A(10,10,10)
    dim as UDT  V => UDT( A() )
    
    dim as boolean success => TRUE
    
    for i as integer = 0 to 10
      for j as integer = 0 to 10 
        for k as integer = 0 to 10
            if not A(i, j,k)=V[i][j][k] then
                 success = FALSE
                 exit for
            end if
        next k 
      next j
    next i
    
    ? success
    
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

@Tourist Trap,

The only new difficulty (for me) is in defining a UDT structure that supports the following syntax:
instance[j][k]
for accessing a three-dimensional array.

After a short analysis, I found for this interesting challenge a solution that seems to me very logic and even elegant.
(I would classify my solution in force 2-3 as difficulty)
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

TT

Code: Select all


'=========== THE UDT =========
Type udt
    Declare Constructor
    Declare Constructor (() As Integer)
    Declare Destructor
    As udt Ptr   p(10,10,10)
    Declare Operator [](i As Integer)  As udt Ptr
End Type
Constructor udt
End Constructor

Constructor udt(A() As Integer)
For i As Integer = 0 To 10
    For j As Integer = 0 To 10 
        For k As Integer = 0 To 10
            this.p(i,j,k)=New udt[11]
        Next k 
    Next j
Next i
End Constructor

Destructor udt
For i As Integer = 0 To 10
    For j As Integer = 0 To 10 
        For k As Integer = 0 To 10
            Delete[]this.p(i,j,k)
        Next k 
    Next j
Next i
End Destructor

Operator udt.[] (Byval i As Integer)  As udt Ptr 
Return This.p(i,i,i)
End Operator

'====================================== TT ============

Dim As Integer   A(10,10,10)

Dim As UDT  V => UDT( A() )

Dim As boolean success => TRUE

For i As Integer = 0 To 10
    For j As Integer = 0 To 10 
        For k As Integer = 0 To 10
            If Not A(i, j,k)=V[i][j][k] Then
                success = FALSE
                Exit For
            End If
        Next k 
    Next j
Next i

? success
Sleep 
My last puzzle still awaits.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

The above proposal don't work if array elements are not all null.
Try with for example:

Code: Select all

Dim As Integer   A(10,10,10)
For i As Integer = 0 To 10
  For j As Integer = 0 To 10
    For k As Integer = 0 To 10
        A(i, j, k) = Rnd() * 1000
        Print A(i, j, k)
    Next k
  Next j
Next i
Print
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Post by Tourist Trap »

dodicat wrote: My last puzzle still awaits.
I for sure will be late on the puzzles until next hollydays! But I keep watching them with a sneaky eye ;) (oups I dont know what sneaky means, but it sounds well)

About those arrays; what about something like that? Would it be on the right path?

Code: Select all

type T
	declare operator cast() as string ptr ptr ptr
		as string	_array(any, any, any)
end type
operator T.cast() as string ptr ptr ptr
	dim as string ptr ptr ptr	ret
	ret[uBound(THIS._array, 1)][uBound(THIS._array, 2)][uBound(THIS._array, 3)]	=  _ 
				THIS._array( uBound(THIS._array, 1), uBound(THIS._array, 2), uBound(THIS._array, 3) )
	'
	return ret
end operator
Damn, this next code works but is still uggly with its cast(integer ptr ptr....). Missing a slight touch.

Code: Select all

type T
	declare operator cast() as integer ptr ptr
		as integer ptr ptr	_i
		as integer			_array(any, any)
end type
operator T.cast() as integer ptr ptr
	THIS._i = new integer ptr
	THIS._i[uBound(THIS._array, 1)][uBound(THIS._array, 2)]	=  _ 
			THIS._array(uBound(THIS._array, 1), uBound(THIS._array, 2))
	'
	return THIS._i
end operator

dim as T v
redim as integer v._array(1, 2)
v._array(1, 2) = 9999999

? cast(integer ptr ptr, v)[1][2]

sleep
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

1)
@Tourist Trap,
Your last code above does not work and crashes on my PC:

Code: Select all

type T
   declare operator cast() as integer ptr ptr
      as integer ptr ptr   _i
      as integer         _array(any, any)
end type
operator T.cast() as integer ptr ptr
   THIS._i = new integer ptr
   THIS._i[uBound(THIS._array, 1)][uBound(THIS._array, 2)]   =  _
         THIS._array(uBound(THIS._array, 1), uBound(THIS._array, 2))
   '
   return THIS._i
end operator

dim as T v
redim as integer v._array(1, 2)
for i as integer = 0 to 1
   for j as integer = 0 to 2
      v._array(i, j) = i * 10 + j
   next j
next i

for i as integer = 0 to 1
   for j as integer = 0 to 2
      ? cast(integer ptr ptr, v)[i][j],
   next j
   ?
next i

sleep
In addition, the 'Cast' operator must not be used as first operator because its return as pointer needs an explicit call with the 'Cast' keyword (not the wished syntax).


2)
One raw solution for evaluating the syntax
v[j][k]...
is that calls an operator '[]' which returns a Ptr Ptr ..., and that the next indexes ([j], [k], ...) correspond to successive dereferencings.

- For a two-dimensional array, the code is simple:

Code: Select all

type T
   declare operator [] (byval index as integer) as integer ptr
      as integer _array(any, any)
end type
operator T.[] (byval index as integer) as integer ptr
   return @THIS._array(index, 0)
end operator

dim as T v
redim as integer v._array(1, 2)
for i as integer = 0 to 1
   for j as integer = 0 to 2
      v._array(i, j) = i * 10 + j
   next j
next i

for i as integer = 0 to 1
   for j as integer = 0 to 2
      ? v[i][j],
   next j
   ?
next i

sleep
- For a three-dimensional array, the code is a little more complex because a one-dimensional pointer array must be constructed:

Code: Select all

type T
   declare operator [] (byval index as integer) as integer ptr ptr
      as integer _array(any, any, any)
      as integer ptr _p(any)
end type
operator T.[] (byval index as integer) as integer ptr ptr
   redim this._p(ubound(this._array, 2))
   for i as integer = 0 to ubound(this._array, 2)
      this._p(i) = @this._array(index, i, 0)
   next i
   return @this._p(0)
end operator

dim as T v
redim as integer v._array(1, 2, 3)
for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         v._array(i, j, k) = i * 100 + j * 10 + k
      next k
   next j
next i

for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         ? v[i][j][k],
      next k
      ?
   next j
   ?
next i

sleep
- For a 'n'-dimensional array (with n>3), a pointer arrays structure from one-dimensional to 'n-2'-dimensional arrays, more and more complex should be constructed!
Example for n = 4:

Code: Select all

type T
   declare operator [] (byval index as integer) as integer ptr ptr ptr
      as integer _array(any, any, any, any)
      as integer ptr _p1(any, any)
      as integer ptr ptr _p2(any)
end type
operator T.[] (byval index as integer) as integer ptr ptr ptr
   redim this._p1(ubound(this._array,2), ubound(this._array,3))
   redim this._p2(ubound(this._array, 2))
   for i as integer = 0 to ubound(this._array, 2)
      this._p2(i) = @this._p1(i, 0)
      for j as integer = 0 to ubound(this._array, 3)
        this._p1(i, j) = @this._array(index, i, j, 0)
      next j
   next i
   return @this._p2(0)
end operator

dim as T v
redim as integer v._array(1, 2, 3, 4)
for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         for l as integer = 0 to 4
            v._array(i, j, k, l) = i * 1000 + j * 100 + k * 10 + l
         next l
      next k
   next j
next i

for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         for l as integer = 0 to 4
            ? v[i][j][k][l],
         next l
         ?
      next k
      ?
   next j
   ?
next i

sleep
3)
Instead of using a pointer array structure more and more complex:
- For a 'n'-dimensional array, my preferred solution uses only 'n-1' variables corresponding to the memorization of the first 'n-1' indexes before outputting the requested array value.
- 'n' operators '[]' are called successively, each memorizing its passed index before referring to the next operator, and the last operator applying all memorized indexes plus its own passed index, for accessing the requested value of array.
- None pointer used!



[edit]
- Added example for n = 4.
Last edited by fxm on May 19, 2017 8:25, edited 3 times in total.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

fxm wrote:Instead of using a pointer array structure more and more complex:
- For a 'n'-dimensional array, my preferred solution uses only 'n-1' variables corresponding to the memorization of the first 'n-1' indexes before outputting the requested array value.
- 'n' operators '[]' are called successively, each memorizing its passed index before referring to the next operator, and the last operator applying all memorized indexes plus its own passed index, for accessing the requested value of array.
- None pointer used!
My analysis:
- The 'n' operators '[]' must be distinct, therefore in 'n' different Types.
- The 'n-1' memorized indexes must be accessible from any Type.
- Each operator '[]' return must allow to chain with the next operator '[]', called on a reference to the same object (to can access all memorized indexes).

All this evokes me a structure of inheritance:
- Each Type has its own operator '[]'.
- Each operator '[]' (except the last) memorizes the passed index and returns a base-type reference of the object on which it has been called.
- So the different operators '[]' are successively called from down to up in the inheritance hierarchy.
- With all previously memorized indexes and its own passed index, the last operator '[]' returns the value of the requested array element.
- All the operators '[]' return by reference in order to can also change any element value of the array from that syntax.

My preferred proposal for the Tourist Trap's challenge:

Code: Select all

Type UDT0
  Dim As Integer array(Any, Any, Any)
End Type

Type UDT1 Extends UDT0
  Dim As Integer i, j
  Declare Operator [] (Byval index As Integer) Byref As Integer
End Type
Operator UDT1.[] (Byval index As Integer) Byref As Integer
  Return This.array(i, j, index)
End Operator

Type UDT2 Extends UDT1
  Declare Operator [] (Byval index As Integer) Byref As UDT1
End Type
Operator UDT2.[] (Byval index As Integer) Byref As UDT1
  j = index
  Return This
End Operator

Type UDT Extends UDT2
  Declare Operator [] (Byval index As Integer) Byref As UDT2
End Type
Operator UDT.[] (Byval index As Integer) Byref As UDT2
  i = index
  Return This
End Operator

dim as UDT v
redim as integer v.array(1, 2, 3)
for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         v.array(i, j, k) = i * 100 + j * 10 + k
      next k
   next j
next i

for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         ? v[i][j][k],
      next k
      ?
   next j
   ?
next i

sleep
Last edited by fxm on May 16, 2017 22:01, edited 2 times in total.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Post by Tourist Trap »

Variation on the very clever solution of fxm. Just more balanced (variables are distributed to each level) in order to make it easier to generalize mechanically. Maybe it's wrong, but it seems to work and it's slightly easier to generalize in this form, at least to me.

Code: Select all

Type UDT0
  Dim As Integer array(Any, Any, Any)
end type

Type UDT1 Extends UDT0
  Dim As Integer i, j
  Declare Operator [] (Byval index As Integer) Byref As Integer
End Type
Operator UDT1.[] (Byval index As Integer) Byref As Integer
  Return This.array(i, j, index)
End Operator

Type UDT2 Extends UDT1
  Dim As Integer j
  Declare Operator [] (Byval index As Integer) Byref As UDT1
End Type
Operator UDT2.[] (Byval index As Integer) Byref As UDT1
  Cast(UDT1, This).j = index
  Return Cast(UDT1, This)
End Operator

Type UDT3 Extends UDT2
  Declare Operator [] (Byval index As Integer) Byref As UDT2
End Type
Operator UDT3.[] (Byval index As Integer) Byref As UDT2
  Cast(UDT2, This).i = index
  Return Cast(UDT2, This)
End Operator


'------------------------------

dim as UDT3 v
redim as integer v.array(1, 2, 3)
for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         v[i][j][k] = i * 100 + j * 10 + k
      next k
   next j
next i

for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         ? v[i][j][k]; 
      next k
      ?
   next j
   ?
next i

sleep

fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

The syntaxes:
Cast(UDT1, This).j = index
and
Cast(UDT2, This).i = index
may be replaced by more lightweight syntaxes:
Base.j = index
and
Base.i = index

I would add 'Dim As Integer i' in the Type UDT3.

We can also suppress the 'Cast' instruction in the two operators '[]' (the returns are already implicitly "cast" thanks to the return type declaration).

Code: Select all

Type UDT0
  Dim As Integer array(Any, Any, Any)
end type

Type UDT1 Extends UDT0
  Dim As Integer i, j
  Declare Operator [] (Byval index As Integer) Byref As Integer
End Type
Operator UDT1.[] (Byval index As Integer) Byref As Integer
  Return This.array(i, j, index)
End Operator

Type UDT2 Extends UDT1
  Dim As Integer j
  Declare Operator [] (Byval index As Integer) Byref As UDT1
End Type
Operator UDT2.[] (Byval index As Integer) Byref As UDT1
  Base.j = index
  Return This
End Operator

Type UDT3 Extends UDT2
  Dim As Integer i
  Declare Operator [] (Byval index As Integer) Byref As UDT2
End Type
Operator UDT3.[] (Byval index As Integer) Byref As UDT2
  Base.i = index
  Return This
End Operator


'------------------------------

dim as UDT3 v
redim as integer v.array(1, 2, 3)
for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         v[i][j][k] = i * 100 + j * 10 + k
      next k
   next j
next i

for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         ? v[i][j][k];
      next k
      ?
   next j
   ?
next i

sleep

Last edited by fxm on Sep 02, 2017 20:14, edited 1 time in total.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: FreeBASIC syntax challenge games

Post by Tourist Trap »

fxm wrote:

Code: Select all

Type UDT0
  Dim As Integer array(Any, Any, Any)
end type

Type UDT1 Extends UDT0
  Dim As Integer i, j
  Declare Operator [] (Byval index As Integer) Byref As Integer
End Type
Operator UDT1.[] (Byval index As Integer) Byref As Integer
  Return This.array(i, j, index)
End Operator

Type UDT2 Extends UDT1
  Dim As Integer j
  Declare Operator [] (Byval index As Integer) Byref As UDT1
End Type
Operator UDT2.[] (Byval index As Integer) Byref As UDT1
  Base.j = index
  Return This
End Operator

Type UDT3 Extends UDT2
  Dim As Integer i
  Declare Operator [] (Byval index As Integer) Byref As UDT2
End Type
Operator UDT3.[] (Byval index As Integer) Byref As UDT2
  Base.i = index
  Return This
End Operator


'------------------------------

dim as UDT3 v
redim as integer v.array(1, 2, 3)
for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         v[i][j][k] = i * 100 + j * 10 + k
      next k
   next j
next i

for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         ? v[i][j][k];
      next k
      ?
   next j
   ?
next i

sleep

Or,

Code: Select all

Type UDT0
  Dim As Integer array(Any, Any, Any)
End Type

Type UDT1 Extends UDT0
  Dim As Integer i, j, k
  Declare Operator [] (Byval index As Integer) Byref As Integer
End Type
Operator UDT1.[] (Byval index As Integer) Byref As Integer
  This.k = index
  Return This.array(i, j, k)
End Operator

Type UDT2 Extends UDT1
  Dim As Integer i, j
  Declare Operator [] (Byval index As Integer) Byref As UDT1
End Type
Operator UDT2.[] (Byval index As Integer) Byref As UDT1
  Base.j = index
  Return This
End Operator

Type UDT3 Extends UDT2
  Dim As Integer i
  Declare Operator [] (Byval index As Integer) Byref As UDT2
End Type
Operator UDT3.[] (Byval index As Integer) Byref As UDT2
  Base.Base.i = index
  Return This
End Operator





'------------------------------

dim as UDT3 v
redim as integer v.array(1, 2, 3)
for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         v[i][j][k] = i * 100 + j * 10 + k
      next k
   next j
next i

for i as integer = 0 to 1
   for j as integer = 0 to 2
      for k as integer = 0 to 3
         ? v[i][j][k];
      next k
      ?
   next j
   ?
next i

sleep

fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Enigma #18, force 1-2 (for 64-bit, compile with '-exx')
(see also "Preparation to enigma #18" at http://www.freebasic.net/forum/viewtopi ... 36#p231936)
(easier for those who remember two of my posts that I temporarily censored, but such a code is better here)

By only adding three instructions (three simple lines inside the dedicated zone for line insertion ), make so that program correctly displays the elements of the dynaix 'array2()' array which must be a copy of the dynamic 'array1()' array before destruction:
- Copy of a dynamic array in another dynamic array, in a global way (without sizing the array and looping on the array elements).

Code: Select all

Dim As Integer array1()
Redim array1(1 To 5, 1 To 9)
For I As Integer = 1 To 5
  For J As Integer = 1 To 9
    array1(I, J) = I*10 + J
  Next J
Next I

Dim As Integer array2()

Type MyArray
   As Integer array(Any, Any)
End Type
Function arrayDescriptorPtrFunction (Byval p As Any Ptr) As Any Ptr
  Return p
End function
#Define arrayDescriptorPtr(array) Cast(Function (() As Typeof((array))) As Any Ptr, @arrayDescriptorPtrFunction)(array())

'---- Zone beginning of code insertion ----



'------ Zone ending of code insertion -----

Erase array1
For I As Integer = 1 To 5
  For J As Integer = 1 To 9
    Print array2(I, J);
  Next J
  Print
Next I
Print

Sleep
Last edited by fxm on May 19, 2017 15:47, edited 3 times in total.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

This seems to work with two lines.

Code: Select all

Dim As Integer array1()
Redim array1(1 To 5, 1 To 9)
For I As Integer = 1 To 5
  For J As Integer = 1 To 9
    array1(I, J) = I*10 + J
  Next J
Next I

Dim As Integer array2()

Type MyArray
   As Integer array(Any, Any)
End Type
Function arrayDescriptorPtrFunction (Byval p As Any Ptr) As Any Ptr
  Return p
End function
#Define arrayDescriptorPtr(array) Cast(Function (() As Typeof((array))) As Any Ptr, @arrayDescriptorPtrFunction)(array())

'---- Zone beginning of code insertion ----
Dim Byref As MyArray a  = *Cptr(MyArray Ptr, arrayDescriptorPtr(array1))
 *Cptr(MyArray Ptr, arrayDescriptorPtr(array2))=a
'------ Zone ending of code insertion -----

Erase array1
For I As Integer = 1 To 5
  For J As Integer = 1 To 9
    Print array2(I, J);
  Next J
  Print
Next I
Print

Sleep 
I get no warnings (fbide).
But I maybe should get some sort of incompatibility warning somewhere??

It can be done in three lines via crt.bi and memcpy.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Yes, well found!

I had for my own broken down this problem into 3 distinct steps (perhaps simpler to understand):

Code: Select all

'---- Zone beginning of code insertion ----
Dim Byref As MyArray a1 = *Cptr(MyArray Ptr, arrayDescriptorPtr(array1))
Dim Byref As MyArray a2 = *Cptr(MyArray Ptr, arrayDescriptorPtr(array2))
a2 = a1
'------ Zone ending of code insertion -----
You have removed one step:

Code: Select all

'---- Zone beginning of code insertion ----
Dim Byref As MyArray a  = *Cptr(MyArray Ptr, arrayDescriptorPtr(array1))
*Cptr(MyArray Ptr, arrayDescriptorPtr(array2)) = a
'------ Zone ending of code insertion -----
But considering our two solutions, we can do it in one step (one line):

Code: Select all

'---- Zone beginning of code insertion ----
*Cptr(MyArray Ptr, arrayDescriptorPtr(array2)) = *Cptr(MyArray Ptr, arrayDescriptorPtr(array1))
'------ Zone ending of code insertion -----
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC syntax challenge games

Post by fxm »

Enigma #19, force 1 (a simple challenge for not overheating the brain)

How to change the 2 UDT overloaded constructors (in type defining delimited by beginning / ending zone) so that only one constructor is declared and defined, playing either the default-construction role or the copy-construction role depending on calling mode only (same displaying as the initial code without program crashing):

Code: Select all

'------------------ zone beginning of modification -------------------
Type UDT
  Public:
    Declare Constructor ()
    Declare Constructor (Byref As UDT)
  Private:
    Const As String dcs = "  Instance created by default-construction."
    Const As String ccs = "  Instance created by copy-construction."
    Dim As Integer dummy
End Type

Constructor UDT ()
  Print dcs
End Constructor

Constructor UDT (Byref u As UDT)
  Print ccs
End Constructor
'-------------------- zone ending of modification --------------------

Print "Begin of challenge:"
Dim As UDT u1 = UDT()    ' To highlight the default-constructor's call, explicit call but can be reduced to: 'Dim As UDT u1'
Dim As UDT u2 = UDT(u1)  ' To highlight the copy-constructor's call, explicit call but can be reduced to: 'Dim As UDT u2 = u1'
Print "End of challenge."

Sleep
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: FreeBASIC syntax challenge games

Post by dodicat »

I'll try this.

Code: Select all

'------------------ zone beginning of modification -------------------
Type UDT
  Public:
    static as udt ptr  p
    Declare Constructor (Byref As UDT=*p)
  Private:
    Const As String dcs = "  Instance created by default-construction."
    Const As String ccs = "  Instance created by copy-construction."
    Dim As  Integer dummy
End Type
dim as udt ptr udt.p


Constructor UDT (Byref u As UDT)
  p=@u
  Print iif(u.p,ccs,dcs)
  p=dummy
End Constructor
'-------------------- zone ending of modification --------------------

Print "Begin of challenge:"
Dim As UDT u1 = UDT()    ' To highlight the default-constructor's call, explicit call but can be reduced to: 'Dim As UDT u1'
Dim As UDT u2 = UDT(u1)  ' To highlight the copy-constructor's call, explicit call but can be reduced to: 'Dim As UDT u2 = u1'
Print "End of challenge."


Sleep
 
Seems to work both ways to dim u1 and u2.
Post Reply