[SOLVED] New Year Puzzle and fun programming challenge
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
First noticed this thread late Monday; this is great fun!
I wrote my logic in C, a bit over 300 lines w/ comments, about 11k Linux binary.
I get 49 results for 2019. My matrix:
Code:
0 1 2 3 4 5 6 7 8 9
|--------------------
0 | X X X X X X X X X X
1 | X X X X X - X X X X
2 | X X X - - - - X X X
3 | X - - - - - - - X X
4 | - - - - X X X - - -
5 | - - - - - - - - - -
6 | - - - - X - - - - X
7 | X X X - - - - - X -
8 | X X X - - - - X X X
9 | X X X X - X - - - -
10 | X
Also get 53 results for 2029
and 95 for 1972!
(as Sinatra would say, "When I was 21, it was a very good year")
Algebraic formulae and code upon request. I will keep trying to improve on that 49 as well.
What would you say to applying other operations as well? I remember back in the 1970s a similar calculator puzzle entitled '4x4' in which you were allowed to press only the '4' key exactly four times to get results from 0 to 100. Almost the same as this, but in '4x4', you could also use the square, square root, factorial, and reciprocate keys, with parentheses as needed. It took me a good while, but i was eventually able to generate all 101 values (not with a program).
I played the 4x4 game in the 70s too. I didn't make it to 100 though.
I did it on paper, which unlike a calculator allowed me to write .4 with a bar over it. That represents a repeating digit to make .4444444444..., which is 4/9, and the square root of that is 2/3. I got some mileage out of that. Yeah, good times!
This is my although not a program itself. Idea is to use RPN (or PRN): reverse polish notation. Notation which allows to avoid completely use of parentheses, say:
Code:
2*3
is written as
Code:
2 3 *
in rpn any possible expression would be something like that
Code:
d1 d2 op1 d3 op2 d4 op3
just d1,d2,d3,d4 are all different digits, every each is one of 0,1,2,9, and op1,op2,op3 are one operators as in the first post, all of such sequences is 24*6^3 - quite a lot - not of them are however allowed - but decision is being made during computation, say ( | - denotes concatenation)
Code:
0 1 | 2 * 9 +
evaluates to
Code:
((01)*2)+9
which is wrong, so exception NaN is raised - as early as possible. However
Code:
1 0 | 2 * 9 -
is OK - it evaluates to
Code:
10*2-9 = 11
in summary: some sequences will eval to NaN, others to < 0 or > 100, another example
Yeah, my first programmable calculator, an HP11, used RPN. Much more intuitive than parentheses, once you get used to the concept. Also, a co-worker in the 90s wrote a compiler, using RPN to evaluate algebraic expressions.
I played the 4x4 game in the 70s too. I didn't make it to 100 though.
I did it on paper, which unlike a calculator allowed me to write .4 with a bar over it. That represents a repeating digit to make .4444444444..., which is 4/9, and the square root of that is 2/3. I got some mileage out of that. Yeah, good times!
The toughest one (took me over a year of background cogitation) was 93. Turns out, needed both the factorial and reciprocate keys to do it:
I have been investigating the perils of floating point division. To explain: Computers can add, subtract, and multiply whole numbers exactly, provided they don't exceed the number of available bits. Division is different. No matter how many bits are available, division often use every last bit, and still the result is inexact.
For example, on many calculators, 1/3 evaluates to something like 0.33333333. We all know that 3*(1/3) should be 1, but the calculator yields 0.99999999. Call it roundoff error, or truncation error. For most purposes, the difference is negligible, but in the New Year Puzzle, it is a huge problem because we need to know whether the result is or is not a whole number.
When I try that calculation in python, at first it doesn't look so bad:
Code:
>>> 1/3
0.3333333333333333
>>> (1/3)*3
1.0
Wow! It gets the right answer. How does it do that? I am guessing that it calculates it to a few extra places (actually bits), and then rounds it to the required precision. That's actually how the floating-point unit (FPU) in almost every computer works. Most of them do the calculations in 64-bit precision and output the result after rounding down to 53 bits (for double precision). In the above case, that gives the right answer.
Let's try introducing another step:
Code:
>>> (1/3)*3*7
7.0
So far, so good. Now change the order of operations:
Code:
>>> (1/3)*7*3
6.999999999999999
Whaaaat? I am not sure how to explain that in detail, but it warns us that the order of operations makes a small difference in the way truncation errors accumulate. Let the programmer beware!
Here is some good news: If I do those same two calculations in C, I get perfect answers regardless of the order of operations. I don't know why. There must be a small difference in the implementation.
In C it is possible to declare variables as long double, which is (or so I believe) the native format of the FPU, with 64-bit precision. I experimented with it and found that I can get better results by doing all the calculations in long double, and then casting it to regular double (thereby rounding to 53 bits) before testing whether the result is a whole number.
Let me share two programs with you, one in python3 and the other in C, which do the same thing, except C has the option of long double. In the C program, feel free to change the long double declaration and cast to double, or even float, and see what happens. equality-test-for-fractions.py.txt equality-test-for-fractions.c.txt
#!/usr/bin/env python3
def check(n):
digits = set(d for d in n)
if len(digits) < len(n):
return False
if digits - set(['2', '0', '1', '9']):
return False
return True
for i in range(101):
if check((str(i))):
print(i)
Generate all integers from 0 to 100. Filter out the ones that have the same digit more than once. Filter out the ones that have digits that aren't 2, 0, 1, or 9. Print what's left.
Interesting. I didn't know such things can be done with python's set() function. Someday I should learn how, and when, to use set().
There is more to the New Year Puzzle. It requires each digit of the year to be used once and only once, and certain arithmetic operations are allowed. Sorry if the original post didn't make that clear.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.