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

# montxero's solution

## to Difference Of Squares in the Scheme Track

Published at Oct 28 2019 · 0 comments
Instructions
Test suite
Solution

#### Note:

This exercise has changed since this solution was written.

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

## Overview

Suppose you're solving halting-problem:

• Start a REPL, either in your favorite editor or from the command line.
• Type `(load "halting-problem.scm")` at the prompt.
• Test your code by calling `(test)` from the REPL. At first this should result in failed tests.
• Develop your solution in "halting-problem.scm" and reload the file to run the tests again.

## Testing options

You can see more information about failing test cases by passing arguments to the procedure `test`. To see the failing input call `(test 'input)` and to see the input and output together call `(test 'input 'output)`.

## 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

``````(define test-fields '(input output who))

(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)
(with-exception-handler
(lambda (e)
(k `(fail
(description . ,description)
(input . ,input)
(output . ,output)
(who . ,procedure))))
(lambda ()
(let ([result (test-run-solution procedure input)])
(unless (success-predicate result output)
(error 'exercism-test
"test fails"
description
input
result
output)))
`(pass . ,description))))))

(define (test-error description procedure input)
(call/cc
(lambda (k)
(with-exception-handler
(lambda (e) (k `(pass . ,description)))
(lambda ()
(test-run-solution procedure input)
`(fail
(description . ,description)
(input . ,input)
(output . error)
(who . ,procedure)))))))

(define (run-test-suite tests . query)
(for-each
(lambda (field)
(unless (and (symbol? field) (memq field test-fields))
(error 'run-test-suite
(format "~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!~%~%") 'success]
[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))])
(format #t "  - ~a: ~a~%" (car info) (cdr info))))
query))
failures)
(newline)
'failure])))

(define (test . args)
(apply
run-test-suite
(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)))
args))``````
``````;;;; difference-of-squares.scm
;;;; an exercism exercise

(import (rnrs (6)))

(define (square-of-sum n)
"return (1 + ... + n)^2"
(expt (/ (* n (+ n 1)) 2) 2))

(define (sum-of-squares n)
"return (1^2 + ... + n^2)"
(* (/ n 3) (+ n 1) (+ n 1/2)))

(define (difference-of-squares n)
"return square-of-sum n - sum-of-squares n"
(- (square-of-sum n) (sum-of-squares n)))``````