Skip to content

Instantly share code, notes, and snippets.

@duangsuse
Forked from Trumeet/Main.java
Last active January 21, 2021 11:29
Show Gist options
  • Save duangsuse/59bfe0cc0875a095ea88fac40717e1f5 to your computer and use it in GitHub Desktop.
Save duangsuse/59bfe0cc0875a095ea88fac40717e1f5 to your computer and use it in GitHub Desktop.
Cosmic Number
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; }
}
}
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;
}
}
}