## Upside Up

### May 27, 2011

This is an easy exercise for a lazy late-spring Friday afternoon. We take 0, 1, 6, 8 and 9 as the possible upside up digits:

`(define (upside-up d)`

(case d ((0) 0) ((1) 1) ((6) 9) ((8) 8) ((9) 6) (else #f)))

Then we map over the digits of the input, report `#f`

if any have no upside, then recombine and check if the number is the same as its upside up reversal:

`(define (upside-up? n)`

(let ((ds (map upside-up (digits n))))

(if (member #f ds) #f

(= (undigits (reverse ds)) n))))

The next upside up number after 1961 is 6009, and there are 39 upside up numbers less than ten thousand:

`> (let loop ((n 1962))`

(if (upside-up? n) n

(loop (+ n 1))))

6009

> (length (filter upside-up? (range 10000)))

39

We used `range`

, `filter`

, `digits`

, and `undigits`

from the Standard Prelude. You can run the program at http://programmingpraxis.codepad.org/VYkXm2GM.

Pages: 1 2

[…] 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: