2

For two numbers x and y that are base b, does this work for subtracting them? The numbers are given in string format and 2 <= b <= 10.

def n2b(n, b):         # function to convert number n from base 10 to base b
    if n == 0:
        return 0
    d = []
    while n:
        d.append(int(n % b))
        n /= b
    return ''.join(map(str,d[::-1]))

x = int(x,b) # convert to integers in base 10 
y = int(y,b)
z = x - y
z = n2b(z,b) # convert back to base b, still in integer form
kfish15
  • 73
  • 1
  • 8
  • 4
    Internally, _all_ numbers are base 2. We do not answer questions "Does it work?" here. We answer questions "Why does it not work?" So, what is your question? – DYZ Jan 14 '17 at 07:23
  • Can you see ways in which this wouldn't work? Larger problem is that I'm working on a project in which the end result is supposed to pass some tests in which I can only see whether my code passed or failed, but not what the inputs or outputs were or where the error occurred. I think the error is here but not totally sure. The project passed the two tests I was given & could see the inputs and supposed out, but didn't pass most of the blind tests applied to it. – kfish15 Jan 14 '17 at 07:29
  • You have to tell us how it is supposed to work and why you think it does not work. We cannot guess what is the expected behavior of your code. – DYZ Jan 14 '17 at 07:31
  • Why do `int(n % b)`? `n % b` is already an int, so converting it to an int is pointless. Instead, you could do `str(n % b)` then you won't need that `map` call. Note that your code will only work for `2 <= b <= 10`, but `int(x, b)` works for `2 <= b <= 36`. BTW, you should do `n /= b` since you want floor division, and that will also make your code compatible with Python 3 (in Python 3, `/` always gives a float result). – PM 2Ring Jan 14 '17 at 07:39
  • For example, this is chunk of code is supposed to produce the result of subtracting two base b numbers x and y. If x == 2111 and y = 1112, z should equal 0999, which it does. However, I'm concerned with the idea of converting from base b to base 10 just to subtract them, and then converting the result (z) back to base b and whether that would work in all situations. The function n2b takes the base 10 number and converts it back to base b. The area I think that doesn't work is going from base b to base 10 and back. – kfish15 Jan 14 '17 at 07:39
  • You _aren't_ converting to base 10, you're actually converting to binary, as DYZ mentioned. Python numbers only _look like_ they're in base 10 because when you print them they get converted to a string of the base 10 representation of the number. – PM 2Ring Jan 14 '17 at 07:42
  • But I am converting them from their original base to another base and back to the original base, which could lead to errors. I think more of my misunderstanding here is around subtracting non-base 10 to be honest :). For the project, this is part of an algorithm that catches recurring patterns in the output (z), which are derived from a few modifications to an original number n. I was worried that this step could lead to incorrect answers, and then the rest of the code wouldn't be able to pick up on the patterns. However, it sounds like you both believe the error is elsewhere? – kfish15 Jan 14 '17 at 07:52
  • What error? Your code works fine on Python 2, for `0 <= y <= x`, and `2 <= b <= 10`, but you should change `n /= b` to `n //= b`, which has the side-benefit that it'll work correctly (under those conditions) on Python 3, too. It's not that hard to make it work for a higher range of bases. And I guess you should think about how to handle negative numbers if your project needs that. Alternatively, it's possible to do the subtraction directly in base `b`, but I wouldn't bother doing that unless this is for an assignment where you're expected to implement that algorithm. – PM 2Ring Jan 14 '17 at 08:09
  • 4
    These answers won't help you infiltrate commander lambda's castle. Your problem isn't dealing with integers at all, but strings. Subtracting the two gives you 220888, not 210111, which doesn't convert into base 3 how you're thinking. –  Jan 29 '17 at 05:42

2 Answers2

4

You have some confusion about how integers work in python. As the comments above say: python always stores integers in binary form and only converts them to a base when you print them. Depending on how you get x and y and how you need to give back z the code needs to be different

Situation 1: x, y and z are all integers

In this case you only need to do

z = x - y

And you're done.

Situation 2: x, y and z are all strings

In this case you first need to convert the strings into integers with the right base. I think that's your case, since you already deal with int(x, b) which is correct to transform a string into an integer (e.g. int("11", 2) gives 3 (integer represented in base 10). I would advice you to reform your code into something like this:

x_int = int(x, b)
y_int = int(y, b)
z_str = n2b(x_int - y_int, b)

In your code x is first a string and then an integer, which is bad practice. So e.g. use x_int instead of x.

Now it comes down to if your n2b function is correct. It looks good from the distance, although you're not handling signs and bases bigger than 10. There is a broadly accepted convert integer to base b answer so you might take this to be sure.

Community
  • 1
  • 1
hansaplast
  • 11,007
  • 2
  • 61
  • 75
1

This is exactly the problem I just ran into in the google foobar challenge (which I suspect is the same source of ops problem). Granted its years later and op has no use for my answer but someone else might.

The issue

The function op used looked a lot like a copy and paste of this provided by the accepted answer but slightly modified (although I didn't look to closely).
I used the same function and quickly realized that I needed my output to be a string. Op appears to have realized the same thing based on the return statement at the end of the function.
This is why most of the test cases passed. Op did almost everything right.
See, the function begins with

if n==0:
    return 0

One of the test cases in the foobar challenge uses 0 as the input. Its an easy line to miss but a very important one.

Solution

When I was presented this problem, I thought about the possible outlier cases. 0 was my first idea (which turned out to be right). I ran the program in vscode and would ya look at that - it failed.
This let me see the error message (in my case it was a list rather than int but op would have received a similar error).
The solution is simply changing return 0 to return '0' (a string rather than int)

I wasn't super excited to write out this answer since it feels a bit like cheating but its such a small detail that can be so infuriating to deal with. It doesn't solve the challenge that foobar gives you, just tells you how to get past a speed bump along the way.

Good luck infiltrating commander lambda's castle and hopefully this helps.