ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# aeugh's solution

## to Difference Of Squares in the Scheme Track

Published at Feb 08 2021 · 0 comments
Instructions
Test suite
Solution

Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.

The square of the sum of the first ten natural numbers is (1 + 2 + ... + 10)Â² = 55Â² = 3025.

The sum of the squares of the first ten natural numbers is 1Â² + 2Â² + ... + 10Â² = 385.

Hence the difference between the square of the sum of the first ten natural numbers and the sum of the squares of the first ten natural numbers is 3025 - 385 = 2640.

You are not expected to discover an efficient solution to this yourself from first principles; research is allowed, indeed, encouraged. Finding the best algorithm for the problem is a key skill in software engineering.

## Running and testing your solutions

### From the command line

Simply type `make chez` if you're using ChezScheme or `make guile` if you're using GNU Guile. Sometimes the name for the scheme binary on your system will differ from the defaults. When this is the case, you'll need to tell make by running `make chez chez=your-chez-binary` or `make guile guile=your-guile-binary`.

### From a REPL

• Enter `(load "test.scm")` at the repl prompt.
• Develop your solution in `difference-of-squares.scm` reloading as you go.
• Run `(test)` to check your solution.

### Failed Test Cases

If some of the test cases fail, you should see the failing input and the expected output. The failing input is presented as a list because the tests call your solution by `(apply difference-of-squares input-list)`. To learn more about `apply` see The Scheme Programming Language -- Chapter 5

## Source

Problem 6 at Project Euler http://projecteuler.net/problem=6

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### test.scm

``````(import (except (rnrs) current-output-port))

(define test-fields '(input output))

(define (test-run-solution solution input)
(if (procedure? solution) (apply solution input) solution))

(define (test-success description success-predicate
procedure input output)
(call/cc
(lambda (k)
(let ([out (open-output-string)])
(with-exception-handler
(lambda (e)
(let ([result `(fail
(description . ,description)
(input . ,input)
(output . ,output)
(stdout . ,(get-output-string out)))])
(close-output-port out)
(k result)))
(lambda ()
(let ([result (parameterize ([current-output-port out])
(test-run-solution procedure input))])
(unless (success-predicate result output)
(error 'exercism-test
"test fails"
description
input
result
output)))
(let ([result `(pass
(description . ,description)
(stdout . ,(get-output-string out)))])
(close-output-port out)
result)))))))

(define (test-error description procedure input)
(call/cc
(lambda (k)
(let ([out (open-output-string)])
(with-exception-handler
(lambda (e)
(let ([result `(pass
(description . ,description)
(stdout . ,(get-output-string out)))])
(close-output-port out)
(k result)))
(lambda ()
(parameterize ([current-output-port out])
(test-run-solution procedure input))
(let ([result `(fail
(description . ,description)
(input . ,input)
(output . error)
(stdout . ,(get-output-string out)))])
(close-output-port out)
result)))))))

(define (run-test-suite tests . query)
(for-each
(lambda (field)
(unless (and (symbol? field) (memq field test-fields))
(error 'run-test-suite
(format #t "~a not in ~a" field test-fields))))
query)
(let-values ([(passes failures)
(partition
(lambda (result) (eq? 'pass (car result)))
(map (lambda (test) (test)) tests))])
(cond
[(null? failures) (format #t "~%Well done!~%~%")]
[else
(format
#t
"~%Passed ~a/~a tests.~%~%The following test cases failed:~%~%"
(length passes)
(length tests))
(for-each
(lambda (failure)
(format
#t
"* ~a~%"
(cond
[(assoc 'description (cdr failure)) => cdr]
[else (cdr failure)]))
(for-each
(lambda (field)
(let ([info (assoc field (cdr failure))])
(display "  - ")
(write (car info))
(display ": ")
(write (cdr info))
(newline)))
query))
failures)
(error 'test "incorrect solution")])))

(define (run-docker test-cases)
(write (map (lambda (test) (test)) test-cases)))

(define sum-of-squares)

(define difference-of-squares)

(define square-of-sum)

(define test-cases
(list
(lambda ()
(test-success "square of sum 1" = square-of-sum '(1) 1))
(lambda ()
(test-success "square of sum 5" = square-of-sum '(5) 225))
(lambda ()
(test-success "square of sum 100" = square-of-sum '(100)
25502500))
(lambda ()
(test-success "sum of squares 1" = sum-of-squares '(1) 1))
(lambda ()
(test-success "sum of squares 5" = sum-of-squares '(5) 55))
(lambda ()
(test-success "sum of squares 100" = sum-of-squares '(100)
338350))
(lambda ()
(test-success "difference of squares 1" =
difference-of-squares '(1) 0))
(lambda ()
(test-success "difference of squares 5" =
difference-of-squares '(5) 170))
(lambda ()
(test-success "difference of squares 100" =
difference-of-squares '(100) 25164150))))

(define (test . query)
(apply run-test-suite test-cases query))

(let ([args (command-line)])
(cond
[(null? (cdr args))
(test 'input 'output)]
(run-docker test-cases)]
``````(import (rnrs))

(define (square-of-sum n)
(define sum
(/ (* n (+ n 1))
2))
(* sum sum))

(define (sum-of-squares n)
(/ (* n
(+ n 1)
(+ (* 2 n) 1))
6))

(define (difference-of-squares n)
(define (abs x)
(if (< x 0) (- x) x))
(abs (- (square-of-sum n) (sum-of-squares n))))``````