Miscellanea
April 26, 2011
We have three short exercises today.
FizzBuzz: Looking back over past exercises, I was surprised to find that we haven’t done this classic interview question. You are to write a function that displays the numbers from 1 to an input parameter n, one per line, except that if the current number is divisible by 3 the function should write “Fizz” instead of the number, if the current number is divisible by 5 the function should write “Buzz” instead of the number, and if the current number is divisible by both 3 and 5 the function should write “FizzBuzz” instead of the number. For instance, if n is 20, the program should write 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16, 17, Fizz, 19, and Buzz on twenty successive lines.
Prime Words: Consider that a word consisting of digits and the letters A through Z can represent an integer in base 36, where the digits represent their base-10 counterparts, A is a decimal 10, B is a decimal 11, and so on, until Z is a decimal 35. For instance, PRAXIS36 = P36 × 365 + R36 × 364 + A36 × 363 + X36 × 362 + I36 × 361 + S36 × 360 = 25 × 365 + 27 × 364 + 10 × 363 + 33 × 362 + 18 × 361 + 28 × 360 = 25 × 60466176 + 27 × 1679616 + 10 × 46656 + 33 × 1296 + 18 × 36 + 28 × 1 = 1557514036. You are to write a function that takes a base-36 number as input and returns true if the number is prime and false if the number is composite.
Split A List: You are to write a function that takes an input list and returns two lists, the first half of the input list and the second half of the input list. If the input list has an odd number of elements, it is your choice in which half to place the center element. You are only permitted to scan the list once.
Your task is to write the three functions described above. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
My try in REXX
[…] today’s Programming Praxis exercise, our goal is to write three fucntions: FizzBuzz, a function to […]
My Haskell solution (see http://bonsaicode.wordpress.com/2011/04/26/programming-praxis-miscellanea/ for a version with comments):
my implementation in c
Solution in Python (for simple tests look at github):
I have been trying to learn macros , so here is my code
using predicate dispatch paper, implemented using macros.
@Vikas Tandi – how about PrimeWords(“3”) and PrimeWords(“2”) :)
Oh and in my code instead of:
should be
My solution to “FizzBuzz”: write a generator “fizzer()” that accepts an argument list of the “fizz-buzz” parameters.
This is how you call it:
This is the output:
@arturasl – Thanks for pointing that out :(
This check should be added after decimal conversion
My Python solution, with multiple answers for each.
Some of it isn’t original, but I’m most proud of my list splitting and my use of Horner’s Method for
converting a word to a base 36 number (though Python’s
int()
provides all the functionality we need,anyway).
Here’s ruby versions of each. FizzBuzz is unimaginative, prime words is OK, split_list works for arrays, but I feel like it could be better.
@Graham – is_prime_word_horner will not work if you pass it word with digits:
Anyway neat solution, especially the usage of all() and reduce() q:-)
Here is an attempt in python
number = input(‘What number would you like to count to? ‘) + 1
whole = 0
fizzz = 0
buzzz = 0
def whole_number(num):
global whole
if num % 1 == 0:
whole = 1
else:
whole = 0
def fizz(num):
global fizzz
if num % 3 == 0:
fizzz = 1
else:
fizzz = 0
def buzz(num):
global buzzz
if num % 5 == 0:
buzzz = 1
else:
buzzz = 0
for N in range(1,number,1):
whole_number(N)
fizz(N)
buzz(N)
if fizzz is 1 and buzzz is 1:
print(‘FizzBuzz’)
elif buzzz is 1 and fizzz is 0:
print(‘Buzz’)
elif buzzz is 0 and fizzz is 1:
print(‘Fizz’)
else:
print(N)
Sorry I dont know how to retain the indentation and code look
Ryan Take a look at https://programmingpraxis.com/contents/howto-posting-source-code/. That should explain how to format your code. I was going to paste it in, but I’m pretty sure it wouldn’t do what I want.
@arturasl: Thanks for catching that. I only thought to work with letters, basing my
ord(y) - 55
off of the offset for the letters A through Z…Like I said, the use of Python’s integer
conversion is probably the preferred method—in this case, the only correct method :-)
—that I came up with. Thanks again!
A non-destructive solution without using reverse (in case that’s cheating):
(define (split xs)
(let loop ((xs xs) (rest xs))
(if (or (null? rest) (null? (cdr rest)))
(values ‘() xs)
(let-values (((first second) (loop (cdr xs) (cddr rest))))
(values (cons (car xs) first) second)))))
Err, I’ll try formatted:
Here’s my 2 cents:
FizzBuzz
Thought I’d do something different than the standard if-elif-type answer.
Prime Words
isprime() is from a prior exercise
Split A List
Uses deques to efficiently add/pop items from either end.
Basic idea is add each item in the list to the end of the ‘back’ half. Every other time an item is added to the back, an item
is popped off the front of the ‘back’ half and added to the ‘front’ half.
Tested in MIT Scheme
praxis.scm
Here’s my Ruby solution:
I feel I cheated a bit with my solution for the 3rd assignment because I’m not scanning the list in situ. Oh well… =)
Simple Haskell for FizzBuzz.
run n = mapM_ putStrLn $ take n $ zipWith (\a b -> if null b then show a else b) [1..] $ zipWith (++) (cycle ["","","Fizz"]) (cycle ["","","","","Buzz"])
Scheme.
In a table, I store a continuation that builds a list made of 1/ what’s on the stack, and 2/ what you give it, as well as the current rest of the list. Each time I scan one more element of the list, I put it on the stack (with CONS) and call myself recursively, after setting the continuation and the rest of the list in the table. When the list is empty, compute the middle index, fetch the continuation and rest at this time, save the rest somewhere, and call the continuation with ‘() to return the list up to the middle. Then assemble everything and you’re done. Lists of length 0 and 1 are edge cases.
(define (split l)
(define table (make-table))
(define cnt 0)
(define bottom '())
(define (aux l)
(if (null? l)
(case cnt
((0 1) '())
(else
(let* ((mid (floor (/ cnt 2)))
(val (table-ref table mid)))
(set! bottom (cdr val))
((car val) '()))))
(begin
(set! cnt (+ cnt 1))
(cons (car l)
(call/cc
(lambda (build-top)
(table-set! table cnt (cons build-top (cdr l)))
(aux (cdr l))))))))
(let ((res (aux l)))
(vector res bottom)))
Morally the same as above, but cleaner. Uses a hack (?) from gambit (4.2.8 in my test), the fact that ((lambda(x) x) (values a b)) will effectively return the two values.
(define (split l)
(define (aux l #!optional (table (make-table)) (cnt 1))
(if (null? l)
(let* ((mid (floor (/ cnt 2)))
(val (table-ref table mid (cons (lambda (x) x) '()))))
((car val) (values '() (cdr val))))
(call-with-values
(lambda ()
(call/cc
(lambda (build-top)
(table-set! table cnt (cons build-top (cdr l)))
(aux (cdr l) table (+ 1 cnt)))))
(lambda (val bot)
(values (cons (car l) val) bot)))))
(aux l))