9
\$\begingroup\$

Let us define the "multiplicative deltas" of values \$[\; a_0, \cdots a_N, \;]\$ as:

$$ [\; a_1 / a_0, \cdots, a_{i+1} / a_i, \cdots, a_N / a_{N-1} \;] $$

The reverse operation - namely "multiplicative undelta" - returns values such that the above operation results in the given values.

Example

Given values \$[\; 1, 5, 3, 2 \;]\$ a general solution to the "multiplicative undelta" operation is:

$$ [\; a_0, \quad \underset{a_1}{\underbrace{a_0 \cdot 1}}, \quad \underset{a_2}{\underbrace{a_1 \cdot 5}}, \quad \underset{a_3}{\underbrace{a_2 \cdot 3}}, \quad \underset{a_4}{\underbrace{a_3 \cdot 2}} \;] $$

A particular solution can be obtained by setting \$a_0\$ to any value other than zero, for example by setting \$a_0 := 1 \$ we would get:

$$ [\; 1, 1, 5, 15, 30 \;] $$

Challenge

Your task for this challenge is to implement the operation "multiplicative undelta" as defined above.

Rules

Inputs are:

  • a non-zero value \$a_0\$
  • a non-empty list/array/vector/... of non-zero "multiplicative deltas"

Output is a list/array/vector/... of values such that the first element is \$a_0\$ and for which the "multiplicative deltas" are the input.

Note: If your language has no support of negative integers you may replace non-zero by positive.

Test cases

2 [21] -> [2,42]
1 [1,5,3,2] -> [1,1,5,15,30]
-1 [1,5,3,2] -> [-1,-1,-5,-15,-30]
7 [1,-5,3,2] -> [7,7,-35,-105,-210]
2 [-12,3,-17,1311] -> [2,-24,-72,1224,1604664]
-12 [7,-1,-12,4] -> [-12,-84,84,-1008,-4032]
1 [2,2,2,2,2,2,2,2] -> [1,2,4,8,16,32,64,128,256]
\$\endgroup\$
  • \$\begingroup\$ May we take a single list of length 1+number of deltas, where the first item is a₀? \$\endgroup\$ – Adám Oct 9 '18 at 8:08
  • \$\begingroup\$ @Adám: I'm gonna say no to that because it would change things for existing answers. \$\endgroup\$ – ბიმო Oct 9 '18 at 9:15

24 Answers 24

17
\$\begingroup\$

Haskell, 8 bytes

scanl(*)

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I was checking if anyone wrote this, and I thought noone wrote it and I said "cool, then I'll write" and then saw your answer at the bottom of the page. upvoted. \$\endgroup\$ – Windmill Cookies Oct 7 '18 at 7:06
9
\$\begingroup\$

APL(Dyalog), 3 bytes

×\∊

Try it online!

If I have to take the number on the left and the array on the right:

-2 thanks to @H.PWiz

7 5 3 bytes

×\,

\$\endgroup\$
  • 2
    \$\begingroup\$ ⊣,⊢ can just be , \$\endgroup\$ – H.PWiz Oct 6 '18 at 17:52
  • \$\begingroup\$ @H.PWiz thanks, my tacit is extremely weak \$\endgroup\$ – Quintec Oct 6 '18 at 17:54
  • \$\begingroup\$ You don't need the parens; ×\, evaluates to a function. \$\endgroup\$ – Dennis Oct 6 '18 at 17:54
  • \$\begingroup\$ @Dennis Doesn't seem to work unfortunately \$\endgroup\$ – Quintec Oct 6 '18 at 17:56
  • \$\begingroup\$ You don't need to count the parens, because they're not needed in some situations. f←×\ works, for example. Btw, the (-12 3 -17 1311) in your permalink should be (¯12 3 ¯17 1311). \$\endgroup\$ – Dennis Oct 6 '18 at 18:27
8
\$\begingroup\$

R, 15 bytes

cumprod(scan())

Try it online!

Full program. Function is longer (unless we were allowed to "glue" the inputs together, so that built-in cumprod would suffice as a complete answer):

R, 28 bytes

function(i,x)cumprod(c(i,x))

Try it online!

\$\endgroup\$
5
\$\begingroup\$

MATL, 3 bytes

hYp

Try it online!

            #implicit input, x_0 and A
h           #horizontally concatenate
Yp          #cumulative product
            #implicit output

The hYpe about MATL is real.

\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 27 bytes

Takes input as (m)(a).

m=>a=>[m,...a.map(x=>m*=x)]

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Japt, 3 bytes

å*V

Try it


Explanation

        :Implicit input of array U and integer V
å       :Cumulatively reduce U
 *      :By multiplication
  V     :With an initial value of V
\$\endgroup\$
3
\$\begingroup\$

Python 3, 39 bytes

def f(a,b):
    for x in[1]+b:a*=x;yield a

Alternative approach. Returns a generator.

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Jelly, 3 bytes

;×\

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Wolfram Language (Mathematica), 14 bytes

FoldList@Times

Try it online!

FoldList[Times, a0, {x1, x2, ..., xn}] produces the desired output. FoldList[Times] is the curried form that produces a pure function still waiting for its a0 and {x1, x2, ..., xn}.

\$\endgroup\$
2
\$\begingroup\$

Perl 6, 9 bytes

{[\*] @_}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Standard ML, 32 bytes

fun f(x::r)a=a::f r(a*x)|f&a=[a]

Try it online!

Ungolfed:

fun f (x::xr) a = a :: f xr (a*x)
  | f    _    a = [a]
\$\endgroup\$
2
\$\begingroup\$

J, 6 5 bytes

-1 byte thanks to Bubbler

*/\@,

Try it online!

Explanation:

A diadic verb, the left argument is a0, the rigth one - the vector

     @, - append the vector to a0 and 
  */\   - find the running product
\$\endgroup\$
1
\$\begingroup\$

Batch, 69 bytes

@set/pa=
@echo %a%
@for %%d in (%*) do @set/aa*=%%d&call echo %%a%%

Takes input of \$a_0\$ on STDIN and the deltas as command-line arguments.

\$\endgroup\$
1
\$\begingroup\$

Common Lisp, 67 bytes

(lambda(a l &aux(y 1))(mapcar(lambda(x)(setf y(* y x)))(cons a l)))

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Husk, 2 bytes

G*

Try it online!

This is equivalent to nimi's answer in Haskell: scanl(*), which means reduce from the left using multiplication, and return all partial results.

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 5 3 bytes

šηP

-2 bytes thanks to @BMO.

Try it online or verify all test cases.

Explanation:

š      # Prepend the (implicit) input-integer at the start of the (implicit) input-list
       #  i.e. -12 and [7,-1,-12,4] → ["-12",7,-1,-12,4]
 η     # Prefixes of this new list
       #  i.e. ["-12",7,-1,-12,4]
       #   → [["-12"],["-12",7],["-12",7,-1],["-12",7,-1,-12],["-12",7,-1,-12,4]]
  P    # Take the product of each inner list (and output implicitly)
       #  i.e. [["-12"],["-12",7],["-12",7,-1],["-12",7,-1,-12],["-12",7,-1,-12,4]]
       #   → [-12,-84,84,-1008,-4032]
\$\endgroup\$
  • 1
    \$\begingroup\$ No, the s was there to get the other input. :) s is swap, and š is prepending at the start of the list. Either way, thanks for the -2 \$\endgroup\$ – Kevin Cruijssen Oct 8 '18 at 14:42
1
\$\begingroup\$

Pyth, 6 bytes

*FR._s

Test that one here!

Alternatively, 7 bytes:

.u*NYEQ

Test it here!

The first takes input as a tuple, the second takes input as two separate lines.

Thanks to @Sok for helping me with getting good at mapping and saving 1 byte.

\$\endgroup\$
  • 1
    \$\begingroup\$ You can save a byte by implementing the map in the second solution as R, as in *FR._s - demonstration \$\endgroup\$ – Sok Oct 8 '18 at 10:27
  • \$\begingroup\$ @Sok Nice catch! I had tried M assuming it'd work, then got a sugar parse failure - mostly because I didn't remember how the parsing for F <pf2> worked. \$\endgroup\$ – Steven H. Oct 9 '18 at 1:51
  • \$\begingroup\$ I'll be honest, I don't really understand how nested M, F, L, and R work, I just tried a bunch until one worked :o) \$\endgroup\$ – Sok Oct 9 '18 at 7:23
1
\$\begingroup\$

Python 2, 40 bytes

f=lambda a,b:[a]+(b and f(a*b[0],b[1:]))

Try it online!

Surprisingly, the move to Python 3 and use of generators there only saves 1 byte over the recursive solution.

\$\endgroup\$
1
\$\begingroup\$

PowerShell, 29 bytes

param($a,$b)$a;$b|%{($a*=$_)}

Try it online!

This assumes just outputting the values is fine.

> .\scratch.ps1 1 (1,5,3,2)
1
1
5
15
30

If that's not fine, this actually builds the list and then pushes it to toString which prints the same way.

param($a,$b)$c=,$a;$b|%{$c+=$_*$c[-1]};$c #41 bytes
\$\endgroup\$
  • \$\begingroup\$ Rules are: Output is a list/array/vector/. So, the first is fine. \$\endgroup\$ – mazzy Oct 12 '18 at 16:00
1
\$\begingroup\$

MathGolf, 6 5 bytes

\{\o*

Try it online!

I think this could be 5 bytes (\{\o*) but \ instruction seems a little off when dealing with input. This is now fixed in the latest version.

Explanation:

\       Swap arguments, pushing both to stack
 {      Foreach loop over second argument
  \o    Output counter with newline
    *   Multiply counter by current element
        Implicitly output the last element
\$\endgroup\$
  • \$\begingroup\$ I have redesigned the handling of `` with implicit input. It still handles items on the stack the same way, but now it pops two elements from the input onto the stack instead of just one. I think it could be useful for this challenge. \$\endgroup\$ – maxb Nov 27 '18 at 11:42
0
\$\begingroup\$

Python 2, 47 bytes

lambda n,A:reduce(lambda a,c:a+[a[-1]*c],A,[n])

Try it online!

\$\endgroup\$
  • \$\begingroup\$ It may be of interest to you that a python solution is shorter in python 3 using generators \$\endgroup\$ – Quintec Oct 7 '18 at 23:34
0
\$\begingroup\$

Charcoal, 12 bytes

IE⁺⟦N⟧AΠ⊞Oυι

Try it online! Link is to verbose version of code. Explanation:

    N           Input a₀
   ⟦ ⟧          Wrap in a list
      A         Input deltas as a list
  ⁺              Concatenate lists
 E              Map over elements
           ι    Current element
          υ     Predefined empty list variable
        ⊞O      Push and return updated list
       Π        Product
I               Cast to string
                Implicitly print each value on its own line
\$\endgroup\$
0
\$\begingroup\$

K (oK), 9 bytes

{(*\)x,y}

Try it online!

Joins the first number to the second input as a list, and then returns successive results of multiplication

Test Cases

Enter your input after the function like below and then run, as I'm unsure how to use input properly for this language in TiO

{(*\)x,y}[1;1 5 3 2]
\$\endgroup\$
0
\$\begingroup\$

dc, 13 bytes

p[*pz1<A]dsAx

Try it online!

p[*pz1<A]dsAx
p               # Print the first element
  *p            # Multiply top elements on the stack
 [  z1<A]dsAx   # until only one element is left
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.