LOGO-L> Inverting Numbers 
Author Message
 LOGO-L> Inverting Numbers

Hello everybody,

I'd like to introduce you to some rather interesting examples
proposed by teachers S.Gorlitskaya and I.Kuznetsova from
St.Petersburg and posted in Russian newspaper "Informatics".
I think these examples are in time for our "word games".

Here are  the first ones.

The main procedure reads a number as a word.
how_digits? counts the "sensible" digits of the number.
Then invert calls inverty, which returns the  inverted number.

I've slightly changed the initial code, and if there is something
wrong here, it's my fault.
---------------------------------
to how_digits? :n
;counts the "sensible"(?) digits of the number
if emptyp :n [op 0]
ifelse not (first :n)=0[op count :n]~
                       [op how_digits? butfirst :n]
end

to invert :n
op inverty how_digits? :n :n 0
end

to inverty :k :n :new_n
; inverts the initial number :n and returnes it as :new_n
if :k=0 [op :new_n]
op inverty :k-1 int :n/10 10*:new_n+remainder :n 10  
end

to main
pr [input any number, it may begin with 0  ==>]
pr  invert rw
end
------------------------------------------------------

Regards,
Olga.
---------------------------------------------------------------





Tue, 07 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers

Quote:

> Hello everybody,

> I'd like to introduce you to some rather interesting examples
> proposed by teachers S.Gorlitskaya and I.Kuznetsova from
> St.Petersburg and posted in Russian newspaper "Informatics".
> I think these examples are in time for our "word games".

> Here are  the first ones.

> The main procedure reads a number as a word.
> how_digits? counts the "sensible" digits of the number.
> Then invert calls inverty, which returns the  inverted number.

> I've slightly changed the initial code, and if there is something
> wrong here, it's my fault.
> ---------------------------------
> to how_digits? :n
> ;counts the "sensible"(?) digits of the number
> if emptyp :n [op 0]
> ifelse not (first :n)=0[op count :n]~
>                        [op how_digits? butfirst :n]
> end

> to invert :n
> op inverty how_digits? :n :n 0
> end

> to inverty :k :n :new_n
> ; inverts the initial number :n and returnes it as :new_n
> if :k=0 [op :new_n]
> op inverty :k-1 int :n/10 10*:new_n+remainder :n 10
> end

> to main
> pr [input any number, it may begin with 0  ==>]
> pr  invert rw
> end
> ------------------------------------------------------

Hello Olga,

You can reverse ANY word, not only numbers, by the following function:

=================================
to reverse :wrd
if 2>count :wrd[op :wrd]
op word last :wrd reverse bl :wrd
end
=================================

Try it by PR REVERSE 1997 or PR REVERSE "H2SO4

Regards...

[[Yehuda]]

---------------------------------------------------------------





Tue, 07 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers

Quote:
> Date:          Fri, 20 Jun 1997 18:50:17 +0300




> Subject:       Re: LOGO-L> Inverting Numbers

> > to how_digits? :n
> > ;counts the "sensible"(?) digits of the number
> > if emptyp :n [op 0]
> > ifelse not (first :n)=0[op count :n]~
> >                        [op how_digits? butfirst :n]
> > end

> > to invert :n
> > op inverty how_digits? :n :n 0
> > end

> > to inverty :k :n :new_n
> > ; inverts the initial number :n and returnes it as :new_n
> > if :k=0 [op :new_n]
> > op inverty :k-1 int :n/10 10*:new_n+remainder :n 10
> > end

> > to main
> > pr [input any number, it may begin with 0  ==>]
> > pr  invert rw
> > end
> > ------------------------------------------------------

> Hello Olga,

> You can reverse ANY word, not only numbers, by the following function:

> =================================
> to reverse :wrd
> if 2>count :wrd[op :wrd]
> op word last :wrd reverse bl :wrd
> end
> =================================

> Try it by PR REVERSE 1997 or PR REVERSE "H2SO4

But if I take 900 as an input, I'll get 009 and I don't think this
number looks nice.

There is another thing there. It seems my experience of teaching
Pascal began to play bad tricks with me. In Pascal program all the
variables are to be described in the very beginning of the program.
And then you can't summaries variables a and b if a defined as a char
and b - as a number, or if they both defined as a char type. But, in
Logo it proves to be not forbidden. The following lines works
wonderfully:
make "a "1
make "b 2
show :a+:b
And you'll get 3!

I was going to share some tasks which use the described above process
of number digits definition. But it seems to be much easier to define
them looking at a number as it being just a word.

There is something I don't like. May be, it's just hard to get rid of
the old programming heritage :-). But when we work with the
senior students with spreadsheets (Excel, for example), the cells
there could be also taken as a variables. And "1 or "2 there mean
text and the attempt to summaries them will draw to an error. And the
students won't do that if they are acquainted with the variables
types.  

So, sorry for all this mess. Though, may be it's just useful
for students to compare:

Let "N be a number, then

last :n = remainder :n 10
bl :n    = int :n/10    and so on.

Regards,
Olga.

---------------------------------------------------------------





Fri, 10 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers

Quote:
>But if I take 900 as an input, I'll get 009 and I don't think this
>number looks nice.

Try PRINT 0 + REVERSE 900

Once you do any arithmetic on the word (even adding zero) it turns
back into a number inside Logo.

Quote:
>There is another thing there. It seems my experience of teaching
>Pascal began to play bad tricks with me. In Pascal program all the
>variables are to be described in the very beginning of the program.
>And then you can't summaries variables a and b if a defined as a char
>and b - as a number, or if they both defined as a char type. [...]
>There is something I don't like. May be, it's just hard to get rid of
>the old programming heritage :-). But when we work with the
>senior students with spreadsheets (Excel, for example), the cells
>there could be also taken as a variables. And "1 or "2 there mean
>text and the attempt to summaries them will draw to an error. And the
>students won't do that if they are acquainted with the variables
>types.  

There are still fierce arguments between people who like typed variables
and people who don't.  Languages designed for compilation of fast-running
programs tend to have typed variables because that makes it easier for
the compiler; if the compiler knows ahead of time that you're adding two
integers it can just use an integer add instruction.  (It's not good
enough in Pascal, etc., to say "number"; you have to say integer or
real, because integer add and real add are two different machine language
instructions.)

But the trouble with declared variables is that often you have something
that's usually but not always a number.  My standard example is that you
want to write a program that lets the user type in an arbitrary number
of numbers and adds them up.  Now, how does the user tell the program
s/he doesn't have any more numbers to add?  In Logo I can say

        make "sum 0
        make "number readword
        while [numberp :number] [make "sum :sum+:number
                                 make "number readword]

and then the user can type a non-number, like DONE for example, to end
the calculation.  But in Pascal either you say "type 9999 when done",
which is really hideous, or else the programmer has to read what the
user types as text and convert it to a number explicitly, which is
also hideous.

Some languages, most notably ML, try for the best of both worlds by
having really smart compilers that can *infer* the type of a variable.
In other words, if all you ever do with a certain variable is arithmetic,
the compiler figures out that it must be a number, and so on.



Fri, 10 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers

Quote:

> > Date:          Fri, 20 Jun 1997 18:50:17 +0300




> > Subject:       Re: LOGO-L> Inverting Numbers


> > > to how_digits? :n
> > > ;counts the "sensible"(?) digits of the number
> > > if emptyp :n [op 0]
> > > ifelse not (first :n)=0[op count :n]~
> > >                        [op how_digits? butfirst :n]
> > > end

> > > to invert :n
> > > op inverty how_digits? :n :n 0
> > > end

> > > to inverty :k :n :new_n
> > > ; inverts the initial number :n and returnes it as :new_n
> > > if :k=0 [op :new_n]
> > > op inverty :k-1 int :n/10 10*:new_n+remainder :n 10
> > > end

> > > to main
> > > pr [input any number, it may begin with 0  ==>]
> > > pr  invert rw
> > > end
> > > ------------------------------------------------------

> > Hello Olga,

> > You can reverse ANY word, not only numbers, by the following function:

> > =================================
> > to reverse :wrd
> > if 2>count :wrd[op :wrd]
> > op word last :wrd reverse bl :wrd
> > end
> > =================================

> > Try it by PR REVERSE 1997 or PR REVERSE "H2SO4

> But if I take 900 as an input, I'll get 009 and I don't think this
> number looks nice.

Olga,

You might remember that 007 was the name of a really nice detective
(James Bond)... But "nice" is a relative virtue, not absolut.

My REVERSE function keeps the convention of:
         (REVERSE REVERSE someting) = something

while this convention isn't observed by your procedure.

If leading zeros are found disturbing, they can be easily removed by:
         PR INT REVERSE :NUM

Of course you can also write a function to remove leading zeros.

Best Regards...

[[Yehuda]]

---------------------------------------------------------------





Fri, 10 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers

Quote:

> There is another thing there. It seems my experience of teaching
> Pascal began to play bad tricks with me. In Pascal program all the
> variables are to be described in the very beginning of the program.
> And then you can't summaries variables a and b if a defined as a char
> and b - as a number, or if they both defined as a char type. But, in
> Logo it proves to be not forbidden. The following lines works
> wonderfully:
> make "a "1
> make "b 2
> show :a+:b
> And you'll get 3!

It's Logo doing "bad" tricks and Pascal that's doing things "good".
It's called Strict Type Checking and one of the reasons why Pascal
was done the way it was and why it was very popular.

The above code you listed should generate a bug because you usually do
not want to mix datatypes unless you explicity tell it you want to. It's
helping you to stay out of trouble. For example the code you wrote
above in many lauguages would give the ascii value of 1 plus 2 and the
answer would be "c :-). Which is correct 3 or "c. Pascal does not allow
you to be ambiguous, it's "Strict".

Quote:
> I was going to share some tasks which use the described above process
> of number digits definition. But it seems to be much easier to define
> them looking at a number as it being just a word.

> There is something I don't like. May be, it's just hard to get rid of
> the old programming heritage :-). But when we work with the
> senior students with spreadsheets (Excel, for example), the cells
> there could be also taken as a variables. And "1 or "2 there mean
> text and the attempt to summaries them will draw to an error. And the
> students won't do that if they are acquainted with the variables
> types.

> So, sorry for all this mess. Though, may be it's just useful
> for students to compare:

> Let "N be a number, then

> last :n = remainder :n 10
> bl :n    = int :n/10    and so on.

> Regards,
> Olga.

> ---------------------------------------------------------------




--
===============================================================

http://www.softronix.com/
The www page contains some very powerful educational software.
Our single most important investment is our kids.

---------------------------------------------------------------





Sat, 11 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers

Quote:
> Date:          Tue, 24 Jun 1997 00:46:14 -0400



> Subject:       Re: LOGO-L> Inverting Numbers


>> The following lines works wonderfully:
> > make "a "1
> > make "b 2
> > show :a+:b
> > And you'll get 3!

> The above code you listed should generate a bug because you usually do
> not want to mix datatypes unless you explicity tell it you want to. It's
> helping you to stay out of trouble. For example the code you wrote
> above in many lauguages would give the ascii value of 1 plus 2 and the
> answer would be "c :-). Which is correct 3 or "c. Pascal does not allow
> you to be ambiguous, it's "Strict".

... And I prefer to deal with a number as a number.

Here is a problem which might be interesting I think. It is based on
the definition of the digits of an integer number.

Find all "happy" 6-digital (? sorry if the terminology isn't
correct) integers. The integer is called "happy" if the sum of the
first three digits is equal to the sum of the last three ones.

My proposal for a solution:

to happy
ct
for [i 100000 999999][if happy.test :i [pr :i]]
end

to happy.test :i
localmake "s1 0
localmake "s2 0
repeat 3 [make "s1 :s1+remainder :i 10
          make "i int :i/10]
repeat 3 [make "s2 :s2+remainder :i 10
          make "i int :i/10]
op :s1=:s2
end

A lot of "makes" ... Sorry. But note, some of them are local. :-)
I'm sure, much better solutions may be found.

Regards,
Olga.
---------------------------------------------------------------





Sun, 12 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers

Quote:
>> > make "a "1
>> > make "b 2
>> > show :a+:b
>> > And you'll get 3!
>> The above code you listed should generate a bug because you usually do
>> not want to mix datatypes unless you explicity tell it you want to.

So who is mixing datatypes?  Logo only has two datatypes: words and lists!
All the above are words.

Quote:
>> It's
>> helping you to stay out of trouble. For example the code you wrote
>> above in many lauguages would give the ascii value of 1 plus 2 and the
>> answer would be "c :-).

Logo doesn't give you the ASCII value unless you ask for it.  Anyhow, "many
languages" do things in a way that is natural for computers, not for human
beings.  Logo tries to work more like people.

Quote:
>Find all "happy" 6-digital (? sorry if the terminology isn't
>correct) integers. The integer is called "happy" if the sum of the
>first three digits is equal to the sum of the last three ones.
>My proposal for a solution:
>to happy
>ct
>for [i 100000 999999][if happy.test :i [pr :i]]
>end
>to happy.test :i
>localmake "s1 0
>localmake "s2 0
>repeat 3 [make "s1 :s1+remainder :i 10
>          make "i int :i/10]
>repeat 3 [make "s2 :s2+remainder :i 10
>          make "i int :i/10]
>op :s1=:s2
>end

That's about the way I would do it in C.  I think the nature of Logo
suggests a different approach, though.  Try this...

to happy.test :i
   op equalp (sum first :i first bf :i first bf bf :i) ~
             (sum last :i last bl :i last bl bl :i)
end

--
   Tony Belding
   http://hamilton.htcomp.net/tbelding/

---------------------------------------------------------------





Sun, 12 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers

Quote:




> Date:          Wed, 25 Jun 1997 07:29:37 -0600
> Organization:  Team AMIGA
> Subject:       Re: LOGO-L> Numbers or Words?
> >My proposal for a solution:

> >to happy
> >ct
> >for [i 100000 999999][if happy.test :i [pr :i]]
> >end

> >to happy.test :i
> >localmake "s1 0
> >localmake "s2 0
> >repeat 3 [make "s1 :s1+remainder :i 10
> >          make "i int :i/10]
> >repeat 3 [make "s2 :s2+remainder :i 10
> >          make "i int :i/10]
> >op :s1=:s2
> >end

> That's about the way I would do it in C.  I think the nature of Logo
> suggests a different approach, though.  Try this...

> to happy.test :i
>    op equalp (sum first :i first bf :i first bf bf :i) ~
>              (sum last :i last bl :i last bl bl :i)
> end

> --
>    Tony Belding
>    http://hamilton.htcomp.net/tbelding/

Oh, is it really more natural? But I'd like my students to know that
number is a number, not just a word, and it's components (digits)
have some special qualities. And I want them to introduce to the
position system of numeration (?) and I'm going to do it with the
help of Logo.

Regards,
Olga.
---------------------------------------------------------------





Sun, 12 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers


Quote:
>> to happy.test :i
>>    op equalp (sum first :i first bf :i first bf bf :i) ~
>>              (sum last :i last bl :i last bl bl :i)
>> end
>Oh, is it really more natural?

I think it is more natural, based on the way you defined the problem.

Quote:
>But I'd like my students to know that
>number is a number, not just a word, and it's components (digits)
>have some special qualities. And I want them to introduce to the
>position system of numeration (?) and I'm going to do it with the
>help of Logo.

I'm not sure exactly what you mean by the position system of numeration.

However, I think it's useful to compare the two functions and see why they
give the same results -- and why my function would *not* work with anything
other than base-10 numbers.  :-)

In fact, consider this...  You can divide an integer in Logo by ten this way,
discarding the remainder:

   (print :num [ divided by ten equals ] butlast :num)

In C you can do something similar...

   printf("%d divided by two equals %d\n",num,num>>1);

But why does C divide by two instead of by ten?  It is only because C
considers integers to be base-two numbers instead of base-ten!

Some dialects of Logo can also do that.  This works in Berkeley Logo:

   (print :num [ divided by two equals ] ashift :num -1)

--
   Tony Belding
   http://hamilton.htcomp.net/tbelding/

---------------------------------------------------------------





Sun, 12 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers

Quote:

>to happy.test :i
>localmake "s1 0
>localmake "s2 0
>repeat 3 [make "s1 :s1+remainder :i 10
>          make "i int :i/10]
>repeat 3 [make "s2 :s2+remainder :i 10
>          make "i int :i/10]
>op :s1=:s2
>end

I can't resist...

to happy.test :i
localmake "s1 reduce "sum remainder :i 1000
localmake "s2 reduce "sum int quotient :i 1000
op :s1=:s2
end

Of course checking each of the million possibilities separately leads
to a lot of repeated checking of three-digit numbers.  Another approach
would be to notice that the smallest possible sum-of-digits for a
three digit number is zero, and the largest possible sum is 27 (for
the number 999).  So we could start by collecting all the three-digit
numbers into 28 buckets, then for each bucket, print all possible
pairings of numbers.

to happy
localmake "buckets (array 28 0)
for [i 0 999] [localmake "index reduce "sum :i
               setitem :index :buckets (fput :i (item :index :buckets))]
for [i 0 27] [localmake "values item :i :buckets
              foreach (crossmap [1000 * ?1 + ?2] :values :values) "print]
end

This version is much harder to understand; in the other version the
algorithm is obvious from the code.  This one would be really obscure
without the explanatory paragraph above it.  So I'm not sure this is
what I'd show students!

Also, this version doesn't print the results in numerical order.  If
that matters, you could make a big list of the results, sort the
list, and then print it.

This (as I'm sure Olga had in mind when proposing the problem in the
first place) is a nice example of treating a number both as a number
and as a string of digits, whichever is more appropriate to the
subtask at hand.



Sun, 12 Dec 1999 03:00:00 GMT  
 LOGO-L> Inverting Numbers

Quote:

> Of course checking each of the million possibilities separately leads
> to a lot of repeated checking of three-digit numbers.  Another approach
> would be to notice that the smallest possible sum-of-digits for a
> three digit number is zero, and the largest possible sum is 27 (for
> the number 999).  So we could start by collecting all the three-digit
> numbers into 28 buckets, then for each bucket, print all possible
> pairings of numbers.

Nice observation!  It can also be used to simply skip needless
iterations and print out the numbers directly:

to happy
local "firstsum    ;sum of first three digits
for [ firstthree 100 999 ] [

    ;(you could loop over middle digits here, if you want to
    ; do more than six digit numbers)

    make "firstsum sumdigits :firstthree
    for (list "i 0 min :firstsum 9) [
    for (list "j 0 min :firstsum - :i 9) [

        ;the below IF is annoying; with a little work on the two for loops
        ;above, I bet it could be removed

        if (:firstsum - :i - :j < 10) [
            print (word :firstthree :i :j :firstsum-:i-:j)
        ]
    ]]
]
end

to min :a :b
ifelse (:a < :b) [output :a] [output :b]
end

to sumdigits :num
    if ((count :num) = 1) [output :num]
    output (first :num)  +  (sumdigits butfirst :num)
end

This version starts producing output immediately, and it has the
advantage of requiring less memory.  It also prints them directly in
numerical order.

On the other hand, this version was probably harder to work out, and
it won't allow you a lot of conveniences that having them in a list
would give you; for instance, if you want to sort the numbers in a
different order, you have to rewrite the loops, which is easy to{*filter*}
up.

lex



Mon, 13 Dec 1999 03:00:00 GMT  
 
 [ 32 post ]  Go to page: [1] [2] [3]

 Relevant Pages 

1. LOGO-L> Numbers-->English translator

2. LOGO-L> Number Sculpturing

3. LOGO-L>GUIs versus functions (was: input of numbers)

4. LOGO-L> Mid-Value of Three Numbers

5. LOGO-L> Mid-Value of Three Numbers

6. LOGO-L>GUIs versus functions (was: input of numbers)

7. LOGO-L> re Input numbers

8. LOGO-L> Re:input of numbers

9. LOGO-L> middle number

10. LOGO-L> Mid Number

11. LOGO-L> ascii numbers

12. LOGO-L> Re: Question: Binary Numbers

 

 
Powered by phpBB® Forum Software