Decompose a number!

16

1

Your task is to decompose a number using the format below.

This is similar to base conversion, except that instead of listing the digits in the base, you list the values, such that the list adds up to the input.

If the given base is n, then each number in the list must be in the form of k*(n**m), where 0<=k<n and m is unique throughout the list.

Specs

  • Any reasonable input/output format. Your program/function takes 2 inputs and outputs a list.
  • Output list can be in any order.
  • 0 can be excluded or included.
  • Leading 0 are allowed.
  • Built-ins are allowed.

Testcases

number base   converted list
input1 input2 output
123456 10     [100000,20000,3000,400,50,6] or [6,50,400,3000,20000,100000]
11     2      [8,2,1] or [0,0,0,0,8,0,2,1]
727    20     [400,320,7]
101    10     [100,1] or [100,0,1]

Scoring

This is . Shortest solution in bytes wins.

Leaky Nun

Posted 2016-05-01T03:03:53.863

Reputation: 45 011

Answers

5

Jelly, 7 bytes

lr0⁹*×b

Try it online! or verify all test cases.

How it works

lr0⁹*×b  Main link. Arguments: x (integer), n (base)

l        Compute the logarithm of x to base n.
 r0      Range; yield all non-negative integers less than the logarithm, in
         decreasing order.
   ⁹*    Elevate n to all integers in that range.
      b  Yield the list of base-n digits of x.
     ×   Multiply each digit by the corresponding power of n.

Dennis

Posted 2016-05-01T03:03:53.863

Reputation: 196 637

Ah, reversed range... – Leaky Nun – 2016-05-02T04:05:30.213

It is so impressive what can be achieved with so few characters – t-clausen.dk – 2016-05-03T08:24:19.490

4

JavaScript (ES6), 47 bytes

f=(n,b,p=1,q=b*p)=>[...n<q?[]:f(n,b,q),n%q-n%p]
document.write("<pre>"+
[ [ 123456, 10 ], [ 11, 2 ], [ 727, 20 ], [ 101, 10 ] ]
.map(c=>c+" => "+f(...c)).join`\n`)

Neil

Posted 2016-05-01T03:03:53.863

Reputation: 95 035

Care to include a snippet? :) – Leaky Nun – 2016-05-01T09:27:07.510

3

Pyth - 12 11 bytes

Just a FGITW, can be shorter.

.e*b^Qk_jEQ

Test Suite.

Maltysen

Posted 2016-05-01T03:03:53.863

Reputation: 25 023

Remove the _ for a byte :) – Leaky Nun – 2016-05-01T03:17:20.133

@KennyLau meant FGITW, it means "Fastest Gun In The West", a phenomenon where people answering first get more upvotes than the better answers. – Maltysen – 2016-05-01T03:17:50.910

@KennyLau oh that's allowed, derp. – Maltysen – 2016-05-01T03:18:45.457

3

Jelly, 12 bytes

bLR’*@€U
b×ç

Can be waaaay shorter...

Try it online!

Doorknob

Posted 2016-05-01T03:03:53.863

Reputation: 68 138

3lḞr0⁴*×b should work. – Dennis – 2016-05-01T05:54:33.040

Technically, 0r⁴*³%I works as well.

– Dennis – 2016-05-01T20:49:39.977

Scratch that. lr0⁴*×b has the same byte count, without all the extra zeroes. – Dennis – 2016-05-02T02:53:58.293

@Dennis That's definitely different enough to post as a separate answer. – Doorknob – 2016-05-02T03:32:42.130

OK, done.

– Dennis – 2016-05-02T04:01:45.693

3

J, 20 19 bytes

[(]*(^<:@#\.))#.inv

Usage

   f =: [(]*(^<:@#\.))#.inv
   10 f 123456
100000 20000 3000 400 50 6
   2 f 11
8 0 2 1
   20 f 727
400 320 7
   10 f 101
100 0 1

Explanation

[(]*(^<:@#\.))#.inv
              #.      Given a base and list of digits in that base,
                      converts it to an integer in base 10
                inv   Power conjunction by -1, creates an inverse
                      Now, this becomes a verb that given a base and an integer in base 10,
                      creates a list of digits in that base representing it
[                     Select the base and pass it along
         #\.          Tally each suffix of the list of base digits,
                      Counts down from n to 1
      <:              Decrements each value
        @             More specifically, decrement is composed with the tally and applied
                      together on each suffix
     ^                Raises each value x using base^x
  ]                   Selects the list of base digits
   *                  Multiply elementwise between each base power and base digit

miles

Posted 2016-05-01T03:03:53.863

Reputation: 15 654

2

CJam, 16 bytes

{1$b\1$,,f#W%.*}

An unnamed block that expects the base and the number on top of the stack (in that order) and replaces them with the digit list (including internal zeros, without leading zeros).

Test it here.

Explanation

1$  e# Copy base b.
b   e# Compute base-b digits of input number.
\   e# Swap digit list with other copy of b.
1$  e# Copy digit list.
,   e# Get number of digits M.
,   e# Turn into range [0 1 ... M-1].
f#  e# Map b^() over this range, computing all necessary powers of b.
W%  e# Reverse the list of powers.
.*  e# Multiply each digit by the corresponding power.

Martin Ender

Posted 2016-05-01T03:03:53.863

Reputation: 184 808

2

TSQL, 68 bytes

DECLARE @ INT=123456,@z INT=10
DECLARE @l INT=1WHILE
@>0BEGIN PRINT @%@z*@l SELECT @/=@z,@l*=@z END

t-clausen.dk

Posted 2016-05-01T03:03:53.863

Reputation: 2 874

1

Python 2, 44 bytes

lambda n,b:[n/b**i%b*b**i for i in range(n)]

Outputs from least significant to most, with many extra zeroes.

To output most significant to least:

f=lambda n,b,c=1:n*[1]and f(n/b,b,c*b)+[n%b*c]

Recurse, repeatedly taking digits off of n with divmod while scaling up the place value multiplier c.

xnor

Posted 2016-05-01T03:03:53.863

Reputation: 115 687

For the second version, can't you do range(-n,1) instead of range(n,-1,-1)? – Erik the Outgolfer – 2016-07-18T18:49:57.350

@EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Thanks, I didn't see that going in reverse was an option. It even suffices to just do range(n). – xnor – 2016-07-18T22:46:25.617

1

Ruby, 35 34 bytes

This is a port of xnor's Python answer, but it prints n times so the test case 727 20 prints 7, 320, 400, and 724 0s. Golfing suggestions welcome.

Edit: 1 byte thanks to Jordan.

->n,b{n.times{|i|p n/b**i%b*b**i}}

Sherlock9

Posted 2016-05-01T03:03:53.863

Reputation: 11 664

You can save a byte with n.times{|i|p ...}. – Jordan – 2016-08-20T16:08:34.633

1

Mathematica, 46 bytes

DiagonalMatrix@IntegerDigits@##~FromDigits~#2&

Explanation:

In[1]:= IntegerDigits[123456,10]                                                

Out[1]= {1, 2, 3, 4, 5, 6}

In[2]:= DiagonalMatrix@IntegerDigits[123456,10] // MatrixForm                   

Out[2]//MatrixForm= 1   0   0   0   0   0

                    0   2   0   0   0   0

                    0   0   3   0   0   0

                    0   0   0   4   0   0

                    0   0   0   0   5   0

                    0   0   0   0   0   6

In[3]:= DiagonalMatrix@IntegerDigits[123456,10]~FromDigits~10                   

Out[3]= {100000, 20000, 3000, 400, 50, 6}

alephalpha

Posted 2016-05-01T03:03:53.863

Reputation: 23 988

Very unexpected use of DiagonalMatrix. Kindly explain how it works in this case. – DavidC – 2016-08-20T16:15:01.213

1

Mathematica, 12 bytes (non-competing)

I wonder whether Wolfram Research created this function after seeing the OP's challenge!

NumberExpand

This was introduced in version 11.0 (August, 2016).

DavidC

Posted 2016-05-01T03:03:53.863

Reputation: 24 524

1I edited to make this non-competing because Mathematica 11.0 was released on Aug 8. – Leaky Nun – 2016-08-20T16:11:53.237

0

Racket, 82 bytes

(define(d n b[a'()])(if(< n 1)a(d(/ n b)b(cons(*(modulo(floor n)b)(length a))a))))

I'm a winner (!)

Winny

Posted 2016-05-01T03:03:53.863

Reputation: 1 120

1So many spaces... does <n 1 not work? (I don't know Racket at all) – Leaky Nun – 2016-05-01T04:37:12.670

1No that wouldn't work -- identifiers are delimited only by whitespace, parentheses/braces/curly braces, and some other symbols, like '. It's a good question, though. – Winny – 2016-05-01T04:41:23.537

(And < is just a variable with a function bound to it) – Winny – 2016-05-01T04:41:54.113

0

JavaScript (ES7), 68 bytes

n=>b=>(c=[...n.toString(b)]).map(d=>b**--p*parseInt(d,b),p=c.length)

Test

Test uses Math.pow for browser compatibility.

f=n=>b=>(c=[...n.toString(b)]).map(d=>Math.pow(b,--p)*parseInt(d,b),p=c.length)
document.write("<pre>"+
[ [ 123456, 10 ], [ 11, 2 ], [ 727, 20 ], [ 101, 10 ] ]
.map(c=>c+" => "+f(c[0])(c[1])).join`\n`)

user81655

Posted 2016-05-01T03:03:53.863

Reputation: 10 181

** isn't a valid JavaScript operator though right? – ericw31415 – 2016-05-01T13:15:34.763

@ericw31415 It's the ES7 exponentiation operator.

– user81655 – 2016-05-01T13:21:54.423

Oh, it's experimental. That's why my browser does not support it. – ericw31415 – 2016-05-01T13:50:56.700

0

JavaScript, 75 bytes

(a,b)=>[...a.toString(b)].reverse().map(($,_)=>Math.pow(b,_)*parseInt($,b))

Just for fun :) It could be golfed more, but I'm not too sure how.

ES7, 66 bytes

If ES7 is allowed then:

(a,b)=>[...a.toString(b)].reverse().map(($,_)=>b**_*parseInt($,b))

ericw31415

Posted 2016-05-01T03:03:53.863

Reputation: 2 229

0

O, 17 bytes

jQb`S/l{#Qn^*p}d

Two notes:

  1. The third test case does not work due to a bug with base conversion. See phase/o#68.

  2. This does not work in the online interpreter. b hadn't been implemented yet.

kirbyfan64sos

Posted 2016-05-01T03:03:53.863

Reputation: 8 730

0

><>, 28 bytes

:&\
&*>:{:}$%:n$}-:0=?;ao$&:

Expects the input values to be present on the stack at program start.

As ><> doesn't have list objects, the output is presented as a newline-separated list of values, with the 'units' on the first line. An example run:

Input: 
11 2

Ouput:
1
2
0
8

@OP, if this isn't an acceptable output format, let me know and I'll edit the answer accordingly.

Sok

Posted 2016-05-01T03:03:53.863

Reputation: 5 592

0

PHP, 55 bytes

Uses Windows-1252 encoding.

for($n=$argv[1];$d+$n-=$d=$n%$argv[2]**++$i;)echo$d,~Ó;

Run like this (-d added for aesthetics only):

php -d error_reporting=30709 -r 'for($n=$argv[1];$d+$n-=$d=$n%$argv[2]**++$i;)echo$d,~Ó; echo"\n";' 123056 10

aross

Posted 2016-05-01T03:03:53.863

Reputation: 1 583

0

C#, 77 bytes

IEnumerable _(int n,int b){int m=1;while(n>0){yield return n%b*m;n/=b;m*=b;}}

Nick Mertin

Posted 2016-05-01T03:03:53.863

Reputation: 161

0

Actually, 17 bytes (non-competing)

;a¡;lrR(♀ⁿ@♂≈♀*;░

Try it online!

This submission is non-competing because the command was added after this challenge.

Explanation:

;a¡;lrR(♀ⁿ@♂≈♀*;░
                   initial stack: [b n] (b = base, n = number)
;                  dupe b
 a                 invert stack
  ¡                n as a base-b integer
   ;lrR            dupe, length, range, reverse
       (♀ⁿ         raise b to each power in range
          @♂≈      create list of integers from base-b string
             ♀*    pairwise multiplication
               ;░  filter out zeroes

Mego

Posted 2016-05-01T03:03:53.863

Reputation: 32 998

Surely there is a way to avoid ? (Golfed off four bytes) – Leaky Nun – 2016-08-21T02:45:00.213

0

Pip, 13 bytes

Wa-:Pa%oo*:b

Doing it the old-fashioned way turned out to be shorter than using the TB base-conversion operator. The code runs a while loop until a (the number) is 0. At each iteration, it prints a%o and subtracts it from a. o is preinitialized to 1 and gets multiplied by b (the base) each iteration. (This approach keeps all 0s and also adds a leading 0.)

Try it online!

DLosc

Posted 2016-05-01T03:03:53.863

Reputation: 21 213