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

# scottviteri's solution

## to Difference Of Squares in the Scheme Track

Published at Nov 01 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

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

## 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 (rnrs))

(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 #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))])
(format #t "  - ~a: ~a~%" (car info) (cdr info))))
query))
failures)
(error 'test "incorrect solution")])))

(define sum-of-squares)

(define difference-of-squares)

(define square-of-sum)

(define (test . query)
(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)))
query))

(let ([args (command-line)])
(if (null? (cdr args))
(test 'input 'output))``````
``````(import (rnrs))
(use-modules ((srfi srfi-1) #:prefix srfi-1:))

(define (square x) (* x x))
(define (sum x) (srfi-1:fold + 0 x))
(define (range n) (srfi-1:iota n 1))

(define square-of-sum
(compose square sum range))

(define sum-of-squares
(compose sum (lambda (l) (srfi-1:map square l)) range))

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