Multiplicative undelta

9

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]

ბიმო

Posted 2018-10-06T15:53:07.170

Reputation: 15 345

May we take a single list of length 1+number of deltas, where the first item is a₀? – Adám – 2018-10-09T08:08:47.417

@Adám: I'm gonna say no to that because it would change things for existing answers. – ბიმო – 2018-10-09T09:15:00.940

Answers

17

Haskell, 8 bytes

scanl(*)

Try it online!

nimi

Posted 2018-10-06T15:53:07.170

Reputation: 34 639

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. – Windmill Cookies – 2018-10-07T07:06:57.260

9

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

×\,

Quintec

Posted 2018-10-06T15:53:07.170

Reputation: 2 801

2⊣,⊢ can just be , – H.PWiz – 2018-10-06T17:52:45.510

@H.PWiz thanks, my tacit is extremely weak – Quintec – 2018-10-06T17:54:03.480

You don't need the parens; ×\, evaluates to a function. – Dennis – 2018-10-06T17:54:19.470

@Dennis Doesn't seem to work unfortunately – Quintec – 2018-10-06T17:56:18.060

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). – Dennis – 2018-10-06T18:27:33.247

@Dennis I'm not really sure on this, but if it only works when defined as a function then wouldn't you need to include that definition in the bytecount, keeping it at 5? – Quintec – 2018-10-06T18:33:47.190

It has to work as a function (or a full program) to be valid. Snippets aren't allowed as submissions. – Dennis – 2018-10-06T18:36:18.990

Dennis is most probably trying to say that anonymous functions are allowed (they are). Parentheses are unnecessary; for example, we don't wrap Python lambdas in parentheses, they're not needed, similarly for Dyalog. Sure, lambda x:x+1(7) won't return 8 in Python, and (lambda x:x+1)(7) will, but f=lambda x:x+1 and then f(7) will return 8; the parentheses aren't part of the function. Note that this doesn't hold true for the {} (i.e. the lambda: part in Python) around dfns. – Erik the Outgolfer – 2018-10-06T18:38:18.113

@EriktheOutgolfer Got it, thanks. – Quintec – 2018-10-06T18:41:02.370

8

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!

Kirill L.

Posted 2018-10-06T15:53:07.170

Reputation: 6 693

5

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.

Giuseppe

Posted 2018-10-06T15:53:07.170

Reputation: 21 077

3

JavaScript (ES6), 27 bytes

Takes input as (m)(a).

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

Try it online!

Arnauld

Posted 2018-10-06T15:53:07.170

Reputation: 111 334

3

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

Shaggy

Posted 2018-10-06T15:53:07.170

Reputation: 24 623

3

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!

Quintec

Posted 2018-10-06T15:53:07.170

Reputation: 2 801

2

Jelly, 3 bytes

;×\

Try it online!

Erik the Outgolfer

Posted 2018-10-06T15:53:07.170

Reputation: 38 134

2

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}.

Misha Lavrov

Posted 2018-10-06T15:53:07.170

Reputation: 4 846

2

Perl 6, 9 bytes

{[\*] @_}

Try it online!

nwellnhof

Posted 2018-10-06T15:53:07.170

Reputation: 10 037

2

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]

Laikoni

Posted 2018-10-06T15:53:07.170

Reputation: 23 676

2

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

Galen Ivanov

Posted 2018-10-06T15:53:07.170

Reputation: 13 815

1*/\@, works exactly the same. – Bubbler – 2018-10-11T23:02:26.337

@Bubbler Yes, of course! Thank you! – Galen Ivanov – 2018-10-12T03:19:50.960

1

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.

Neil

Posted 2018-10-06T15:53:07.170

Reputation: 95 035

1

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

Jo King

Posted 2018-10-06T15:53:07.170

Reputation: 38 234

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. – maxb – 2018-11-27T11:42:29.157

1

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.

Steven H.

Posted 2018-10-06T15:53:07.170

Reputation: 2 841

1

You can save a byte by implementing the map in the second solution as R, as in *FR._s - demonstration

– Sok – 2018-10-08T10:27:37.430

@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. – Steven H. – 2018-10-09T01:51:10.717

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) – Sok – 2018-10-09T07:23:33.920

1

Common Lisp, 67 bytes

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

Try it online!

Renzo

Posted 2018-10-06T15:53:07.170

Reputation: 2 260

1

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.

Leo

Posted 2018-10-06T15:53:07.170

Reputation: 8 482

1

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]

Kevin Cruijssen

Posted 2018-10-06T15:53:07.170

Reputation: 67 575

1No, 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 – Kevin Cruijssen – 2018-10-08T14:42:54.757

1

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.

Steven H.

Posted 2018-10-06T15:53:07.170

Reputation: 2 841

1

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

Veskah

Posted 2018-10-06T15:53:07.170

Reputation: 3 580

Rules are: Output is a list/array/vector/. So, the first is fine. – mazzy – 2018-10-12T16:00:21.410

0

Python 2, 47 bytes

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

Try it online!

Chas Brown

Posted 2018-10-06T15:53:07.170

Reputation: 8 959

It may be of interest to you that a python solution is shorter in python 3 using generators – Quintec – 2018-10-07T23:34:28.073

0

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

Neil

Posted 2018-10-06T15:53:07.170

Reputation: 95 035

0

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]

Thaufeki

Posted 2018-10-06T15:53:07.170

Reputation: 421

0

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

eush77

Posted 2018-10-06T15:53:07.170

Reputation: 1 280