How to make a cumulative sequence? - clojure

Say I have a lazy sequence like the following:
(def s (iterate inc 1))
(take 10 s)
=> (1 2 3 4 5 6 7 8 9 10)
Now, I want to generate a sequence of cumulative sum of s like the following:
=> (1 3 6 10 15 ...)
How can I do this?
What I tried is to use atom and accumulate the sum to it(mutating) Is this the only way to generate cumulative sequence or is there a better way to do this?
NOTE: the above cumulative sum is only an example. The source sequence can be other sequence. So I can't use formula: s(n) = n(n+1)/2

(take 10 (reductions + s))
=> (1 3 6 10 15 21 28 36 45 55)

Related

Getting MAX() of each row with an ARRAYFORMULA() [duplicate]

This question already has an answer here:
How to use arrayformula with formulas that do not seem to support arrayformulas?
(1 answer)
Closed 4 months ago.
Using an array formula I want to find the max value of each row of a range and get the resulting range to work with it further.
The problem occurs as soon as I add the MAX() statement since it does seem to behave strangely within an array formula. Even if you ad commands which will give you multiple values within the MAX() statement it does always only return one single value.
E.g. this will give you the ranges which I want to get the max of:
=ARRAYFORMULA(ADDRESS(ROW(E1:E11); COLUMN() + 1; 4) & ":" & ADDRESS(ROW(E1:E11); COLUMN() + 4; 4))
The result looks like the following:
F1:I1
F2:I2
F3:I3
F4:I4
F5:I5
F6:I6
F7:I7
F8:I8
F9:I9
F10:I10
F11:I11
If I now add INDIRECT() to make those to actual ranges and add MAX() it should return the max of each of those ranges since the array formula should go through the ROW(E1:11) as it did bevor. However, the result of this new formula
=ARRAYFORMULA(MAX(INDIRECT(ADDRESS(ROW(E1:E11); COLUMN() + 1; 4) & ":" & ADDRESS(ROW(E1:E11); COLUMN() + 4; 4))))
rather is one single value, the maximum of the first range.
I have even tried to bypass the problem by adding an IF() statement for the array formula to iterate through the rows. Doing so, it did give me a result for all 11 rows, however, the result always was the same (the max of the first row).
The new formula:
=ARRAYFORMULA(IF(ROW(E1:E11) = ROW(E1:E11); MAX(INDIRECT(ADDRESS(ROW(E1:E11); COLUMN() + 1; 4) & ":" & ADDRESS(ROW(E1:E11); COLUMN() + 4; 4))); ""))
The new result (left column are the results of the formula, trying to get the max of each row to its right):
10 7 10 4 1
10 10 8 1 2
10 4 5 9 4
10 10 10 2 2
10 10 10 5 10
10 10 6 9 5
10 4 5 7 3
10 6 9 4 7
10 5 5 7 3
10 9 2 3 10
10 10 3 9 10
=QUERY(TRANSPOSE(QUERY(TRANSPOSE(F1:I),
"select "&REGEXREPLACE(JOIN( , ARRAYFORMULA(IF(LEN(F1:F&G1:G&H1:H&I1:I),
"max(Col"&ROW(F1:F)-ROW(F1)+1&"),", ""))), ".\z", "")&"")),
"select Col2")

How to calculate Primes number

I'm trying to solve programming question, a term called "FiPrima". The "FiPrima" number is the sum of prime numbers before, until the intended prime tribe.
INPUT FORMAT
The first line is an integer number n. Then followed by an integer number x for n times.
OUTPUT FORMAT
Output n number of rows. Each row must contain the xth "FiPrima" number of each line.
INPUT EXAMPLE
5
1 2 3 4 5
OUTPUT EXAMPLE
2
5
10
17
28
EXPLANATION
The first 5 prime numbers in order are 2, 3, 5, 7 and 13.
So:
The 1st FiPrima number is 2 (2)
The 2nd FiPrima number is 5 (2 + 3)
The 3rd FiPrima number is 10 (2 + 3 + 5)
The 4th FiPrima number is 17 (2 + 3 + 5 + 7)
The 5th FiPrima number is 28 (2 + 3 + 5 + 7 + 13)
CONSTRAINTS
1 ≤ n ≤ 100
1 ≤ x ≤ 100
Can anyone create the code ?

Getting items from a list in Racket

I am wondering if in Racket I could get n number of items from a list I've already created. So lets say I made a list in Racket
(define base(list 1 2 3 4 5 6 7 8 9 10))
Now I want to define a function which will pick n number of items from this list and display them in a new list. So lets say n=4 I would want 4 random items from the base list I've made above. An example of the output im looking for would be
'(9 4 3 10)
Is there a way I can do this in Racket?
There are built-in procedures that literally do what you need: shuffling the list and taking n elements from it. Try this:
(define (take-n-random lst n)
(take (shuffle lst) n))
(define base (list 1 2 3 4 5 6 7 8 9 10))
(take-n-random base 4)
=> '(6 9 1 7)

LISP - sequence of integers

Does exist a function in LISP for making a sequence of integers like (0 1 2 3)?
I found make-sequence, but I didn't find out how to make a sequence of integers.
I tried make-list and nothing.
I know that in Scheme exists (build-list 5 (lambda (x) x)). I tried to change the build-list with make-list, but it didn't work.
Some ideas? Thanks
Edit: I need something like make-list 5 ==> (0 1 2 3 4)
Simply done with loop:
(loop :for n :below 10 :collect n)
; ==> (0 1 2 3 4 5 6 7 8 9)
The Alexandria library, which is intended to work on any conforming implementation of Common Lisp, defines iota:
(iota 5)
=> (0 1 2 3 4)
You can also customize start and step:
(iota 3 :start 1 :step 1.0)
=> (1.0 2.0 3.0)
But often you do not need to actually produce the list, you just want to iterate over the given range. That's why there is also map-iota:
(map-iota #'print 3 :start 1 :step 1.0)
=> 3
In such cases you can of course use LOOP:
(loop for i from 1.0 below 22 by 1.5 do (print i))
Instead of do, you can also collect and obtain a list; this is a bit more verbose than iota, but easier to customize.
Lets see if can still write mac lisp of the top of my head:
(defun foo (num acc)
(if (eq num 0)
acc
(foo (- num 1) (cons num acc))))
(foo 5 nil)
should be
(1 2 3 4 5)

Clojure reducers fold not calling combine function as expected

I'm experimenting with the clojure reducers library, and I'm a little confused as to when the combining function is called as part of the reducers/fold function. To see what was being called when, I created the below example:
(def input (range 1 100))
(defn combine-f
([]
(println "identity-combine")
0)
([left right]
(println (str "combine " left " " right))
(max (reduce max 0 left)
(reduce max 0 right))))
(defn reduce-f
([]
(println "identity-reduce")
0)
([result input]
(println (str "reduce " result " " input))
(max result input)))
(clojure.core.reducers/fold 10 combine-f reduce-f input)
;prints
identity-combine
reduce 0 1
reduce 1 2
reduce 2 3
reduce 3 4
.
.
.
reduce 98 99
I was expecting that when fold executes, the input would be partitioned into groups of approximately size 10, with each group reduced using reduce-f, and then combined using combine-f. However running the above code, it seems that the combine function is only called once as an identity, and the entire input reduced using reduce-f. Can anyone explain why I'm seeing this behaviour?
Thanks,
Matt.
Unfortunately, range cannot at the moment be realized in parallel. It seems there are foldable implementations around as an enhancement ticket, but I can't seem to find right now why they haven't been accepted. As is, folds over a range will always proceed like a straight reduce, except for the identity call to the combine operator. For comparison, a vector provides random access and so is foldable:
(def input (vec (range 1 50)))
(defn combine-f
([]
(println "identity-combine")
Long/MIN_VALUE)
([left right]
(println (str "combine " left " " right))
(max left right)))
(defn reduce-f
([]
(println "identity-reduce")
Long/MIN_VALUE)
([result input]
(println (str "reduce " result " " input))
(max result input)))
(clojure.core.reducers/fold 10 combine-f reduce-f input)
with output:
identity-combineidentity-combineidentity-combine
reduce -9223372036854775808 1
reduce -9223372036854775808 25reduce -9223372036854775808 19
reduce -9223372036854775808 13reduce 25 26
reduce 26 27
reduce 1 2
reduce 27 28
reduce 28 29
reduce 29 30
reduce 2 3
reduce 19 20
reduce 3 4
identity-combinereduce 4 5
reduce 5 6reduce 13 14
reduce 14 15
reduce 20 21identity-combine
reduce 21 22
reduce 15 16
reduce -9223372036854775808 31
reduce 22 23reduce 16 17reduce -9223372036854775808 7
reduce 7 8
reduce 8 9
reduce 23 24
reduce 31 32
reduce 17 18
reduce 9 10
reduce 10 11
reduce 11 12
identity-combine
reduce 32 33
combine 18 24
combine 6 12identity-combine
reduce -9223372036854775808 37
reduce 33 34
reduce 37 38reduce -9223372036854775808 43
combine 12 24
reduce 43 44reduce 34 35reduce 38 39
reduce 44 45
reduce 35 36
reduce 45 46
reduce 39 40
reduce 46 47
combine 30 36
reduce 47 48
reduce 48 49
reduce 40 41
reduce 41 42
combine 42 49
combine 36 49
combine 24 49
which you may notice is a lot more jumbled because of non-serialized accessing of *out*.
(I needed to alter combine-f a little because it was trying and failing to reduce over a single long. Switching to Long/MIN_VALUE doesn't affect this example much but is the identity element of max over longs, so I figured why not?).