Hacker News new | past | comments | ask | show | jobs | submit login

The idea here is to get a smooth logarithmic division of each order of magnitude (power of 10). To get x steps that perfectly divide the order of magnitude, just use the xth root of 10 as your factor. In Ruby:

    def series(x, precision=2)
      root = 10 ** (1 / x.to_f)
      return x.times.map {|i| (root ** i).round(precision)}
    end

    > series(2)
    => [1.0, 3.16]
    > series(5)
    => [1.0, 1.58, 2.51, 3.98, 6.31]
    > series(10)
    => [1.0, 1.26, 1.58, 2.0, 2.51, 3.16, 3.98, 5.01, 6.31, 7.94]
And of course, if you want more aesthetically pleasing increments (like for axis markers on a logarithmic graph), just round each increment as desired. I usually find that the [1, 2, 5] series is sufficient.



That happens to be the series used for the Euro currency:

[0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500]


Yep, that's a good way to minimize both the number of denominations offered and the number of bills/coins needed to make change for a given amount of money.

The USD is close, too. Bills are in 1, 2, 5, although the $2 bill is rare. For some reason our coins are irregular, although people in my experience find all coins a bother.

The "ideal" set of 3 denominations would be 1, 2.15, and 4.64.


Is it at all surprising? Coins don't fit in wallets, represent small denominations, and are therefore not worth the trouble.


That's because the highest US coin in practice is $0.25—even though $1 coins exist, they are not widespread and overlap with the $1 bill.

Contrast with the Euro where the highest coin is €2 and bills start at €5.

Also prices tend to be inclusive of sales tax / VAT in Europe, so a €9.99 widget can be purchased with a €10 bill and you get 1 single €0.01 coin in change. Whereas your $9.99 widget will be $10.79 (at 7% tax), so you'll get 3 dimes and a nickel (4x the amount of change) assuming you handed over $11. Most likely, you had a $20 so you also get lots of $1 bills with your coins. :)


I tried using $1 coins for a while. I found then too bulky and heavy with zero advantage over paper.

I would only use them routinely if forced.

In some US stores they set prices so that the total is an even total after tax.


I actually found the contrary. 25 coins hold surprisingly well in a pocket, much easier than a thick set of 25-bills IMO.

25-Bills get wet with sweat and insulate your legs. I kinda prefer 25-coins over that.


I think most currency uses that. Dollars are a weird exception.


You don’t have to make it so complicated!

    : user@debian:~; python
    Python 2.7.3 (default, Mar 13 2014, 11:03:55) 
    [GCC 4.7.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import numpy as np
    >>> (10**(1+np.arange(24)/24.0)).reshape((2,3,4)).round()
    array([[[ 10.,  11.,  12.,  13.],
            [ 15.,  16.,  18.,  20.],
            [ 22.,  24.,  26.,  29.]],

           [[ 32.,  35.,  38.,  42.],
            [ 46.,  51.,  56.,  62.],
            [ 68.,  75.,  83.,  91.]]])
    >>> (10**(2+np.arange(48)/48.0)).reshape((2,3,8)).round()
    array([[[ 100.,  105.,  110.,  115.,  121.,  127.,  133.,  140.],
            [ 147.,  154.,  162.,  169.,  178.,  187.,  196.,  205.],
            [ 215.,  226.,  237.,  249.,  261.,  274.,  287.,  301.]],

           [[ 316.,  332.,  348.,  365.,  383.,  402.,  422.,  442.],
            [ 464.,  487.,  511.,  536.,  562.,  590.,  619.,  649.],
            [ 681.,  715.,  750.,  787.,  825.,  866.,  909.,  953.]]])
    >>> 
Hmm, Ruby has a numpy-like thing too, no? NArray, it’s called? There are a few minor differences, but you can do the same thing:

    : user@debian:~; irb
    irb(main):001:0> require 'narray'
    => true
    irb(main):002:0> (10*10**(NArray.float(24).indgen!/24)).round.reshape(4,3,2)
    => NArray(ref).int(4,3,2): 
    [ [ [ 10, 11, 12, 13 ], 
        [ 15, 16, 18, 20 ], 
        [ 22, 24, 26, 29 ] ], 
      [ [ 32, 35, 38, 42 ], 
        [ 46, 51, 56, 62 ], 
        [ 68, 75, 83, 91 ] ] ]
    irb(main):003:0> (100*10**(NArray.float(48).indgen!/48)).round.reshape(8,3,2)
    => NArray(ref).int(8,3,2): 
    [ [ [ 100, 105, 110, 115, 121, 127, 133, 140 ], 
        [ 147, 154, 162, 169, 178, 187, 196, 205 ], 
        [ 215, 226, 237, 249, 261, 274, 287, 301 ] ], 
      [ [ 316, 332, 348, 365, 383, 402, 422, 442 ], 
        [ 464, 487, 511, 536, 562, 590, 619, 649 ], 
        [ 681, 715, 750, 787, 825, 866, 909, 953 ] ] ]
    irb(main):004:0> 
Presumably 12, 24, and 48 were chosen because they are https://en.wikipedia.org/wiki/Highly_composite_numbers, and 96 and 192 for compatibility with 48 (since the HCNs in that neighborhood — 60, 120, and 180 — aren’t divisible by 48.)

(Related joke: How do we know the Babylonians were idiots? Because the day doesn’t have 83160 seconds.)




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: