## Codeabbey -- dice and weighted sum

Oforth examples. Feel free to post your own code.

### Codeabbey -- dice and weighted sum

I did some quick codeabbey again, and the first one was so simple I didn't feel that it needs a post for itself, so I decided to group it together with a much more interesting weighted sum of digits

dice

input are here some random floats between 0 and 1, and one has to make dice numbers 1-6 out of them
Code: Select all
`6 Constant new: sides: getLn { System.Console askln }                    // ( <stdin> -- string ): getNumber { getLn asInteger }                     // ( <stdin> -- integer ): pprint { apply(#.) printcr }                      // ( [a] -- <stdout> ): getInput { [] getNumber #[ getLn + ] times }      // ( <stdin> -- [string] ): number->dice { sides * floor 1 + }                // ( float -- int(1-6) )getInput map( #[ asFloat number->dice ] ) pprint`

Pretty standard stuff, and not very interesting really

Weighted sum

This one is a lot more interesting, we get in a list of numbers, and have to make a weighted sum of the digits of each one. eg. 21 = 2*1 + 1*2 = 6

Code: Select all
`48 Constant new: ASCII0: getLn { System.Console askln }                    // ( <stdin> -- string ): getNumber { getLn asInteger }                     // ( <stdin> -- integer ): pprint { apply(#.) printcr }                      // ( [a] -- <stdout> ): getInput { [] getNumber getLn words }      // ( <stdin> -- [string] ): getDigits { map( #[ asInteger ASCII0 - ])}        // ( String -- [integer] ): ws { dup size seq zip map( #[ reduce(#*)]) sum }  // ( [integer] -- weighted-sum )getInput map( #[ getDigits ws]) pprint`

I don't really know a better way to get out the digits of a number string, but this works.
I really like how concise ws turned out just that the map reduce looks a bit ugly with all the parenthesis, brackets and hashes
sotolf

Posts: 55
Joined: 30 Jul 2015 15:53

### Re: Codeabbey -- dice and weighted sum

Hi,

1) To get a digit from a char, you can use #asDigit

Code: Select all
`: getDigits { map(#asDigit)}        // ( String -- [integer] )`

or, without parenthesis :

Code: Select all
`: getDigits { #asDigit swap map }   // ( String -- [integer] )`

2) To calculate product of a collection, #prod is already defined (like #sum) :

Code: Select all
`: ws { dup size seq zip map(#prod) sum }      // ( [integer] -- weighted-sum )`

or, with a local variable and without parenthesis :

Code: Select all
`: ws(l) { #prod l dup size seq zip map sum }      // ( [integer] -- weighted-sum )`

or, without local variable and without parenthesis :

Code: Select all
`: ws { #prod swap dup size seq zip map sum }     // ( [integer] -- weighted-sum )`

Here, I would opt for the first one. For the 2 last, I think #prod is too far from #map to understand quickly that it is map's parameter.

You can also use #zipWith :
Code: Select all
`: ws { dup size seq zipWith(#*) sum }      // ( [integer] -- weighted-sum )`

Or directly calculate the weighted sum of the string :

Code: Select all
`: ws { dup size seq swap zipWith(#[ asDigit * ]) sum }    // ( aString -- n )`

Many ways ...

Franck
Franck

Posts: 171
Joined: 29 Oct 2014 19:01

### Re: Codeabbey -- dice and weighted sum

Thank you! That helps a lot, I really like the zipWith version, that's clean, and still not so hard to understand
sotolf

Posts: 55
Joined: 30 Jul 2015 15:53

### Re: Codeabbey -- dice and weighted sum

Yes, I agree, the zipWith version is cleaner. And faster because you don't need to create an intermediary map.

btw, #zip is written using #zipWith :

Code: Select all
`Indexable method: zip { #[ [ , ] ] self zipWith }`
Franck

Posts: 171
Joined: 29 Oct 2014 19:01