Read numbers in the base of the largest digit and write it using underscores

5

This isn't as much a "challenge" as "a unique problem that there are no built-in functions to solve." Basically, you need to do this:

  • Read some lines of numbers from stdin. These lines may contain trailing or preceding whitespace, and there may be empty lines. No lines will contain "just whitespace" other than a newline. Each non-empty line will have exactly one number. This:

     123
    
    456\t
    

    (where \t is a tab) is considered valid input.

  • Read the numbers in the input in base N+1, where N is the largest digit in any of the lines. In this case, the largest digit is 6, so the numbers would be read in base 7, resulting in 6610 and 23710.

  • Find the sum of the numbers. The sum of 6610 and 23710 is 30310.

  • Convert the sum back to base N+1 again. We'd convert 30310 to base 7, which would be 6127.

  • For each digit, print that many underscores, followed by a space. The last digit should instead be followed by a newline or a space and a newline. In our example, that would be ______ _ __\n or ______ _ __ \n, where \n is the newline character.

Here's an example in Python:

import sys

def convert_to_base(n, b):
    'Convert `n` to base `b`'
    res = []
    while n:
        res.append(n % b)
        n /= b
    return res[::-1]

# read the lines, discarding empty ones and stripping any whitespace
lines = map(str.strip, filter(None, list(sys.stdin)))
# find the largest digit, and add 1 to it to make our base
base = max(map(max, (map(int, line) for line in lines)))+1
# read the lines in the base and sum them
result = sum(int(line, base) for line in lines)
# print the result in the original base using underscores, separated by spaces
for number in convert_to_base(result, base):
    print '_'*number,
# print a newline
print

This is code golf: the shortest program wins!

kirbyfan64sos

Posted 2015-06-03T21:28:32.410

Reputation: 8 730

Can you add <sub>7</sub> and <sub>10</sub> to your instructions? - nevermind - i just did that. – Not that Charles – 2015-06-04T02:10:19.463

@NotthatCharles What do you mean? – kirbyfan64sos – 2015-06-04T02:12:24.883

I was unclear about which base numbers were in. I edited your question to make them explicit (pending review) – Not that Charles – 2015-06-04T02:14:00.607

@NotthatCharles Ah! Thanks! – kirbyfan64sos – 2015-06-04T02:16:02.013

Answers

2

Pyth, 24 bytes

Just found this question via Twitter.

Notice that quite large parts of the program are similar to isaacg's solution (like base-conversion and the printing part), but the main algorithm is completely different.

.V0#jd*R\_jsiRbcjd.z)b.q

Try it online: Demonstration

My solution is based on this answer, I gave to a similar question two months ago.

Explanation:

.V0                       for b in [0, 1, 2, ...):
   #__________________.q    try-catch block. If ___ is successful, exit the program (.q), 
                            otherwise do nothing
               cjd.z)         read all input (.z), join lines by spaces (jd) and split (c))
                              this gives a list of numbers (but still in string format)
            iRb               convert each number from base b
           s                  sum, add all numbers up
          j          b        convert to base b
      *R\_                    multiply each digit with "_"
    jd                        join with spaces
                              implicit print

The infinite loop .V0 combined with the try-catch #___.q basically finds the first number b >= 0, with which the conversion iRb doesn't throw an error. And this happens, when b is equal to the largest digit + 1.

Jakube

Posted 2015-06-03T21:28:32.410

Reputation: 21 462

5

Pyth, 26

JscR).zjd*R\_jsiRKhseSsJJK

Demonstration.

JscR).z
     .z                       Take the input as a list of lines.
  cR)                         Remove all whitespace from each line.
 s                            Combine the lines.
J                             Save the result to J.
                              J is now the list of the string forms of the numbers.
       jd*R\_jsiRKhseSsJJK
                      sJ      Combine J into one string.
                    eS        Find the maximum of that string.
                   s          Convert it to an integer.
                  h           Add one.
                 K            Save to K. K is the base.
               iRK      J     Convert the strings in J to base K.
              s               Add them together.
             j           K    Convert the result back to base K, as a list of ints.
         *R\_                 Map each int in that list to that many underscores.
       jd                     Join on spaces and print.

isaacg

Posted 2015-06-03T21:28:32.410

Reputation: 39 268

Your Pyth answers always manage to surprise me! – kirbyfan64sos – 2015-06-04T02:12:56.730

2

CJam, 28 27 bytes

q_$W=~)_@N%::~fb:+\b'_f*S*N

UPDATE - 1 byte saved thanks to Martin

Try it online here

Optimizer

Posted 2015-06-03T21:28:32.410

Reputation: 25 836

0

PHP, 188 182

function f($s){$b=max(str_split($s))+1;foreach(preg_split('/\s/',$s)as$x)$m+=base_convert($x,$b,10);foreach(str_split(base_convert($m,10,$b))as$d)echo' ',str_repeat('_',$d);echo'

';}

prints a leading blank instead of a trailing one. if not accepted, add +1.

breakdown:

function f($s)
{
    $b=max(str_split($s))+1;           // find base
    foreach(preg_split('/\s/',$s)as$x) // extract all words and loop
        $m+=base_convert($x,$b,10);    // convert, sum up
    foreach(str_split(base_convert($m,10,$b))as$d) // convert back, split into array, loop
        echo' ',str_repeat('_',$d);    // print underscores
    echo'
';                                     // append newline
}

I wonder if there is a golfier approach to this ...

Titus

Posted 2015-06-03T21:28:32.410

Reputation: 13 814