Skip to content

Instantly share code, notes, and snippets.

@kohyama
Created October 23, 2012 05:37
Show Gist options
  • Save kohyama/3936925 to your computer and use it in GitHub Desktop.
Save kohyama/3936925 to your computer and use it in GitHub Desktop.
Exercise 01 FizzBuzz
(defn fizz-buzz [n]
(map #(cond (zero? (mod % 15)) "FizzBuzz"
(zero? (mod % 5)) "Buzz"
(zero? (mod % 3)) "Fizz"
:else %)
(range 1 (inc n))))
(fizz-buzz 100)
; -> (1 2 "Fizz" 4 "Buzz" "Fizz" 7 8 "Fizz" "Buzz" 11 "Fizz" 13 14 "FizzBuzz"
; 16 17 "Fizz" 19 "Buzz" "Fizz" 22 23 "Fizz" "Buzz" 26 "Fizz" 28 29 "FizzBuzz"
; 31 32 "Fizz" 34 "Buzz" "Fizz" 37 38 "Fizz" "Buzz" 41 "Fizz" 43 44 "FizzBuzz"
; 46 47 "Fizz" 49 "Buzz" "Fizz" 52 53 "Fizz" "Buzz" 56 "Fizz" 58 59 "FizzBuzz"
; 61 62 "Fizz" 64 "Buzz" "Fizz" 67 68 "Fizz" "Buzz" 71 "Fizz" 73 74 "FizzBuzz"
; 76 77 "Fizz" 79 "Buzz" "Fizz" 82 83 "Fizz" "Buzz" 86 "Fizz" 88 89 "FizzBuzz"
; 91 92 "Fizz" 94 "Buzz" "Fizz" 97 98 "Fizz" "Buzz")
fizzBuzz n = map fizzBuzz' [1..n]
where
fizzBuzz' x
| mod x 15 == 0 = "FizzBuzz"
| mod x 5 == 0 = "Buzz"
| mod x 3 == 0 = "Fizz"
| otherwise = show x
fizzBuzz 100
-- -> ["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14",
-- "FizzBuzz","16","17","Fizz","19","Buzz","Fizz","22","23","Fizz","Buzz","26",
-- "Fizz","28","29","FizzBuzz","31","32","Fizz","34","Buzz","Fizz","37","38",
-- "Fizz","Buzz","41","Fizz","43","44","FizzBuzz","46","47","Fizz","49","Buzz",
-- "Fizz","52","53","Fizz","Buzz","56","Fizz","58","59","FizzBuzz","61","62",
-- "Fizz","64","Buzz","Fizz","67","68","Fizz","Buzz","71","Fizz","73","74",
-- "FizzBuzz","76","77","Fizz","79","Buzz","Fizz","82","83","Fizz","Buzz","86",
-- "Fizz","88","89","FizzBuzz","91","92","Fizz","94","Buzz","Fizz","97","98",
-- "Fizz","Buzz"]
function fizzBuzz (n) {
var i, a = [];
for (i = 1; i < n + 1; i++)
a.push((function (x) {
if (Math.floor(x/15) == x/15)
return "FizzBuzz";
else if (Math.floor(x/5) == x/5)
return "Buzz";
else if (Math.floor(x/3) == x/3)
return "Fizz";
else
return x;
})(i));
return a;
}
fizzBuzz(100);
// -> [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14,
// 'FizzBuzz', 16, 17, 'Fizz', 19, 'Buzz', 'Fizz', 22, 23, 'Fizz', 'Buzz', 26,
// 'Fizz', 28, 29, 'FizzBuzz', 31, 32, 'Fizz', 34, 'Buzz', 'Fizz', 37, 38,
// 'Fizz', 'Buzz', 41, 'Fizz', 43, 44, 'FizzBuzz', 46, 47, 'Fizz', 49, 'Buzz',
// 'Fizz', 52, 53, 'Fizz', 'Buzz', 56, 'Fizz', 58, 59, 'FizzBuzz', 61, 62,
// 'Fizz', 64, 'Buzz', 'Fizz', 67, 68, 'Fizz', 'Buzz', 71, 'Fizz', 73, 74,
// 'FizzBuzz', 76, 77, 'Fizz', 79, 'Buzz', 'Fizz', 82, 83, 'Fizz', 'Buzz', 86,
// 'Fizz', 88, 89, 'FizzBuzz', 91, 92, 'Fizz', 94, 'Buzz', 'Fizz', 97, 98,
// 'Fizz', 'Buzz' ]
(define (1ton n)
(letrec
((nto1
(lambda (n)
(cond ((zero? n) '())
(else (cons n (nto1 (- n 1))))))))
(reverse (nto1 n))))
; -> 1ton
(1ton 3) ; -> (1 2 3)
(define (fizz-buzz n)
(map (lambda (x)
(cond ((zero? (remainder x 15)) "FizzBuzz")
((zero? (remainder x 5)) "Buzz")
((zero? (remainder x 3)) "Fizz")
(else x)))
(1ton n)))
; -> fizz-buzz
(fizz-buzz 100)
; -> (1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
; 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz
; 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz
; 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz
; 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz
; 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz
; 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz)
;; To create a list with consequent numbers, a more general
;; function 'iota' is formulated by srfi-1
;; Please search what SRFI is and how to load modules
;; on your processors and load srfi-1
;; Gauche: (use srfi-1)
;; Racket(R5RS): (require srfi/1)
;; You can use '(iota 100 1)' instead of '(1ton 100)'
;; Use 'mod' to get remainder of division
(mod 5 3) ; -> 2
(mod 6 3) ; -> 0
;; Use 'zero?' to check if the arugment equals to 0
(zero? (mod 5 3)) ; -> false
(zero? (mod 6 3)) ; -> true
;; Use 'fn' to describe function literals
((fn [x] (* x x)) 3) ; -> 9
;; You can also use '#' to describe a function literal
;; arguments can be referred by '%', '%2', '%3' and so on
;; Functions with 'fn' can be nested
;; Functions with '#' cannot be nested
(#(* % %) 3) ; -> 9
;; Use 'map' to apply a function to all elements of a list
(map #(* % %) '(1 2 3 4)) ; -> (1 4 9 16)
;; Use 'def' to name something
(def a 3) ; #'user/a
a ; -> 3
;; Of course, you can name a function
(def square (fn [x] (* x x))) ; -> #'user/square
(square 3) ; -> 9
(square 4) ; -> 16
;; If one you want to name is a function,
;; you can also use 'defn' form, which is transformed
;; to a form using 'def' and 'fn' in compile time
(defn square [x] (* x x)) ; -> #'user/square
(square 3) ; -> 9
(square 4) ; -> 16
;; Use 'cond' to branch code according to conditions
;; forms following 'cond' is recognized as paris of
;; a condition and a result
;; and the first result form of a true condition
;; is evaluated
;; ':else' keyword is true if it evaluated as a boolean,
;; so write default form with a condition ':else'.
(cond true 1
false 2
:else 3) ; -> 1
(cond false 1
true 2
:else 3) ; -> 2
(cond false 1
false 2
:else 3) ; -> 3
(#(cond (= x 1) :a (= x 2) :b :else :c) 1) ; -> :a
(#(cond (= x 1) :a (= x 2) :b :else :c) 2) ; -> :b
(#(cond (= x 1) :a (= x 2) :b :else :c) 3) ; -> :c
;; Use 'range' to create a list of consequent numbers
;; With one argument, returns a list of numbers
;; from 0 to the maximum integer less than the argument
(range 3) ; -> (0 1 2)
;; With two argument, returns a list of numbers
;; from the first argument to the maximum integer less than the
;; second argument
(range 3 7) ; -> (3 4 5 6)
;; Use 'inc' to increment an integer
(inc 1) ; -> 2
(inc 2) ; -> 3
;; Now you can write a function 'fizz-buzz', which accepts
;; the end number and returns a specified sequence as a list.
-- to be written
// Only the type of double precision floating point
// is used for all numbers
// Use 'Math.floor' to get the maximum integral number
// which is less than or equals to the argument.
Math.floor(3.1); // -> 3
5/3; // -> 1.6666666666666667
Math.floor(5/3); // -> 1
// To check if an natural number can be divided by another
// natural number, do like below
Math.floor(5/3) == 5/3; // -> false
Math.floor(6/3) == 6/3; // -> true
// Use 'function' to write a function literal
(function (x) { return x*x; })(3); // -> 9
// 'function (x) { return x*x; }' is a function literal,
// '(' and ')' surrounds the function literal is to be
// recognized as an object
// and '(3)' is to be called the object as a function
// with the argument '3'.
// Use 'var' to declare a name to be used in the current scope.
// Use '=' to name anything a declared name.
var a;
a = 3;
a; // -> 3
a = 4;
a; // -> 4
b; // ReferenceError: b is not defined
(function (x) { var a; a = 2; return x*2; })(3); // -> 6
a; // -> 4
// To declare a name and name anything the name in a time,
// do like below
var b = 5;
b; // -> 5
// Of course, you can name a function literal and can call it
// with the name
var square = function (x) { return x*x; };
square(3); // -> 9
// If what you give a name is a function, you can also write
// like this
function cube (x) { return x*x*x; };
cube(3); // -> 27
// Use '[]' and ',' (comma) to write an array literal
[3, 1, 4, 1, 5]; // -> [3, 1, 4, 1, 5]
// Use the method 'push' to add anything at the end of an array
[3, 1, 4, 1, 5].push(9); // -> 6
// The method push doesn't return the new array, but returns
// the new length of array.
// You can't refer the new array itself unless if you give
// the original array a name
var c = [3, 1, 4, 1, 5]; // -> [3, 1, 4, 1, 5]
c.push(9); // -> 6
c; // -> [3, 1, 4, 1, 5, 9]
// The empty array is '[]'
c = []; // -> []
c.push('Hello'); // -> 1
c; // -> ['Hello']
// Use 'for' to create a loop with
// what is done initially,
// what is the condition to continue the loop and
// what is done the end of the loop body
var i, a = [];
for (i = 0; i < 10; i++)
a.push(i*i);
// -> 10
a; // -> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
// Now you can write a function 'fizzBuzz', which accept a
// natural number as the argument and returns FizzBuzz
// sequence to the number as an array.
;; Use 'remainder' to get the remainder of division of the first argument by the
;; second argument
(remainder 5 3) ; -> 2
(remainder 6 3) ; -> 0
;; Use 'zero?' to check if the first argument equals to 0 or not
;; '#f' and '#t' represent the boolean values false and true respectively
(zero? (remainder 5 3)) ; -> #f
(zero? (remainder 6 3)) ; -> #t
;; Use 'lambda' to describe function literals
;; You can use lambda forms as a function
((lambda (x) (* x x)) 2) ; -> 4
((lambda (x) (* x x)) 3) ; -> 9
;; Use 'cond' to branch codes according to conditions
((lambda (x) (cond ((zero? x) "Foo") (else x))) 2) ; -> 2
((lambda (x) (cond ((zero? x) "Foo") (else x))) 0) ; -> "Foo"
;; Use 'map' to apply a function to all elements of a list
(map (lambda (x) (* x x)) '(1 2 3 4)) ; -> (1 4 9 16)
;; You can write a fizz-buzz process with a literal list from 1 to
;; the end number
(map (lambda (x)
(cond ((zero? (remainder x 15)) "FizzBuzz")
((zero? (remainder x 5)) "Buzz")
((zero? (remainder x 3)) "Fizz")
(else x)))
'(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20))
; -> (1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
; 16 17 Fizz 19 Buzz)
;; Use 'define' to give a global name to a literal of any type
(define a 3) ; -> a
a ; -> 3
;; Of course you can give a name to a function literal with 'define'
(define square (lambda (x) (* x x))) ; -> square
;; and can call it with the name
(square 2) ; -> 4
(square 3) ; -> 9
;; If what you give a name is a function, you can also use 'define'
;; like below
(define (square x) (* x x)) ; -> square
(square 2) ; -> 4
(square 3) ; -> 9
;; Use 'cons' to create a new list having the first argument as a head of
;; the new list and the second argument as a rest of the new list
;; '() represents a list with no elements
(cons 1 '()) ; -> (1)
(cons 2 '(1)) ; -> (2 1)
(cons 3 '(2 1)) ; -> (3 2 1)
(cons 3 (cons 2 (cons 1 (cons '())))) ; -> (3 2 1)
(cons 3 (cons (- 3 1) (cons (- (- 3 1) 1) '()))) ; -> (3 2 1)
;; Below is a function to create a list of integers from the given
;; integer down to 1
(define (nto1 n)
(cond ((zero? n) '())
(else (cons n (nto1 (- n 1)))))) ; -> nto1
(nto1 3) ; -> (3 2 1)
;; Use 'reverse' to get a new list with same but in a reversed order
;; elements as the argument
(reverse '(3 2 1)) ; -> (1 2 3)
;; Now you can create a list of integers from 1 up to the given number
(reverse (nto1 3)) ; -> (1 2 3)
;; You may want not to consume any global names for an intermediate function
;; Use 'let' to give a local name to anything
a ; -> 3
(let ((a 4)) a) ; -> 4
(let ((a 4) (b 5))
(* a b)) ; -> 20
a ; -> 3
b ; ERROR: unbound variable: b
;; You can't use a name in the definition body of the name with 'let'
(let ((nto1 (lambda (n)
(cond ((zero? n) '())
(else (cons n (nto1 (- n 1))))))))
(nto1 3))
; -> ERROR: unbound variable: nto1
;; Use 'letrec' to use a name in the definition body of the name
(letrec
((nto1
(lambda (n)
(cond ((zero? n) '())
(else (cons n (nto1 (- n 1))))))))
(nto1 3))
; -> (3 2 1)
;; Now you can write a function '1ton' to create a list of natural numbers
;; from 1 up to the given number.
;; And you can write a 'fizz-buzz' function using '1ton'

Get natural numbers from 1 to the given number, but replace numbers can be divided by 3 with "Fizz", numbers can be divided by 5 with "Buzz" and numbers can be divided by both 3 and 5 with "FizzBuzz".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment