Weird Calculator

Lynn has a calculator with only two buttons that perform + 1 \boxed{+1} and ÷ 2 \boxed{\div 2} .

She also has a screen with 9 9 significant figures, and it displays 0 0 when she gets the calculator.

If she wants to display π \pi up to the eighth decimal ( 3.14159265 ) (3.14159265) , what is the fewest number of taps she needs to do?

Hint : The first 64 bits of π \pi in binary are given below:

π \pi \approx 11.00100100001111110110101010001000100001011010001100001000110100 2 _2

Note : You may want to use the code environment below.


            
You need to be connected to run code


The answer is 41.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

7 solutions

David Vreken
Mar 22, 2018

The following sequence of 41 \boxed{41} button presses will produce 3.14159265 3.14159265 on Lynn's calculator:

+ 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , + 1 \boxed{+1} , + 1 \boxed{+1}

The binary representation 11.0010010000111111011010101 11.0010010000111111011010101 is sufficient to find π \pi to 8 8 decimal places. The most efficient way to represent the numbers after the decimal on Lynn's calculator is to read from right to left and use + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} for each 1 1 and ÷ 2 \boxed{\div 2} for each 0 0 . Since there are 13 13 1 1 s after the decimal at 2 2 button presses each, and 12 12 0 0 s after the decimal at 1 1 button press each, there are 13 2 + 12 1 = 38 13 \cdot 2 + 12 \cdot 1 = 38 total button presses to obtain the correct numbers after the decimal ( 0.14159265 0.14159265 ). Then an additional 3 3 + 1 \boxed{+1} buttons are necessary to add 3 3 more to obtain the correct answer of 3.14159265 3.14159265 , for a total of 38 + 3 = 41 38 + 3 = \boxed{41} button presses.

Moderator note:

As pointed out in the comments, this approach only shows that we can achieve 41 button presses. However, it has yet to explain why no fewer number of steps is possible, which is necessary to establish a minimum.

If you're interested in exploring this, try answering the question for the minimum number of taps to reach 1.0156 .

Playing devil's advocate, you have shown that it is doable in 41 button presses. How do we know that it cannot be doable in fewer, in order to conclude that this is indeed the minimum?

Calvin Lin Staff - 3 years, 2 months ago

Log in to reply

Unfortunately, I do not know how to prove that this is the minimum.

David Vreken - 3 years, 2 months ago

Log in to reply

This is a slight technicality, but you have the tools and understanding to figure out how to deal with it.

Hint: Supposed we wanted to display 1.0156 as the first 5 digits (possibly with trailing digits), how many steps will we need?
I can do it with less than 10 , whereas your approach will require ~15.

Calvin Lin Staff - 3 years, 2 months ago

Log in to reply

@Calvin Lin 1.0156 1.0156 is approximately 1.000001 1.000001 in binary, so reading this from right to left we have a 1 1 which is + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , then 5 5 0 0 s which is ÷ 2 \boxed{\div 2} each, and then another 1 1 in front of the decimal which is + 1 \boxed{+1} .

Therefore, 1.0156 1.0156 can be obtained on Lynn's calculator using my approach by entering + 1 \boxed{+1} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , ÷ 2 \boxed{\div 2} , + 1 \boxed{+1} , which is 8 8 button presses.

David Vreken - 3 years, 2 months ago

Log in to reply

@David Vreken Great observation! We do not want to use 1.00000001111..... . Instead, by using 1.015625 = 1.00000 1 2 1.015625=1.000001_2 , we can (greatly) cut down the number of steps. because the ending 1's are not "needed".

Now, figure out how to deal with the technicality.

Calvin Lin Staff - 3 years, 2 months ago

Log in to reply

@Calvin Lin Oh, I misunderstood your question. I see what you are asking now:

1 2 1 = 0.5 \frac{1}{2^1} = 0.5 , 1 2 2 = 0.25 \frac{1}{2^2} = 0.25 , 1 2 3 = 0.125 \frac{1}{2^3} = 0.125 have an affect on the number immediately after the decimal because their decimal representations have a number in the tenth spot, but 1 2 4 = 0.0625 \frac{1}{2^4} = 0.0625 (and all powers of 2 2 after this) do not, because 2 3 < 1 0 1 < 2 4 2^3 < 10^1 < 2^4 . Likewise, exponents 1 2 4 \frac{1}{2^4} through 1 2 6 \frac{1}{2^6} have a number in the hundredth spot, but 1 2 7 \frac{1}{2^7} (and all powers of 2 2 after this) do not, because 2 6 < 1 0 2 < 2 7 2^6 < 10^2 < 2^7 . For a decimal representation to be accurate to 1 1 decimal place, in most cases we must be sure that that the 2 n d 2^{nd} number is also accurate to deal with rounding, and so at most 6 6 binary decimals are needed, because 2 6 < 1 0 1 + 1 < 2 7 2^6 < 10^{1 + 1} < 2^7 . Using this logic, in general, to be accurate to n n decimal places, in most cases at most n + 1 log 2 1 \lfloor \frac{n + 1}{\log 2} - 1\rfloor binary decimals are needed.

However, the number of binary decimals needed can be shortened if the last few numbers in the n + 1 log 2 1 \lfloor \frac{n + 1}{\log 2} - 1\rfloor binary decimals are all 0 0 s or all 1 1 s. If the last few numbers are 0 0 s, then the binary representation can be truncated because the 0 0 s are unnecessary. If the last few numbers are 1 1 s, then 1 1 can be added to the n + 1 log 2 1 \lfloor \frac{n + 1}{\log 2} - 1\rfloor spot without changing the decimal representation value, and the addition will change all the last 1 1 s to 0 0 s and the last 0 0 to 1 1 , allowing another truncation because of unnecessary 0 0 s.

So for 1.0156 1.0156 , accurate to 4 4 decimal places, we would at most need 4 + 1 log 2 1 = 15 \lfloor \frac{4 + 1}{\log 2} - 1\rfloor = 15 binary decimals. However, since the first 15 15 decimal places of the binary of 1.0156 1.0156 is 1.000000111111111 1.000000111111111 , which ends in a sequence of 1 1 s, we can add 0.000000000000001 0.000000000000001 to get a shorter binary of 1.000001 1.000001 .

Likewise, for 3.14159265 3.14159265 , accurate to 8 8 decimal places, we would at most need 8 + 1 log 2 1 = 28 \lfloor \frac{8 + 1}{\log 2} - 1\rfloor = 28 binary decimals. However, since the the last 3 3 digits of the first 28 28 decimal places of the binary are 0 0 s, they can be truncated, which means only the first 25 25 binary digits are necessary.

David Vreken - 3 years, 2 months ago

Log in to reply

@David Vreken Great (I didn't check the full details, but) it looks like you are on the right track. The idea is to consider all possible binary representations for values between 1.0156 and 1.0157, so that we can determine a lower bound for the minimum number of steps. Conversely, for this value, it is achieved. Hence we are done.

Calvin Lin Staff - 3 years, 2 months ago

@Calvin Lin With this problem, I was relieved to see 0's in the 26, 27, 28 position because it meant I wouldn't have to worry about rounding.

Jeremy Galvagni - 3 years, 2 months ago

since to get a 11 requires 3 presses on +1, and press /2 will result 1.1, hence 4 presses. But the minimum press to get 1.1 is 3 presses, which is +1, /2, +1, hence the minimum press is always +1 then /1

or moving 1 to front from 0 with +1 requires 3 presses, but moving 1 from 0 to back only requires 2 presses (+1 then /2)

Wuiyang Tan - 3 years, 2 months ago

How do we come to conclude what binary representation is sufficient from the given 64 bit? Is there any trick to this or do I have to work it out?

Shubham Gupta - 3 years, 2 months ago

Log in to reply

If you can figure out how many bits are needed (on average) to represent a decimal digit, then you can multiply that with the number of decimal digits and round up to get how many bits are needed. So, I don't know how to show this, but I think that you need log2(10) bits per decimal digit. So for the decimals after the decimal point I get round_up(8*log2(10)) = 27. Looking at the first 27 bits after the radix point we see that the last couple of bits are 0 and thus would make no difference if we ignored them so we end up needing the first 25 bits after the radix point. This is how I did it, it is far from a proof, so maybe it's wrong.

Daniel Eliasson - 3 years, 2 months ago

Why am I getting a different result on my calculator? On mine, tap #38 results in 0.14159266

Brandon Parker - 3 years, 2 months ago

Log in to reply

Count 38 ( Count 41 minus the last three 1s, here's what I got. Remember the last bit in the binary string has to be a '1'

Count: 41 Decimal: 3.14159265161 ( 3.14159265 ) Binary: 11.0010010000111111011010101 Buttons: +1 /2 /2 +1 /2 /2 +1 /2 /2 +1 /2 +1 /2 /2 +1 /2 +1 /2 +1 /2 +1 /2 +1 /2 +1 /2 /2 /2 /2 /2 +1 /2 /2 /2 +1 /2 /2 /2 +1 +1 +1

Michael Fitzgerald - 3 years, 2 months ago

Why to use binary? In decimals, 3=1+1+1 == 3 taps; 1= (3+1)/2/2 == 3 taps; 4=1+1+1+1 == 3 taps; 1=4/2/4 == 2 taps; 5=1+1+1+1+1 == 4 taps; 9=5+1+1+1+1 == 4 taps; 2=(((9+1)/2+1)/2+1)/2 == 6 taps; 6=2+1+1+1+1 == 4 taps; 5=(6+1+1+1+1)/2 == 5 taps, total 34 taps

carslover14 . - 3 years, 2 months ago

Log in to reply

Note: You are supposed to type out 3.14159265, not 3, 1, 4, 1, 5, 9, 2, 6, 5.

Calvin Lin Staff - 3 years, 2 months ago

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# https://brilliant.org/weekly-problems/2018-03-26/intermediate/?p=5

from math import log, pow

def dec2bin(f, d):    
    if f >= 1:
        pow_ = int(log(f, 2))
    else:
        pow_ = -1        
    h = pow_ + 1
    x = pow(2, pow_)
    str_ = ""  
    while f > 0 or x >= 1: 
        if f < 1:
            if len(str_[h:]) >= d:
                break          
        if f >= x:
            str_ += "1"
            f -= x
        else:
            str_ += "0"
        x /= 2
    str_ = str_[:h] + "." + str_[h:]
    return str_


def radix_point(string):
    if any(i in '.' for i in string):
        r_p = string.find('.')         #Fetch the radix point
    else:
        r_p = len(string)
    return r_p

#float_ = 1.0156       
float_ = 3.14159265  # pi
#float_ = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481

#float_ = 2.718281828  # e
#float_ = 2.71828182845904523536028747135266249775724709369995

dec_p = radix_point(str(float_))
pwr = len(str(float_)) - dec_p - 1
count = 0
digits = 64
bin_ = dec2bin(float_, digits)
bin_p = radix_point(bin_)
c = 0
buttons = []
sum_ = 0.
for i in range(bin_p, len(bin_)+1):
    if bin_[i] != '.':
        bin_ = bin_[:i+bin_p-1] + '1'
    for j in range(i+bin_p-1, bin_p, -1): 
        if bin_[j] == '1':
            c += 2
            sum_ += 1
            sum_ /= 2
            buttons.append('+1  /2 ')
        elif bin_[j] == '0':
            c += 1
            sum_ /= 2
            buttons.append('/2 ')

    for d in range(int(float_)):
        buttons.append('+1 ')
        c += 1
        sum_ += 1                

    print 'Count: %d\t\tDecimal: ' % c ,
    print '%s  (' % sum_ ,
    print'{:.{prec}f}'.format(sum_, prec=pwr ) ,
    print')\t\tBinary: %s \n' % bin_[:i+bin_p] ,
    print 'Buttons: %s' %(' '.join(buttons))

    if abs(float_ - sum_) <= 0.5*10**-pwr:
        break
    buttons = [] 
    sum_ = 0.
    c = 0
    bin_ = dec2bin(float_, digits)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Count: 5                Decimal:  3.5  ( 3.50000000 )           Binary: 11.1 
Buttons: +1  /2  +1  +1  +1 
Count: 6                Decimal:  3.25  ( 3.25000000 )          Binary: 11.01 
Buttons: +1  /2  /2  +1  +1  +1 
Count: 7                Decimal:  3.125  ( 3.12500000 )         Binary: 11.001 
Buttons: +1  /2  /2  /2  +1  +1  +1 
Count: 9                Decimal:  3.1875  ( 3.18750000 )                Binary: 11.0011 
Buttons: +1  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 10               Decimal:  3.15625  ( 3.15625000 )               Binary: 11.00101 
Buttons: +1  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 11               Decimal:  3.140625  ( 3.14062500 )              Binary: 11.001001 
Buttons: +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 13               Decimal:  3.1484375  ( 3.14843750 )             Binary: 11.0010011 
Buttons: +1  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 14               Decimal:  3.14453125  ( 3.14453125 )            Binary: 11.00100101 
Buttons: +1  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 15               Decimal:  3.142578125  ( 3.14257812 )           Binary: 11.001001001 
Buttons: +1  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 16               Decimal:  3.1416015625  ( 3.14160156 )          Binary: 11.0010010001 
Buttons: +1  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 17               Decimal:  3.14111328125  ( 3.14111328 )         Binary: 11.00100100001 
Buttons: +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 19               Decimal:  3.14135742188  ( 3.14135742 )         Binary: 11.001001000011 
Buttons: +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 21               Decimal:  3.14147949219  ( 3.14147949 )         Binary: 11.0010010000111 
Buttons: +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 23               Decimal:  3.14154052734  ( 3.14154053 )         Binary: 11.00100100001111 
Buttons: +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 25               Decimal:  3.14157104492  ( 3.14157104 )         Binary: 11.001001000011111 
Buttons: +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 27               Decimal:  3.14158630371  ( 3.14158630 )         Binary: 11.0010010000111111 
Buttons: +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 29               Decimal:  3.14159393311  ( 3.14159393 )         Binary: 11.00100100001111111 
Buttons: +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 30               Decimal:  3.14159011841  ( 3.14159012 )         Binary: 11.001001000011111101 
Buttons: +1  /2  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 32               Decimal:  3.14159202576  ( 3.14159203 )         Binary: 11.0010010000111111011 
Buttons: +1  /2  +1  /2  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 34               Decimal:  3.14159297943  ( 3.14159298 )         Binary: 11.00100100001111110111 
Buttons: +1  /2  +1  /2  +1  /2  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 35               Decimal:  3.14159250259  ( 3.14159250 )         Binary: 11.001001000011111101101 
Buttons: +1  /2  /2  +1  /2  +1  /2  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 37               Decimal:  3.14159274101  ( 3.14159274 )         Binary: 11.0010010000111111011011 
Buttons: +1  /2  +1  /2  /2  +1  /2  +1  /2  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 38               Decimal:  3.1415926218  ( 3.14159262 )          Binary: 11.00100100001111110110101 
Buttons: +1  /2  /2  +1  /2  /2  +1  /2  +1  /2  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 40               Decimal:  3.14159268141  ( 3.14159268 )         Binary: 11.001001000011111101101011 
Buttons: +1  /2  +1  /2  /2  +1  /2  /2  +1  /2  +1  /2  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 
Count: 41               Decimal:  3.14159265161  ( 3.14159265 )         Binary: 11.0010010000111111011010101 
Buttons: +1  /2  /2  +1  /2  /2  +1  /2  /2  +1  /2  +1  /2  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  +1  /2  /2  /2  /2  /2  +1  /2  /2  /2  +1  /2  /2  /2  +1  +1  +1 

Michael Fitzgerald - 3 years, 2 months ago

Log in to reply

Can you run your code for 1.0156 ? What do you get?

Calvin Lin Staff - 3 years, 2 months ago

Log in to reply

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Count: 1                Decimal:  1.0  ( 1.0000 )               Binary: 1
Buttons: +1 
Count: 3                Decimal:  1.5  ( 1.5000 )               Binary: 1.1 
Buttons: +1  /2  +1 
Count: 4                Decimal:  1.25  ( 1.2500 )              Binary: 1.01 
Buttons: +1  /2  /2  +1 
Count: 5                Decimal:  1.125  ( 1.1250 )             Binary: 1.001 
Buttons: +1  /2  /2  /2  +1 
Count: 6                Decimal:  1.0625  ( 1.0625 )            Binary: 1.0001 
Buttons: +1  /2  /2  /2  /2  +1 
Count: 7                Decimal:  1.03125  ( 1.0312 )           Binary: 1.00001 
Buttons: +1  /2  /2  /2  /2  /2  +1 
Count: 8                Decimal:  1.015625  ( 1.0156 )          Binary: 1.000001 
Buttons: +1  /2  /2  /2  /2  /2  /2  +1 

Michael Fitzgerald - 3 years, 2 months ago

Last bit in binary string has to be '1'

Michael Fitzgerald - 3 years, 2 months ago
Binky Mh
Mar 26, 2018

The two available functions on the calculator have simple effects when applied to binary numbers: the + 1 \boxed{+1} function adds 1 1 to the number before the point, and the ÷ 2 \boxed{\div 2} moves all the bits one to the right. For example, 0.101 + 1 = 1.101 0.101+1=1.101 and 1.101 ÷ 2 = 0.1101 1.101 \div 2 = 0.1101 .

This means it is possible to produce such a number by considering the bits from the right end, pressing the + 1 \boxed{+1} button to produce a 1 1 , then pressing the ÷ 2 \boxed{\div 2} button to continue progressing along the bits towards the left. We can now calculate the total number of button presses to make such a number:

  • Every individual bit after the point requires one press of the ÷ 2 \boxed{\div 2} button
  • Every 1 1 after the point requires one press of the + 1 \boxed{+1} button
  • The number before the point requires pressing the + 1 \boxed{+1} button enough times to count up to the desired number

The binary number 11.0010010000111111011010101 11.0010010000111111011010101 is the shortest number that will display π \pi to 8 8 decimal places.

There are 25 25 bits after the point, 13 13 individual 1 1 's after the point, and 3 + 1 3\ \boxed{+1} presses needed to count to the 11 11 before the point, meaning a total of 25 + 13 + 3 = 41 25+13+3=\boxed{41} button presses are required to produce the number.

Edit: To determine the shortest possible binary number, I used a brute force approach, taking a number known to produce π \pi to 8 8 decimal places and then rounding it down/up to the next smallest bit until any further changes would no longer produce the correct decimal solution. In this case, 11.0...101 11.0...101 can be rounded either down to 11.0...1 ( 00 ) 11.0...1(00) or up to 11.0...11 ( 0 ) 11.0...11(0) , but these both produce π \pi accurate to only 7 7 decimal places.

You have the right ideas here, but unfortunately are still missing a minor part.

Hint: Supposed we wanted to display 1.0156 as the first 5 digits (possibly with trailing digits), how many steps will we need?
I can do it with less than 10 , whereas your approach will require ~15.

Calvin Lin Staff - 3 years, 2 months ago

Log in to reply

Thanks for pointing this out to me. My approach would still work, I just neglected to state how I determined what the shortest possible solution would be.

Binky MH - 3 years, 2 months ago

A possibly more elegant additive method can also be used to generate the binary number. Some pseudocode: a=0; b=1/2; loop{ If (a+b ≥ 3.14159265 && a+b< 3.14159266){ return a+b; }else if(a+b<pi){ a=a+b; } b=b/2; }

Binky MH - 3 years, 2 months ago

I don't understand (and don't like) the binary solution, but knowing its around 38 steps to get the desired decimal part, by brute force i would do a combinatoric of 37 places, each with 3 options (+1, /2, and nothing)(the first step must be a +1 anyways; maybe more heuristics can be added) to see if we can have at least one positive, if not, 41 (38+3) would be the minimum.

Eliud Alejandro Maldonado Sanchez - 3 years, 2 months ago
Ivo Zerkov
Mar 21, 2018

Only the bits between 2 1 2^1 and 2 25 2^{-25} are necessary to get the needed precision. Starting from the last bit and working backwards, one needs 13 13 presses of the + 1 +1 key, because that’s how many 1 1 ’s there are in the binary presentation of π \pi with the desired accuracy, and 25 25 presses of ÷ 2 \div2 , to get to 0.14159265160561 0.14159265160561\dots . Adding 1 three more times to get to π \pi makes the answer 25 + 13 + 3 = 41 25+13+3=41 .

You are right to say that only those bits are necessary. It is true for a general number (to 8 decimals), but we might have additional redundency for a specific number.

Hint: Supposed we wanted to display 1.0156 as the first 5 digits (possibly with trailing digits). Must we use 2 10 0.000977 2^ { - 10 } \approx 0.000977 ? If no, then perhaps we could do better.

Calvin Lin Staff - 3 years, 2 months ago
Leo Hsu
Mar 26, 2018

A truncated binary representation of π \pi to the n n th corresponds to a sequence of + 1 +1 and ÷ 2 \div 2 in the following way:

11.001001 (in binary) = 2 1 1 + 2 0 1 + 2 1 0 + 2 2 0 + 2 3 1 + 2 4 0 + 2 5 0 + 2 6 1 (in decimal) = 1 + 1 + 1 + 1 2 ( 0 + 1 2 ( 0 + 1 2 ( 1 + 1 2 ( 0 + 1 2 ( 0 + 1 2 ( 1 + 0 ) ) ) ) ) ) = ( ( ( ( ( ( ( ( ( ( ( ( 0 ) + 1 ) ÷ 2 ) ÷ 2 ) ÷ 2 ) + 1 ) ÷ 2 ) ÷ 2 ) ÷ 2 ) + 1 ) + 1 ) + 1 \begin{aligned} 11.001001 \text{ (in binary)} &= 2^1\cdot 1 + 2^0\cdot 1 + 2^{-1}\cdot 0 + 2^{-2}\cdot 0 + 2^{-3}\cdot 1 + 2^{-4}\cdot 0 + 2^{-5}\cdot 0 + 2^{-6}\cdot 1 \text{ (in decimal)}\\ &= 1 + 1 + 1 + \frac{1}{2} \left( 0 + \frac{1}{2} \left( 0 + \frac{1}{2} \left( 1 + \frac{1}{2} \left( 0 + \frac{1}{2} \left( 0 + \frac{1}{2} (1 + 0) \right) \right) \right) \right)\right)\\ &= ((((((((((((0)+1)\div 2)\div 2)\div 2)+1)\div 2)\div 2)\div 2)+1)+1)+1 \end{aligned}

Using a program, we can iterate through the i i th truncation of π \pi in binary, evaluate the corresponding decimal expression rounded to the eighth decimal, until we find one that matches 3.14159265 3.14159265 . An example of a program written in Elm is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
piBinary =
    "11.00100100001111110110101010001000100001011010001100001000110100"

answer = List.range 0 (String.length piBinary)
        |> List.map
            (flip String.left
                (String.dropLeft 3 piBinary)
                >> String.foldr
                    (\c ( x, n ) ->
                        if c == '1' then
                            ( (x + 1) / 2, n + 2 )
                        else
                            ( x / 2, n + 1 )
                    )
                    ( 0, 0 )
                >> (\( x, n ) -> ( x + 3, n + 3 ))
            )
        |> List.filter
            (Tuple.first
                >> roundTo 8
                >> (==) 3.14159265
            )
        |> List.head
        |> Maybe.map Tuple.second

roundTo decPlace n =
    toFloat (round (n * 10 ^ decPlace)) / 10 ^ decPlace

Remember that to show something is the minimum, you have to show that 1) It is attainable, 2) No smaller value is attainable.

Your program has done 1, but not 2.

Calvin Lin Staff - 3 years, 2 months ago

Log in to reply

Ah, you are right. I have shown that assuming I'm using the algorithm of converting a truncated version of π \pi in binary to a sequence of add1 and divBy2 operations, 41 41 is the minimum (since I'm iterating from 0 0 up, and outputting the first number n n such that that the n n -th binary truncation of π \pi gives 3.1415926 3.1415926 in decimal). However, I have not shown that with another algorithm I cannot do it with fewer steps.

Leo Hsu - 3 years, 2 months ago
David Crook
Mar 28, 2018

Needing ceiling log(10**9,2) binary digits to hold 8+1 decimal digits, the gross number of binary digits comes to ~29.9 (or 30 whole digits).

In the string the first 30 binary digits are .....10101000 (note the three trailing zeroes). The position of the rightmost 1 binary digit is at 25 fractional binary digits (30 - 2 (whole digits) - 3 (trailing zeros)). Since the next three (rightmost) are zeros, they do not need to be included in the button operations.

Counting the number of 1s in the fractional portion to be 13. The fractional binary 1s map to a +1 operation. Their position and each zero position all represent a division by 2 operation.

So we are at 13 + 25 operations for the fractional part.

For the whole portion, three +1s are needed (without any further divisions).

So total sum in this case are 13+25+3 = 41

Stephen Emmerson
Mar 26, 2018

C#/LINQ

// one-liner
Enumerable.Range(1,62).Select(n=>"00100100001111110110101010001000100001011010001100001000110100".Take(n).Reverse().Select(b=>b-'0').Aggregate((c:3,a:0.0),(s, b)=>(c:s.c+b+1,a:(s.a+b)/2))).Where(s=>s.a>0.14159265).Select(s=>s.c).First()

41

// to expand
Enumerable.Range(1,62)     // for n = 1 to 62
.Select(n =>    
    "00100100001111110110101010001000100001011010001100001000110100"  // pi minus 3
    .Take(n)   // take first n bits 
    .Reverse()   // smallest bits first
    .Select(bit => bit-'0')   // turn char into 0/1
    .Aggregate(    // run through all bits
        (clicks:3, acc:0.0), // calculator accumulator initially 0; 3 clicks represent the final 3 [+1] for integer part of pi
        (state, bit) => (clicks:state.clicks+bit+1, acc:(state.acc+bit)/2)    // if bit = 1 [+1][/2] else [/2]   
    )         
)  // result is 62 (clicks,acc) pairs
.Where(state => state.acc > 0.14159265)  // filter those where acc is first 8 digits
.Select(state => state.clicks) // take #clicks
.First() // filter on first value - least as #clicks increases with n
Laszlo Kocsis
Mar 26, 2018
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
digits = '00100100001111110110101010001000100001011010001100001000110100'
target = 0.14159265

for j in range(1,len(digits)):
    num = 0    
    taps = 0
    for i in digits[j::-1]:
        if i == '1':
            num = num + 1
            taps = taps + 1
        num = num / 2
        taps = taps + 1
    if int(num*100000000)/100000000 == target:
        print(taps + 3)
        break
else:
    print('More digits needed.')

I used round(num,8) == target first, so I got 42. I think this would be better, as calculators usually round the value instead of showing the first x digits. But I understood how the problem was meant, so got it for the second try.

Remember that to show something is the minimum, you have to show that 1) It is attainable, 2) No smaller value is attainable.

Your program has done 1, but not 2.

Hint: Run the program for 1.0156, and then try to do better than it .

Calvin Lin Staff - 3 years, 2 months ago

Log in to reply

Calvin, can my reply be posted as a solution please?

Michael Fitzgerald - 3 years, 2 months ago

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...