Upside Up
May 27, 2011
An “upside up” number is a number that reads the same when it is rotated 180°. For instance, 689 and 1961 are upside up numbers.
Your task is to find the next upside up number greater than 1961, and to count the number of upside up numbers less than ten thousand. 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.
[…] today’s Programming Praxis exercise, our task is to write a function to determine if a number remains the […]
My Haskell solution (see http://bonsaicode.wordpress.com/2011/05/27/programming-praxis-upside-up/ for a version with comments):
My Python solution:
I went through at least 3 different versions of
is_upside_up
, making my solution less complicated each time; the first version was an imperative-style mess!My Try in REXX
/*
First No. > 1691 = 1881
there are 12 upside up numbers between 1 and 10000
*/
and the Swap-Routine
Sorry, copied confusing tries, this should be it:
My solution is pretty similar to Graham’s:
An inelegant solution to show them all for validation:
print [i for i in range(10000) if set(str(i)).issubset(‘01689’) and str(i)[::-1].replace(‘6′,’x’).replace(‘9′,’6’).replace(‘x’,’9′)==str(i)]
;;; Common Lisp:
;; 5 and 2 are clearly symetrical, as any 2¢ pocket calculator will
;; show you:
;;
;; _ _
;; |_ _|
;; _| |_
;;
;; But since the concensus seems to be to ignore them:
(defparameter *symetric-digits*
#((#\0) (#\1) () () () () (#\9) () (#\8) (#\6))
“A vector indexed by digits, containing lists of symetrical digits.”)
(defun upside-down-digit-p (a b)
(member a (aref *symetric-digits* (digit-char-p b))))
(defun upside-down-number-p (n &optional (base 10.))
(loop
:with digits = (format nil “~VR” base n)
:with last-index = (1- (length digits))
:for i :from 0 :to (truncate (length digits) 2)
:always (upside-down-digit-p (aref digits i) (aref digits (- last-index i)))))
(defun programming-praxis-2011-05-27 ()
(loop
:with first-upside-down = nil
:with count = 0
:for n :from 1962 :below 10000
:do (when (upside-down-number-p n)
(unless first-upside-down
(setf first-upside-down n))
(incf count))
:finally (return (values first-upside-down count))))
(programming-praxis-2011-05-27)
–> 6009
15
Cheating a bit by looking at the Python programs, but here’s one in Ruby …
Another variant using python:
[…] 출처: https://programmingpraxis.com/2011/05/27/upside-up/ […]
Factor Programming language
( scratchpad ) 10000 iota [ upside-up? ] filter length .
39
For grins, here’s a Erlang implementation. I’m new to Erlang, so I’m sure there are other, better, ways to do it.
I don’t understand why, sometimes, even though submission went good, the comment won’t show up…
;; Scheme
(define (upside-char=? x y)
(let ((yy (assoc x
'((#\0 #\0) (#\1 #\1) (#\2 #\5) (#\5 #\2) (#\6 #\9)
(#\8 #\8) (#\2 #\5)))))
(and yy (char=? y (cadr yy)))))
;
(define (upside-down? n)
(let* ((s (number->string n))
(l (string-length s)))
(let loop ((i 0) (j (1- l)))
(if (< i j)
(and
(upside-char=? (string-ref s i)
(string-ref s j))
(loop (1+ i) (1- j)))
(or (and (member (string-ref s i) '(#\0 #\1 #\8)) #t)
(> i j))))))
I went with building upside up numbers instead of looping 10,000 times and checking each one
//C# Solution.
for (int i = 1961; i x == ‘1’ ||x == ‘6’ || x == ‘8’ ||x == ‘9’ ||x == ‘0’);
foreach (var item in j)
{
topupNo += item;
}
if (topupNo == i.ToString())
{
Console.WriteLine(i.ToString());
}
}
//C# Solution
. for (int i = 1961; i <= 10000; i++) {
string topupNo = string.Empty; var j = i.ToString().Replace("6", "T").Replace("9",
"6").Replace("T", "9").Reverse().Where(x => x == '1' ||x == '6' || x == '8' ||x
== '9' ||x == '0');
foreach (var item in j) { topupNo += item; }
if (topupNo == i.ToString()) { Console.WriteLine(i.ToString()); } }
Just cause there isn’t a version in Go yet.. It’s simple, but gets the job done: