-
-
Save duangsuse/59bfe0cc0875a095ea88fac40717e1f5 to your computer and use it in GitHub Desktop.
Cosmic Number
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
/** | |
* Cosmic Number | |
* License: Unlicensed | |
**/ | |
public class Cosmic { | |
private static final int ONE = 1; //$ tac - | |
private static final int TEN = ONE*10; | |
private static final int HUNDRED = TEN*10; | |
private static final int THOUSAND = HUNDRED*10; | |
private static final int MILLION = THOUSAND*1000; | |
private static final int BILLION = MILLION*1000; | |
public static void main(String[] args) { | |
final Scanner scanner = new Scanner(System.in); | |
int input = scanner.nextInt(); | |
scanner.nextLine(); | |
cosmic(input, Object::toString); | |
cosmic(input, n -> String.join(" ", numberToStr((int)n))); | |
} | |
@FunctionalInterface interface ToString { String show(Object o); } | |
private static void cosmic(int n, ToString ts) { | |
int acc = n; | |
while (true) { | |
int last = 0; | |
for (final String term : numberToStr(acc)) | |
last += term.length(); | |
if (acc == last) break; | |
System.out.format("%s is %s, ", ts.show(acc), ts.show(last)); | |
acc = last; | |
} | |
System.out.format("%s is cosmic\n", ts.show(acc)); | |
} | |
private static List<String> numberToStr(final int input) { | |
int value = input; | |
List<String> terms = new ArrayList<>(5); | |
if (value >= BILLION) { | |
final int billions = value / BILLION; // 我担心我可能不能重构这些,因为我已经把它们定义为常量,意味着 | |
value -= billions * BILLION; | |
terms.addAll(numberToStr(billions)); // 如果我要用动态结构替换它们,我就白写了那些名字,即便可以用 SortedSet+Map | |
terms.add("billion"); | |
} | |
if (value >= MILLION) { | |
final int millions = value / MILLION; | |
value -= millions * MILLION; | |
terms.addAll(numberToStr(millions)); | |
terms.add("million"); | |
} | |
if (value >= THOUSAND) { | |
final int thousands = value / THOUSAND; | |
value -= thousands * THOUSAND; | |
terms.addAll(numberToStr(thousands)); | |
terms.add("thousand"); | |
} | |
if (value >= HUNDRED) { | |
final int hundreds = value / HUNDRED; | |
value -= hundreds * HUNDRED; | |
terms.addAll(numberToStr(hundreds)); | |
terms.add("hundred"); | |
} | |
if (value >= TEN) { | |
final int tens = value / TEN; | |
value -= tens * TEN; | |
switch (tens) { | |
case 0: | |
break; //vv NOTE Refactor $ awk 'match($0, /\("(.*)"\)/, m) {print "\""m[1]"\""}'|tr '\n' , | |
case 1: | |
// Extract right now. | |
final Pair<Integer, Integer> oneExtract = extractOnes(value); | |
value = oneExtract.first; | |
final int v = Integer.parseInt(new StringBuilder().append(tens /* 1 */).append(oneExtract.second).toString()); | |
terms.add(switchIndexOrFail("Unknown 10 ~ 19 value", 10, "ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen").at(v)); | |
/*switch (v) { | |
case 10: | |
terms.add("ten"); | |
break; | |
case 11: | |
terms.add("eleven"); | |
break; | |
case 12: | |
terms.add("twelve"); | |
break; | |
case 13: | |
terms.add("thirteen"); | |
break; | |
case 14: | |
terms.add("fourteen"); | |
break; | |
case 15: | |
terms.add("fifteen"); | |
break; | |
case 16: | |
terms.add("sixteen"); | |
break; | |
case 17: | |
terms.add("seventeen"); | |
break; | |
case 18: | |
terms.add("eighteen"); | |
break; | |
case 19: | |
terms.add("nineteen"); | |
break; | |
default: | |
throw new IllegalStateException("Unknown 10 ~ 19 value " + v); | |
}*/ | |
break; | |
default: | |
terms.add(switchIndexOrFail("Unknown tens", 2, "twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety").at(tens)); | |
/*case 2: | |
terms.add("twenty"); | |
break; | |
case 3: | |
terms.add("thirty"); | |
break; | |
case 4: | |
terms.add("forty"); | |
break; | |
case 5: | |
terms.add("fifty"); | |
break; | |
case 6: | |
terms.add("sixty"); | |
break; | |
case 7: | |
terms.add("seventy"); | |
break; | |
case 8: | |
terms.add("eighty"); | |
break; | |
case 9: | |
terms.add("ninety"); | |
break; | |
default: | |
throw new IllegalStateException("Unknown tens " + tens);*/ | |
} | |
} | |
final Pair<Integer, Integer> oneExtract = extractOnes(value); | |
value = oneExtract.first; | |
switch (oneExtract.second) { | |
case 0: | |
break; | |
default: | |
terms.add(switchIndexOrFail("Unknown digit", 1, "one","two","three","four","five","six","seven","eight","nine").at(oneExtract.second)); | |
break; | |
/*case 1: | |
terms.add("one"); | |
break; | |
case 2: | |
terms.add("two"); | |
break; | |
case 3: | |
terms.add("three"); | |
break; | |
case 4: | |
terms.add("four"); | |
break; | |
case 5: | |
terms.add("five"); | |
break; | |
case 6: | |
terms.add("six"); | |
break; | |
case 7: | |
terms.add("seven"); | |
break; | |
case 8: | |
terms.add("eight"); | |
break; | |
case 9: | |
terms.add("nine"); | |
break; | |
default: | |
throw new IllegalStateException("Unknown digit " + oneExtract.second);*/ | |
} | |
if (value != 0) throw new IllegalStateException("Unexpected left out"); | |
return terms; | |
} | |
private static Pair<Integer, Integer> extractOnes(int n) { | |
int ones = 0; | |
if (n >= ONE) { | |
ones = n / 1; | |
return new Pair<>(ones%ONE, ones); | |
} // (a<b)=> (int)(a/b)==0 ; and, ones==0 | |
return new Pair<>(n, ones); | |
} | |
@SafeVarargs | |
private static <T> Switch<T> switchIndexOrFail(String msg, int i0, T... values) { | |
Switch<T> sw = new Switch<T>(values, i0+values.length); | |
System.arraycopy(values, 0, sw.ary, i0, values.length); | |
return sw; | |
} | |
private static class Switch<T> { | |
T[] ary; String errorMsg; | |
@SuppressWarnings("unchecked") | |
public Switch(T[] values, int size) { | |
ary = (T[])java.lang.reflect.Array.newInstance(values[0].getClass(), size); | |
} | |
T at(int index) { | |
try { return ary[index]; } | |
catch (IndexOutOfBoundsException ex) { throw new IllegalStateException(errorMsg+": "+index); } | |
} | |
} | |
private static class Pair<A, B> { | |
public final A first; | |
public final B second; | |
public Pair(A first, B second) { this.first = first; this.second = second; } | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
/** | |
* Cosmic Number | |
* License: Unlicensed | |
**/ | |
public class Main { | |
private static final int BILLION = 1000000000; | |
private static final int MILLION = 1000000; | |
private static final int THOUSAND = 1000; | |
private static final int HUNDRED = 100; | |
private static final int TEN = 10; | |
private static final int ONE = 1; | |
public static void main(String[] args) { | |
final Scanner scanner = new Scanner(System.in); | |
int input = scanner.nextInt(); | |
scanner.nextLine(); | |
while (true) { | |
int last = 0; | |
for (final String term : numberToStr(input)) | |
last += term.length(); | |
if (input == last) break; | |
System.out.format("%d is %d, ", input, last); | |
input = last; | |
} | |
System.out.format("%d is cosmic\n", input); | |
} | |
private static List<String> numberToStr(final int input) { | |
int value = input; | |
List<String> terms = new ArrayList(5); | |
if (value >= BILLION) { | |
final int billions = value / BILLION; | |
value -= billions * BILLION; | |
terms.addAll(numberToStr(billions)); | |
terms.add("billion"); | |
} | |
if (value >= MILLION) { | |
final int millions = value / MILLION; | |
value -= millions * MILLION; | |
terms.addAll(numberToStr(millions)); | |
terms.add("million"); | |
} | |
if (value >= THOUSAND) { | |
final int thousands = value / THOUSAND; | |
value -= thousands * THOUSAND; | |
terms.addAll(numberToStr(thousands)); | |
terms.add("thousand"); | |
} | |
if (value >= HUNDRED) { | |
final int hundreds = value / HUNDRED; | |
value -= hundreds * HUNDRED; | |
terms.addAll(numberToStr(hundreds)); | |
terms.add("hundred"); | |
} | |
if (value >= TEN) { | |
final int tens = value / TEN; | |
value -= tens * TEN; | |
switch (tens) { | |
case 0: | |
break; | |
case 1: | |
// Extract right now. | |
final Pair<Integer, Integer> oneExtract = extractOnes(value); | |
value = oneExtract.first; | |
final int v = Integer.parseInt(new StringBuilder().append(tens /* 1 */).append(oneExtract.second).toString()); | |
switch (v) { | |
case 10: | |
terms.add("ten"); | |
break; | |
case 11: | |
terms.add("eleven"); | |
break; | |
case 12: | |
terms.add("twelve"); | |
break; | |
case 13: | |
terms.add("thirteen"); | |
break; | |
case 14: | |
terms.add("fourteen"); | |
break; | |
case 15: | |
terms.add("fifteen"); | |
break; | |
case 16: | |
terms.add("sixteen"); | |
break; | |
case 17: | |
terms.add("seventeen"); | |
break; | |
case 18: | |
terms.add("eighteen"); | |
break; | |
case 19: | |
terms.add("nineteen"); | |
break; | |
default: | |
throw new IllegalStateException("Unknown 10 ~ 19 value " + v); | |
} | |
break; | |
case 2: | |
terms.add("twenty"); | |
break; | |
case 3: | |
terms.add("thirty"); | |
break; | |
case 4: | |
terms.add("forty"); | |
break; | |
case 5: | |
terms.add("fifty"); | |
break; | |
case 6: | |
terms.add("sixty"); | |
break; | |
case 7: | |
terms.add("seventy"); | |
break; | |
case 8: | |
terms.add("eighty"); | |
break; | |
case 9: | |
terms.add("ninety"); | |
break; | |
default: | |
throw new IllegalStateException("Unknown tens " + tens); | |
} | |
} | |
final Pair<Integer, Integer> oneExtract = extractOnes(value); | |
value = oneExtract.first; | |
switch (oneExtract.second) { | |
case 0: | |
break; | |
case 1: | |
terms.add("one"); | |
break; | |
case 2: | |
terms.add("two"); | |
break; | |
case 3: | |
terms.add("three"); | |
break; | |
case 4: | |
terms.add("four"); | |
break; | |
case 5: | |
terms.add("five"); | |
break; | |
case 6: | |
terms.add("six"); | |
break; | |
case 7: | |
terms.add("seven"); | |
break; | |
case 8: | |
terms.add("eight"); | |
break; | |
case 9: | |
terms.add("nine"); | |
break; | |
default: | |
throw new IllegalStateException("Unknown digit " + oneExtract.second); | |
} | |
if (value != 0) throw new IllegalStateException("Unexpected left out"); | |
return terms; | |
} | |
private static Pair<Integer, Integer> extractOnes(int value) { | |
int ones = 0; | |
if (value >= ONE) { | |
ones = value / 1; | |
value -= ones * 1; | |
} | |
return new Pair(value, ones); | |
} | |
private static class Pair<A, B> { | |
public final A first; | |
public final B second; | |
public Pair(A first, B second) { | |
this.first = first; | |
this.second = second; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
堆污染_掌心童林-CSDN博客
如何使用 Java 泛型来避免 ClassCastException - java宝典 - 博客园
SafeVarargs的用法 – 宿宝臣的博客