Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exercise idea: Golden ratio base / Phinary #885

Open
sshine opened this issue Dec 12, 2019 · 0 comments
Open

Exercise idea: Golden ratio base / Phinary #885

sshine opened this issue Dec 12, 2019 · 0 comments

Comments

@sshine
Copy link
Contributor

sshine commented Dec 12, 2019

(This exercise idea was proposed by someone following the Haskell track. I tried to push them into submitting a pull request for a new exercise, but instead they proposed one of their own, so I'm keeping their idea here.)

The golden ratio base (base-φ) has some interesting properties. One of them is that even though φ is irrational, all non-negative integers have a unique representation as a terminating (finite) base-φ expansion. If the exercise were to define toPhinary :: Natural -> Phinary (Numeric.Natural), the algorithm to apply might be this one. There are two rules to keep in mind, φ × φ = 1 + φ and 1 / φ = −1 + φ.


An example: Representing decimal x = 7 in base-φ:

  1. The highest power of φ ≤ 7: φ⁴ = 2 + 3φ ≈ 6.854... ≤ 7.

    (φ⁴ = φ² × φ² = (1 + φ)² = 1 + φ² + 2φ = 1 + (1 + φ) + 2φ = 2 + 3φ)

    The result so far being 10000.0000...φ

  2. Subtracting this from 7, we have 7 - (2 + 3φ) = 5 - 3φ ≈ 0.146...

  3. The highest power of φ ≤ 5 - 3φ: φ-4 = 5 - 3φ ≈ 0.146...

    (φ-4 = ... = 5 - 3φ)

    The result so far being 10000.0001...φ

  4. Subtracting 5 - 3φ from 5 - 3φ, we have 0, so this is the final representation (confirmed).


I'll copy-paste a note from the exercise's benefactor wrt. precision:

As people will probably apply the algorithm given in this section, they can try to use floating point operations for finding the largest suitable power of phi at step 2. This is not good, because it's imprecise. To prevent this, there must be numbers with large enough negative powers in the test set, so that imprecise methods don't work (that's why the type is Integer). These numbers should probably be randomly generated. Then, there is a challenge for creators of the tests: if we generate a large integer, how do we know if it has a large negative power of phi? (It seems to be so; but maybe not always?) On the other hand, if we generate two sequences of zeros and ones (before and after the decimal dot, the latter being large enough), how do we know it's an integer? Then, this additional task can be useful: given a "fractional" part of Phinary, find the smallest "integer" part that makes the result integer. And vice versa, just for fun.

In the inverse function (Phinary -> Maybe Integer), both integer and fractional numbers should be given to prevent the usage of approximate methods.


There are quite a lot of other potential exercises within this domain, e.g. defining

  • fromPhinary :: Phinary -> Maybe Integer
  • normalize :: Phinary -> Phinary
  • isNormalized :: Phinary -> Bool

See standard form.

But perhaps toPhinary :: Natural -> Phinary is enough already.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant