The challenge
Consider the numbers 6969
and 9116
. When you rotate them 180 degrees
(upside down), these numbers remain the same. To clarify, if we write them down on a paper and turn the paper upside down, the numbers will be the same. Try it and see! Some numbers such as 2
or 5
don’t yield numbers when rotated.
Given a range, return the count of upside down numbers within that range. For example, solve(0,10) = 3
, because there are only 3
upside down numbers >= 0 and < 10
. They are 0, 1, 8
.
More examples in the test cases.
The solution in Java code
Option 1 (using IntStream
):
import java.util.stream.IntStream; import org.apache.commons.lang3.StringUtils; public class UpsideDown { public int solve(int x, int y) { return (int) IntStream.range(x, y) .filter(i -> !StringUtils.containsAny(String.valueOf(i), "23457")) .filter(i -> new StringBuilder(i + "").reverse().toString() .replaceAll("6", "2") .replaceAll("9", "6") .replaceAll("2", "9") .equals(String.valueOf(i))) .count(); } }
Option 2 (using UnaryOperator
):
import java.util.function.UnaryOperator; import static java.util.stream.IntStream.range; public class UpsideDown { public int solve(int x, int y) { UnaryOperator<String> upside = s -> new StringBuilder( s.replaceAll("[23457]", "0").replace('6', '_').replace('9', '6').replace('_', '9')).reverse() .toString(); return (int) range(x, y).filter(i -> i == Integer.parseInt(upside.apply(i + ""))).count(); } }
Option 3 (using streams
):
import java.util.stream.*; public class UpsideDown { public int solve(int x, int y) { return (int) IntStream.range(x, y).boxed().filter(z -> { String s = String.valueOf(z); if(s.matches(".*[23457].*")) return false; int l = s.length(); if(l % 2 == 1) { if(s.substring(l/2, l/2+1).matches(".*[69].*")) return false; } int[] d = s.chars().map(Character::getNumericValue).toArray(); for(int i = 0; i < l/2; i++) { if(d[i] != d[l-1-i]) { if(d[i] == 6 && d[l-1-i] == 9) continue; if(d[i] == 9 && d[l-1-i] == 6) continue; return false; } else { if(d[i] == 6 || d[i] == 9) return false; } } return true; }).count(); } }
Test cases to validate our solution
import org.junit.Test; import static org.junit.Assert.assertEquals; import org.junit.runners.JUnit4; public class UpsideDownTest { UpsideDown sol = new UpsideDown(); @Test public void basicTests() { assertEquals(3, sol.solve(0,10)); assertEquals(4, sol.solve(10,100)); assertEquals(12, sol.solve(100,1000)); assertEquals(20, sol.solve(1000,10000)); assertEquals(6, sol.solve(10000,15000)); assertEquals(9, sol.solve(15000,20000)); assertEquals(15, sol.solve(60000,70000)); assertEquals(55, sol.solve(60000,130000)); } }