loading...

Daily Challenge #249 - Incremental Changes

thepracticaldev profile image dev.to staff ・1 min read

Implement an algorithm which increases number and returns the result. Start from number and increment by step as many times as iterations demands.
Input: number, iterations, step.

Example:
alg(2, 5, 10) => 2 + 10 + 10 + 10 + 10 + 10 = 52
alg(17, 3, 6) => 17 + 6 + 6 + 6 = 35

Tests:
alg(100, 5, 50)
alg(14, 20, 4)

Good luck!


Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Discussion

pic
Editor guide
 

In JS:

let alg = (( num, iter, step) => num + iter*step)
 
 

Clojure - Level 2 🌟🌟

(ns dailyChallenge.IncrementalChange249
  (^:level2))

;; recursive function w/ tail-end optimization
(defn algo [number, step, iterations]
  {:pre (>= iterations 1)}
    (let [accum 
            (loop [ result [number] itr iterations]
              (if (= 1 itr)
                (conj result step)
                (recur result (dec itr))))]
       (apply + accum))


(deftest test-algo
  (is (= 52 (algo 2 5 10))
  (is (= 35 (algo 17, 3, 6)))

(run-tests 'test-algo)
 

Compared to your "level 1", this is more like the question asked, since it asks for an algorithm rather than the answer. (I totally agree that it should be (+ number (* step iterations))).

In Clojure it's usually better to preference core functions, followed by reduce, followed by loop/recur.

The clojure.core function approach is just:

(defn algo
 [number step iterations]
 (->> number
      (iterate (partial + step))
      (drop iterations)
      first))

But that's really using iterate to do the algorithm part. So reduce might be more in the spirit of things. It's shorter too 🙂

(defn algo
 [number step iterations]
 (->> (repeat step)
      (take iterations)
      (reduce + number)))
 

Awesome breakdown! Thanks Paula. 🙏🏿

I feel like you're right on the hierarchy of abstraction to use for Clojure functions (there's just so many, and many of them are composed)._

I could've just used pure-recursion without loop/recur but I don't get the power of the AST's tail-end optimizer for loops. Thank you for reminding me of the thread-macro.

 

Thought I'd give this a try using plain lambda calculus. The notation is:

  • λx.t = Function taking x as an argument and producing the expression t. Can simplify λx.(λy.t) -> λx y.t
  • MN = Apply N to M
  • Application is left-associative, ex. MNO = (MN)O
0 = λf x.x
succ = λn f x. f (n f x)
add = λm n f x. m f (n f x)
mul = λm n f x. m (n f) x
alg = λn i s. add n (mul i s)

Example 1:

2 = succ (succ 0)
5 = succ (add 2 2)
10 = add 5 5
alg 2 5 10
--> λf x.f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f x)))))))))))))))))))))))))))))))))))))))))))))))))))
 

C

Assumed we always work with unsigned numbers for simplicity.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>

bool isUnsignedInteger(const char * string);

int main(int argumentsLength, char ** arguments) {
    if (argumentsLength != 4) {
        puts("Expected three arguments.");

        return EXIT_FAILURE;
    }

    if (!isUnsignedInteger(arguments[1])) {
        puts("Expected an unsigned number for the first argument.");

        return EXIT_FAILURE;
    }

    if (!isUnsignedInteger(arguments[2])) {
        puts("Expected an unsigned number for the second argument.");

        return EXIT_FAILURE;
    }

    if (!isUnsignedInteger(arguments[3])) {
        puts("Expected an unsigned number for the third argument.");

        return EXIT_FAILURE;
    }

    printf("%lld\n", atoll(arguments[1]) + atoll(arguments[2]) * atoll(arguments[3]));

    return EXIT_SUCCESS; 
}

bool isUnsignedInteger(const char * string) {
    for (const char * character = string; *character; character++) {
        if (!isdigit(*character)) {
            return false;
        }
    }

    return true;
}
$ gcc -Wall -Werror -Wpedantic -std=c11 -O3 main.c -o main
$ ./main 2 5 10
52
$ ./main 17 3 6
35
$ ./main 100 5 50
350
$ ./main 14 20 4
94
 

Clojure - Level 1 🌟

(ns dailyChallenge.IncrementalChange249
  (^:level1))

;; algebraic function
(defn algo [number, step, iterations]
  {:pre (>= iterations 1)}
    (+ number (* step iterations)))

(deftest test-algo
  (is (= 52 (algo 2 5 10))
  (is (= 35 (algo 17, 3, 6)))

(run-tests 'test-algo)
 

are we suppose to figure out the pattern and the answer to the algorithm? Or are we suppose to put it in some kind of computer language? i am a beginner... i know the answers but i am not sure how we do this challenge... could someone teach me?

 

yo Christine ✌🏿

  1. Adding the name of the language you're using is helpful.
  2. Finding unique or more efficient solutions is 🦄 unicorn worthy.

Implement an algorithm which increases number and returns the result. Start from number and increment by step as many times as iterations demands.
Input: number, iterations, step.

the keyword here is algorithm, so technically a psudo-code explanation would suffice.
The majority of these Daily Challenges expect an answer in a programming language, with tests.

 

oh i am a complete beginner all i know is html and css and i don't even know if they can be considered a language... but i was listening to a podcast on what algorithms were and she said that even a recipe is an algorithm so isn't an algorithm like a pattern, like in math? like maybe if the pattern is this then the answer is that?
i was just doing it in my head but i guess doing it in a language would be much more difficult but now i understand that you are looking for a way to make it simpler and more efficient right? i think i am still a little confused on this i will have to get more of an intro to algorithms before i try to crack any codes... thanks for being nice to the newbie!
Christine can i ask what an iteration is?

  1. I may be in the minority, but I'd consider CSS + HTML at least non-turing complete languages.👍🏿

  2. ...though it'd behoove you to graduate to a turing complete language like Ruby or JavaScript.

An algorithm is an unambiguous method of solving a specific problem. - Wiki

  1. An example of an algorithm is a recipe, correct. The opposite could be called a heuristic, but it's not a discrete line to draw now that Machine Learning uses some stochastics for it's results.

It's very exciting to see a beginner grappling with these concepts and potentially create fresh examples and metaphors.

  1. As far as the DC - an example of an iteration is a cycle. - Your washing machine has several spin cycles and probably saves the sequence in a list (or array). The machine iterates through each cycle in that list till the process (or algorithm) is complete. In this case, an iteration would be each 'pass' through some block of code that's looping either explicitly or recursively.

If nothing else, a well-worded recipe for getting the sum is valid. ✌🏿

 

In Python:

def alg(number, steps, iter_num):
    # make iteration for adding number
    for i in range(steps):
        number += iter_num

    return number

Another 'short'-cut:

# a 'short'-cut way
def alg(number, steps, iter_num):
    return number + steps * iter_num

Applying function

print(alg(100, 5, 50))    # 350
print(alg(14, 20, 4))      # 94
 

Not much of a challenge here, so I just used a GhostScript REPL:

GS>/alg { mul add } def
GS>2 5 10 alg ==
52
GS>
 

Go

func alg(number, iterator, step int) int {
    return number + iterator*step
}
 

in ruby

def alg(number, iteration, step)
  number + (iteration * step)
end
alg(100, 5, 50)
=> 350
alg(14, 20, 4)
=> 94
 

here's the solution in python :
Alt text of image

 

python answer:
def alg(add, mult, num):
return add + mult*num
JS answer:
alg = (num1, num2, num3) => num1 + num2 *num3;