Related
Question:
In this problem, the scenario we are evaluating is the following: You're standing at the base of a staircase and are heading to the top. A small stride will move up one stair, and a large stride advances two. You want to count the number of ways to climb the entire staircase based on different combinations of large and small strides. For example, a staircase of three steps can be climbed in three different ways: three small strides, one small stride followed by one large stride, or one large followed by one small.
The call of waysToClimb(3) should produce the following output:
1 1 1,
1 2,
2 1
My code:
public static void waysToClimb(int n){
if(n == 0)
System.out.print("");
else if(n == 1)
System.out.print("1");
else {
System.out.print("1 ");
waysToClimb(n - 1);
System.out.print(",");
System.out.print("2 ");
waysToClimb(n - 2);
}
}
My output:
1 1 1,
2,
2 1
My recursion doesn't seem to remember the path it took any idea how to fix it?
Edit:
Thank you guys for the responses. Sorry for the late reply
I figured it out
public static void waysToClimb(int n){
String s ="[";
int p=0;
com(s,p,n);
}
public static void com(String s,int p,int n){
if(n==0 && p==2)
System.out.print(s.substring(0,s.length()-2)+"]");
else if(n==0 && p !=0)
System.out.print(s+"");
else if(n==0 && p==0)
System.out.print("");
else if(n==1)
System.out.print(s+"1]");
else {
com(s+"1, ",1,n-1);
System.out.println();
com(s+"2, ",2,n-2);
}
}
If you explicity want to print all paths (different than counting them or finding a specific one), you need to store them all the way down to 0.
public static void waysToClimb(int n, List<Integer> path)
{
if (n == 0)
{
// print whole path
for (Integer i: path)
{
System.out.print(i + " ");
}
System.out.println();
}
else if (n == 1)
{
List<Integer> newPath = new ArrayList<Integer>(path);
newPath.add(1);
waysToClimb(n-1, newPath);
}
else if (n > 1)
{
List<Integer> newPath1 = new ArrayList<Integer>(path);
newPath1.add(1);
waysToClimb(n-1, newPath1);
List<Integer> newPath2 = new ArrayList<Integer>(path);
newPath2.add(2);
waysToClimb(n-2, newPath2);
}
}
initial call: waysToClimb(5, new ArrayList<Integer>());
Below mentioned solution will work similar to Depth First Search, it will explore one path. Once a path is completed, it will backtrace and explore other paths:
public class Demo {
private static LinkedList<Integer> ll = new LinkedList<Integer>(){{ add(1);add(2);}};
public static void main(String args[]) {
waysToClimb(4, "");
}
public static void waysToClimb(int n, String res) {
if (ll.peek() > n)
System.out.println(res);
else {
for (Integer elem : ll) {
if(n-elem >= 0)
waysToClimb(n - elem, res + String.valueOf(elem) + " ");
}
}
}
}
public class Test2 {
public int climbStairs(int n) {
// List of lists to store all the combinations
List<List<Integer>> ans = new ArrayList<List<Integer>>();
// initially, sending in an empty list that will store the first combination
csHelper(n, new ArrayList<Integer>(), ans);
// a helper method to print list of lists
print2dList(ans);
return ans.size();
}
private void csHelper(int n, List<Integer> l, List<List<Integer>> ans) {
// if there are no more stairs to climb, add the current combination to ans list
if(n == 0) {
ans.add(new ArrayList<Integer>(l));
}
// a necessary check that prevent user at (n-1)th stair to climb using 2 stairs
if(n < 0) {
return;
}
int currStep = 0;
// i varies from 1 to 2 as we have 2 choices i.e. to either climb using 1 or 2 steps
for(int i = 1; i <= 2; i++) {
// climbing using step 1 when i = 1 and using 2 when i = 2
currStep += 1;
// adding current step to the arraylist(check parameter of this method)
l.add(currStep);
// make a recursive call with less number of stairs left to climb
csHelper(n - currStep, l, ans);
l.remove(l.size() - 1);
}
}
private void print2dList(List<List<Integer>> ans) {
for (int i = 0; i < ans.size(); i++) {
for (int j = 0; j < ans.get(i).size(); j++) {
System.out.print(ans.get(i).get(j) + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
Test2 t = new Test2();
t.climbStairs(3);
}
}
Please note this solution will timeout for larger inputs as this isn't a memoized recursive solution and can throw MLE(as I create a new list when a combination is found).
Hope this helps.
if anyone looking for a python solution, for this problem.
def way_to_climb(n, path=None, val=None):
path = [] if path is None else path
val = [] if val is None else val
if n==0:
val.append(path)
elif n==1:
new_path = path.copy()
new_path.append(1)
way_to_climb(n-1, new_path, val)
elif n>1:
new_path1 = path.copy()
new_path1.append(1)
way_to_climb(n-1, new_path1, val)
new_path2 = path.copy()
new_path2.append(2)
way_to_climb(n-2, new_path2, val)
return val
Note: it is based on the #unlut solution, here OP has used a top-down recursive approach. This solution is for all people who looking for all combination of staircase problem in python, no python question for this so i have added a python solution here
if we use a bottom-up approach and use memorization, then we can solve the problem faster.
Even though you did find the correct answer to the problem with your code, you can still improve upon it by using just one if to check if the steps left is 0. I used a switch to check the amount of steps taken because there are only 3 options, 0, 1, or 2. I also renamed the variables that were used to make the code more understandable to anyone seeing it for the first time, as it is quite confusing if you are just using one letter variable names. Even with all these changes the codes run the same, I just thought it might be better to add some of these things for others who might view this question in the future.
public static void climbStairsHelper(String pathStr, int stepsTaken, int stepsLeft)
{
if(stepsLeft == 0)
{
switch(stepsTaken)
{
case 2:
System.out.print(pathStr.substring(0, pathStr.length() - 2) + "]");
break;
case 1:
System.out.print(pathStr + "");
break;
case 0:
System.out.print("");
break;
}
}
else if(stepsLeft == 1)
{
System.out.print(pathStr + "1]");
}
else
{
climbStairsHelper(pathStr + "1, ", 1, stepsLeft - 1);
System.out.println();
climbStairsHelper(pathStr + "2, ", 2, stepsLeft - 2);
}
}`
`
This is a probable answer of my question in stack overflow.Integer to word conversion
At first I have started with dictionary. Then I came to know it is obsolete. So now I use Map instead of dictionary. My code is work well for number till Millions. But the approach I take here is a naive approach. The main problem of this code is
First: Huge numbers of variable use
2nd: Redundant code block as per program requirement
3rd: Multiple if else statement
I am thinking about this problems
Solution for 2nd problem: using user define function or macros to eliminate redundant code block
Solution for 3rd problem: Using switch case
My code:
public class IntegerEnglish {
public static void main(String args[]){
Scanner in=new Scanner(System.in);
System.out.println("Enter the integer");
int input_number=in.nextInt();
Map<Integer,String> numbers_converter = new HashMap<Integer,String>();
Map<Integer,String> number_place = new HashMap<Integer,String>();
Map<Integer,String> number_2nd = new HashMap<Integer,String>();
numbers_converter.put(0,"Zero");
numbers_converter.put(1,"One");
numbers_converter.put(2,"Two");
numbers_converter.put(3,"Three");
numbers_converter.put(4,"Four");
numbers_converter.put(5,"Five");
numbers_converter.put(6,"Six");
numbers_converter.put(7,"Seven");
numbers_converter.put(8,"Eight");
numbers_converter.put(9,"Nine");
numbers_converter.put(10,"Ten");
numbers_converter.put(11,"Eleven");
numbers_converter.put(12,"Twelve");
numbers_converter.put(13,"Thirteen");
numbers_converter.put(14,"Fourteen ");
numbers_converter.put(15,"Fifteen");
numbers_converter.put(16,"Sixteen");
numbers_converter.put(17,"Seventeen");
numbers_converter.put(18,"Eighteen");
numbers_converter.put(19,"Nineteen");
number_place.put(3,"Hundred");
number_place.put(4,"Thousand");
number_place.put(7,"Million");
number_place.put(11,"Billion");
number_2nd.put(2,"Twenty");
number_2nd.put(3,"Thirty");
number_2nd.put(4,"Forty");
number_2nd.put(5,"Fifty");
number_2nd.put(6,"Sixty");
number_2nd.put(7,"Seventy");
number_2nd.put(8,"Eighty");
number_2nd.put(9,"Ninty");
if(input_number== 0){
System.out.println("zero");
}
else if(input_number>0 && input_number<19){
System.out.println(numbers_converter.get(input_number));
}
else if(input_number>19 && input_number<100){
int rem=input_number%10;
input_number=input_number/10;
System.out.print(number_2nd.get(input_number));
System.out.print(numbers_converter.get(rem));
}
else if(input_number==100){
System.out.println(number_place.get(3));
}
else if(input_number>100 && input_number<1000){
int reminder=input_number%100;
int r1=reminder%10;
int q1=reminder/10;
int quot=input_number/100;
System.out.print(numbers_converter.get(quot) + "hundred");
if(reminder>0 && reminder<20){
System.out.print(numbers_converter.get(reminder));
}
else{
System.out.println(number_2nd.get(q1) + numbers_converter.get(r1));
}
}
else if(input_number==1000){
System.out.println(number_place.get(4));
}
else if(input_number>1000 && input_number<10000){
int rem=input_number%100;
int rem_two=rem%10;
int quotient =rem/10;
input_number=input_number/100;
int thousand=input_number/10;
int hundred = input_number%10;
System.out.print(numbers_converter.get(thousand) + "thousand" + numbers_converter.get(hundred)+ " hundred");
if(rem >0 && rem<20){
System.out.print(numbers_converter.get(rem));
}
else if(rem >19 && rem <100){
System.out.print(number_2nd.get(quotient) + numbers_converter.get(rem_two));
}
}
else if(input_number>10000 && input_number<1000000000){
//Say number 418,229,356
int third_part=input_number%1000;//hold 356
input_number=input_number/1000;//hold 418,229
int sec_part=input_number%1000;//hold 229
input_number=input_number/1000;// hold 418
int rem_m=third_part%100;//hold 56
int rem_m1=rem_m%10;//hold 6
int rem_q=rem_m/10;// hold 5
int q_m=third_part/100;// hold 3
int sec_part_rem=sec_part%100;// hold 29
int sec_part_rem1=sec_part_rem%10;//9
int sec_part_q=sec_part_rem/10;//hold 2
int sec_q=sec_part/100;// hold 2
int input_q=input_number/100;// hold 4
int input_rem=input_number%100;//hold 18
int input_q_q=input_rem/10;//hold 1
int input_rem1=input_rem%10;// hold 8
System.out.print(numbers_converter.get(input_q) + " hundred ");
if(input_rem>0 && input_rem<20){
System.out.print(numbers_converter.get(input_rem)+ " Million ");
}
else{
System.out.print(number_2nd.get(input_q_q) + " " + numbers_converter.get(input_rem1) + " Million ");
}
System.out.print(numbers_converter.get(sec_q) + " hundred ");
if(sec_part_rem >0 && sec_part_rem<20){
System.out.println(numbers_converter.get(sec_part_rem) + " thousand ");
}
else{
System.out.print(number_2nd.get(sec_part_q) + " " + numbers_converter.get(sec_part_rem1) + " thousand ");
}
System.out.print(numbers_converter.get(q_m) + " hundred ");
if(rem_m>0 && rem_m<20){
System.out.print(numbers_converter.get(rem_m));
}
else{
System.out.print(number_2nd.get(rem_q) + " " + numbers_converter.get(rem_m1));
}
}
}
}
Redundant Code Blocks
int rem=input_number%100;
int rem_two=rem%10;
int quotient =rem/10;
input_number=input_number/100;
int thousand=input_number/10;
int hundred = input_number%10;
This type of code block used almost every where. Taking a number divide it with 100 or 1000 to find out the hundred position then then divide it with 10 to find out the tenth position of the number. Finally using %(modular division) to find out the ones position.
How could I include user define function and switch case to minimize the code block.
Instead of storing the results in variables, use a method call:
int remainder100(int aNumber) {
return aNumber % 100;
}
int remainder10(int aNumber) {
return aNumber % 10;
}
...etc.
System.out.println(numbers_converter.get(remainder100(input_number)));
About 3rd problem: I wouldn't use switch ... case, too many cases.
Instead, take advantage that numbering repeats itself every 3 digits. That means the pattern for thousands and millions is the same (and billions, trillions, etc).
To do that, use a loop like this:
ArrayList<String> partialResult = new ArrayList<String>();
int powersOf1000 = 0;
for (int kiloCounter = input_number; kiloCounter > 0; kiloCounter /= 1000) {
partialResult.add(getThousandsMilionsBillionsEtc(powersOf1000++);
partialResult.add(convertThreeDigits(kiloCounter % 1000));
}
Then you can print out the contents of partialResult in reverse order to get the final number.
I'd suggest you break your single main method down into a couple of classes. And if you haven't already create a few unit tests to allow you to easily test / refactor things. You'll find it quicker than starting the app and reading from stdin.
You'll find it easier to deal with the number as a string. Rather than dividing by 10 all the time you just take the last character of the string. You could have a class that does that bit for you, and a separate one that does the convert.
Here's what I came up with, but I'm sure it can be improved. It has a PoppableNumber class which allows the last character of the initial number to be easily retrieved. And the NumberToString class which has a static convert method to perform the conversion.
An example of a test would be
#Test
public void Convert102356Test() {
assertEquals("one hundred and two thousand three hundred and fifty six", NumberToString.convert(102356));
}
And here's the NumberToString class :
import java.util.HashMap;
import java.util.Map;
public class NumberToString {
// billion is enough for an int, obviously need more for long
private static String[] power3 = new String[] {"", "thousand", "million", "billion"};
private static Map<String,String> numbers_below_twenty = new HashMap<String,String>();
private static Map<String,String> number_tens = new HashMap<String,String>();
static {
numbers_below_twenty.put("0","");
numbers_below_twenty.put("1","one");
numbers_below_twenty.put("2","two");
numbers_below_twenty.put("3","three");
numbers_below_twenty.put("4","four");
numbers_below_twenty.put("5","five");
numbers_below_twenty.put("6","six");
numbers_below_twenty.put("7","seven");
numbers_below_twenty.put("8","eight");
numbers_below_twenty.put("9","nine");
numbers_below_twenty.put("10","ten");
numbers_below_twenty.put("11","eleven");
numbers_below_twenty.put("12","twelve");
numbers_below_twenty.put("13","thirteen");
numbers_below_twenty.put("14","fourteen ");
numbers_below_twenty.put("15","fifteen");
numbers_below_twenty.put("16","sixteen");
numbers_below_twenty.put("17","seventeen");
numbers_below_twenty.put("18","eighteen");
numbers_below_twenty.put("19","nineteen");
number_tens.put(null,"");
number_tens.put("","");
number_tens.put("0","");
number_tens.put("2","twenty");
number_tens.put("3","thirty");
number_tens.put("4","forty");
number_tens.put("5","fifty");
number_tens.put("6","sixty");
number_tens.put("7","seventy");
number_tens.put("8","eighty");
number_tens.put("9","ninty");
}
public static String convert(int value) {
if (value == 0) {
return "zero";
}
PoppableNumber number = new PoppableNumber(value);
String result = "";
int power3Count = 0;
while (number.hasMore()) {
String nextPart = convertUnitTenHundred(number.pop(), number.pop(), number.pop());
nextPart = join(nextPart, " ", power3[power3Count++], true);
result = join(nextPart, " ", result);
}
if (number.isNegative()) {
result = join("minus", " ", result);
}
return result;
}
public static String convertUnitTenHundred(String units, String tens, String hundreds) {
String tens_and_units_part = "";
if (numbers_below_twenty.containsKey(tens+units)) {
tens_and_units_part = numbers_below_twenty.get(tens+units);
}
else {
tens_and_units_part = join(number_tens.get(tens), " ", numbers_below_twenty.get(units));
}
String hundred_part = join(numbers_below_twenty.get(hundreds), " ", "hundred", true);
return join(hundred_part, " and ", tens_and_units_part);
}
public static String join(String part1, String sep, String part2) {
return join(part1, sep, part2, false);
}
public static String join(String part1, String sep, String part2, boolean part1Required) {
if (part1 == null || part1.length() == 0) {
return (part1Required) ? "" : part2;
}
if (part2.length() == 0) {
return part1;
}
return part1 + sep + part2;
}
/**
*
* Convert an int to a string, and allow the last character to be taken off the string using pop() method.
*
* e.g.
* 1432
* Will give 2, then 3, then 4, and finally 1 on subsequent calls to pop().
*
* If there is nothing left, pop() will just return an empty string.
*
*/
static class PoppableNumber {
private int original;
private String number;
private int start;
private int next;
PoppableNumber(int value) {
this.original = value;
this.number = String.valueOf(value);
this.next = number.length();
this.start = (value < 0) ? 1 : 0; // allow for minus sign.
}
boolean isNegative() {
return (original < 0);
}
boolean hasMore() {
return (next > start);
}
String pop() {
return hasMore() ? number.substring(--next, next+1) : "";
}
}
}
Standard RPG dice notation is something like this: "AdB[x/]C[+-]D", where A, B, C, D are natural numbers: A the number of dice to roll, B the number of sides on each die, C a following multiplier or divisor, and D an addition or subtraction.
Some examples:
d6: Roll a single 6-sided die.
3d6: Roll 3 dice of 6-sides each and find the sum.
4d6+1: Roll 4 dice of 6-sides each, and add 1 to the sum.
3d6x10: Roll 3 dice of 6-sides each, then multiply the sum by 10.
d6/2: Roll a 6-sided die and then divide by 2 (rounding up).
I'd like a Java method that gets fed a string in this format and parses out the correct integer values of A, B, C, and D. (Say: If C is meant as a divisor, then store a negative int; likewise if D is meant as a subtraction do the same.) I've actually implemented this already with some loops looking at individual character values in the String, but it's ugly as sin.
I have the intuition that this would be more concisely solved by using a regular expression, but frankly I'm completely ignorant in that topic. Any suggestions on how that would be done? And if there's a more elegant abstraction to the problem (like say, an arbitrary number of separate x/+- modifiers; or needing to turn the x into *) I'd be open to that, too.
This question gives a closely related regular expression, but doesn't illustrate how to extract the parameters from it: Java Regex repetition (Dice notation parsing)
This isn't the smartest or most elegant way, but it's short, readable and robust. Since I'm not sure how you intend to use it I didn't add anything fancy for outputting or making this into an API/library:
public class DieRegex {
public static void main(String[] args) {
int amount, die, mult = 1, add = 0;
Pattern p = Pattern.compile("([1-9]\\d*)?d([1-9]\\d*)([/x][1-9]\\d*)?([+-]\\d+)?");
Matcher m = p.matcher("d20");
if (m.matches()) {
amount = (m.group(1) != null) ? Integer.parseInt(m.group(1)) : 1;
die = Integer.parseInt(m.group(2));
if (m.group(3) != null) {
boolean positive = m.group(3).startsWith("x");
int val = Integer.parseInt(m.group(3).substring(1));
mult = positive ? val : -val;
}
if (m.group(4) != null) {
boolean positive = m.group(4).startsWith("+");
int val = Integer.parseInt(m.group(4).substring(1));
add = positive ? val : -val;
}
}
else
System.out.println("No match"); // Do whatever you need
}
}
Note: According to the comments about checking the input:
amount (A) die (B) and mult (C) must be greater than 0. However, positive numbers with leading zeros are not allowed (02d20 is not valid, 2d20 is the correct form). This can be fixed with a lookahead but will make the regex more complicated.
add (D) can be any number (even with leading zeros).
mult (C) add (D) are 1 and 0 respectively if they don't exist in the string. It's just a default value that indicates "no value".
The format that is checked for:
A: [optional] non-negative number (default 1)
d
B: [required] non-negative number
C: [optional] / or x followed by a non-negative number (default 1)
D: [optional] + or - followed by a non-negative number (default 0)
This named-group example yields some promising results from your sample input.
Note: Requires Java 7 for named regex groups.
String pattern = "(?<A>\\d*)d((?<B>\\d+)(?<math>(?<mult>[x\\/](?<C>\\d+))?(?<add>[+-](?<D>\\d+))?)?)?";
Pattern p = Pattern.compile(pattern);
String[] tests = new String[] {
"d6", "3d6", "4d6+1", "3d6x10", "d6/2", "3d4/2-7", "12d4-", "d-8", "4dx"
};
for (String test : tests) {
System.out.printf("Testing \"%s\"\n", test);
Matcher m = p.matcher(test);
if (m.matches()) {
String groupA = m.group("A");
if (groupA == null) {
groupA = "1"; // default one roll
}
String groupB = m.group("B");
if (groupB == null) {
groupB = "6"; // default six-sided die
}
String groupC = m.group("C");
if (groupC == null) {
groupC = "1"; // default multiply or divide by 1
}
String groupD = m.group("D");
if (groupD == null) {
groupD = "0"; // default add or subtract 0
}
int a = Integer.parseInt(groupA);
int b = Integer.parseInt(groupB);
int c = Integer.parseInt(groupC);
int d = Integer.parseInt(groupD);
String groupMath = m.group("math");
if (groupMath != null && groupMath.isEmpty()) {
groupMath = null;
}
String groupAdd = m.group("add");
String groupMult = m.group("mult");
System.out.printf("A: %d\n", a);
System.out.printf("B: %d\n", b);
System.out.printf("C: %d\n", c);
System.out.printf("D: %d\n", d);
System.out.println("------");
System.out.printf("math: %s\n", groupMath);
System.out.printf("mult: %s\n", groupMult);
System.out.printf("add: %s\n", groupAdd);
} else {
System.out.println("No Match!");
}
System.out.println();
}
Output
Testing "d6"
A: 1
B: 6
C: 1
D: 0
------
math: null
mult: null
add: null
Testing "3d6"
A: 3
B: 6
C: 1
D: 0
------
math: null
mult: null
add: null
Testing "4d6+1"
A: 4
B: 6
C: 1
D: 1
------
math: +1
mult: null
add: +1
Testing "3d6x10"
A: 3
B: 6
C: 10
D: 0
------
math: x10
mult: x10
add: null
Testing "d6/2"
A: 1
B: 6
C: 2
D: 0
------
math: /2
mult: /2
add: null
Testing "3d4/2-7"
A: 3
B: 4
C: 2
D: 7
------
math: /2-7
mult: /2
add: -7
Testing "12d4-"
No Match!
Testing "d-8"
No Match!
Testing "4dx"
No Match!
I didn't extensively test it, but according to your explanation the following code works. May need some minor tweaking of the regex if you notice something's wrong. Biggest difference from this version to the rest of others is that it's modularized within a Class called RPGDice that you could instantiate with RPGDice.parse(expr) and get an RPGDice instance that contains the different attributes (rolls, faces, multiplier, additive).
public class RPGDice {
private static final Pattern DICE_PATTERN = Pattern.compile("(?<A>\\d*)d(?<B>\\d+)(?>(?<MULT>[x/])(?<C>\\d+))?(?>(?<ADD>[+-])(?<D>\\d+))?");
private int rolls = 0;
private int faces = 0;
private int multiplier = 0;
private int additive = 0;
public RPGDice(int rolls, int faces, int multiplier, int additive) {
this.rolls = rolls;
this.faces = faces;
this.multiplier = multiplier;
this.additive = additive;
}
public int getRolls() {
return rolls;
}
public int getFaces() {
return faces;
}
public int getMultiplier() {
return multiplier;
}
public int getAdditive() {
return additive;
}
#Override
public String toString() {
return String.format("{\"rolls\": %s, \"faces\": %s, \"multiplier\": %s, \"additive\": %s}", rolls, faces, multiplier, additive);
}
private static boolean isEmpty(String str) {
return str == null || str.trim().isEmpty();
}
private static Integer getInt(Matcher matcher, String group, int defaultValue) {
String groupValue = matcher.group(group);
return isEmpty(groupValue) ? defaultValue : Integer.valueOf(groupValue);
}
private static Integer getSign(Matcher matcher, String group, String positiveValue) {
String groupValue = matcher.group(group);
return isEmpty(groupValue) || groupValue.equals(positiveValue) ? 1 : -1;
}
public static RPGDice parse(String str) {
Matcher matcher = DICE_PATTERN.matcher(str);
if(matcher.matches()) {
int rolls = getInt(matcher, "A", 1);
int faces = getInt(matcher, "B", -1);
int multiplier = getInt(matcher, "C", 1);
int additive = getInt(matcher, "D", 0);
int multiplierSign = getSign(matcher, "MULT", "x");
int additiveSign = getSign(matcher, "ADD", "+");
return new RPGDice(rolls, faces, multiplier * multiplierSign, additive * additiveSign);
}
return null;
// OR
// throw new IllegalArgumentException("Invalid Expression");
}
public static void main(String[] args) {
System.out.println(RPGDice.parse("d6"));
System.out.println(RPGDice.parse("d6x"));
System.out.println(RPGDice.parse("33d6x10"));
System.out.println(RPGDice.parse("336x10"));
System.out.println(RPGDice.parse("d6/"));
System.out.println(RPGDice.parse("d6/5"));
System.out.println(RPGDice.parse("d6/5+2"));
System.out.println(RPGDice.parse("2d6/5-32"));
System.out.println(RPGDice.parse("2d6/5+-32"));
}
}
Output:
{"rolls": 1, "faces": 6, "multiplier": 1, "additive": 0}
null
{"rolls": 33, "faces": 6, "multiplier": 10, "additive": 0}
null
null
{"rolls": 1, "faces": 6, "multiplier": -5, "additive": 0}
{"rolls": 1, "faces": 6, "multiplier": -5, "additive": 2}
{"rolls": 2, "faces": 6, "multiplier": -5, "additive": -32}
null
Simple Answer
Consider reading the manual.
RTxM1 and RTxM2
TLDR
the output of the code example below shows what you need to know to parse the dice notation using a regex.
public class RegEx
{
private static final int EXPECTED_GROUP_COUNT = 7;
private static final Pattern pattern = Pattern.compile("(\\d+)?[Dd](\\d+)([Xx/](\\d+))?(([+-])(\\d+))?");
private static void matchit(final String value)
{
final Matcher matcher = pattern.matcher(value);
if (matcher.matches())
{
final int groupCount;
final MatchResult matchResult = matcher.toMatchResult();
groupCount = matchResult.groupCount();
System.out.println("kapow: " + value + ", groups: " + groupCount);
if (groupCount == EXPECTED_GROUP_COUNT)
{
for (int index = 0; index <= groupCount; ++index)
{
final String currentGroup = matchResult.group(index);
System.out.println("\tgroup[" + index + "]: " + currentGroup);
}
}
else
{
System.out.println("match error; wrong group count");
}
}
else
{
System.out.println("Format not recognized: " + value);
}
}
public static void main(
String[] args)
{
final String[] thingArray =
{
"3d6",
"d7",
"4D6+4",
"3d6x10",
"d6/2"
};
for (final String thing : thingArray)
{
matchit(thing);
}
}
}
So I have this script I've written:
public class Primes {
public static void main(String[] args) {
}
//Part 4: Question 1
public static int Binary2int(String b){
int size = b.length();
double count, sum=0;
boolean binary = true;
for (int i=0; i<b.length() ; i++){
int digit = b.charAt(i)-'0';
if (digit>1){
binary = false;
i=b.length();
}
count = digit*Math.pow(2, size-i-1);
sum+=count;
}
if (!binary){
System.out.println("Error - "+b+" is not a binary number.");
}
int sum1 = (int)sum;
return sum1;
}
//Part 4: Question 2
public static boolean isBinaryString(String b){
boolean binary = true;
for (int i=0; i<b.length() ; i++){
int digit = b.charAt(i)-'0';
if (digit>1){
binary = false;
i=b.length();
}
}
return binary;
}
//Part 4: Question 3
public static String int2Binary(int n){
int count=0;
if (n<=0){
count = 1;
}
for (int i=n; i>0 ;){
i=i/2;
count++;
}
int arr[] = new int [count];
for (int i=n, t=0; i>0 ;t++){
arr[arr.length-1-t] = i%2;
i = i/2;
}
if (n<=0){
arr[0] = 0;
}
String s = Arrays.toString(arr);
return s;
}
}
4.1 is meant to take a string (which stands for a binary number) and then return an integer(which stands for the integer the binary number in the input represents).
4.2 takes a binary number in the form of a string and then returns a Boolean variable (true if it’s a binary number and false if it isn’t).
4.3 is doing the opposite of 4.1, it takes an integer in the form of an integer and returns the binary number that represents it in the form of a string.
Oh and It all works fine when I'm testing it.
Now the problem is that the one checking it will be using the following (type of)script:
/**
* This class represents a tester - to be used by students to check Ex3: <br>
* 1. call all the public functions, check compilation. <br>
* 2. test some of function of their results. <br> <br>
* note: for debug change the printFlag to true.
*/
public class BynaryTest {
/**
* if set to true - will print a trace of all the checks.
*/
public static boolean printFlag = true;//false;
/**
* number of errors the test program found
*/
public static int error = 0;
/**
* this main function runs the test of the EX3Tester class
*/
public static void main(String[] a) {
System.out.println("******* Testing Ex3 - print mode = " + printFlag + " ********");
checkEx34();
System.out.println();
System.out.println("******* U have got " + error + " errors ********");
}
public static void checkEx34() {
if (printFlag) {
System.out.println("**** Cheking Ex21 ****");
}
int[] nums = {0, 1, 12345};
for (int i = 0; i < nums.length; i = i + 1) {
String s = Primes.int2Binary(nums[i]);
int num2 = Primes.Binary2int(s);
if (nums[i] != num2) {
error++;
System.out.println("** Error in EX34:" + num2 + "!=" + nums[i] + " **");
} else {
if (printFlag) {
System.out.println("num[" + i + "]=" + nums[i] + " binary: " + s + " .. ok");
}
}
}
}
}
The interaction between the two scripts does happen and nothing crashes, but then, for some reason, the only outcome I get from using it is:
** Error in EX34:21!=0 **
Error - [1] is not a binary number.
** Error in EX34:21!=1 **
Error - [1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1] is not a binary number.
** Error in EX34:21!=12345 **
******* U have got 3 errors ********
I've tried to fix it myself or finding out what causes that sort of unwanted outcome but I couldn't come up with anything :(
Have you tested it? The mistake is quite obvious if you do.
For example for 9 your Int2Binary method returns the following binary representation: [1, 0, 0, 1] as String.
Then in your Binary2Int you check if you only have 0s and 1s like so:
int digit = b.charAt(i)-'0'; // b is [1, 0, 0, 1]
if (digit>1){
binary = false;
//... more code ...
}
See the mistake now?
In your method intToBinary, you have the following line:
String s = Arrays.toString(arr);
I think you are expecting this to take an array and concat all the values in it into a single string. Given this example:
int[] array = {1, 0, 0};
System.out.println(Arrays.toString(array));
You expect the output to be:
100
When in fact it is:
[1,0,0]
I am attempting to create a recursive method that accepts an integer parameter and prints the first n squares
separated by commas, with the odd squares in descending order followed by the even squares in ascending order.
For example, if the input is 8, it should print the following output:
49, 25, 9, 1, 4, 16, 36, 64
My code so far is:
s and n have the same values initially, the only difference is that s changes as the code forwards while n doesn't change.
private static void genSquare(int s, int n) {
if (s >= 0 && s <= n) {
if (isOdd(s)) {
System.out.print(Math.pow(n, 2) + " ");
genSquare(s - 2, n);
}
if (s == 0 || s == 1) {
genSquare(1, n);
}
if (isEven(s)) {
System.out.print(Math.pow(n, 2) + " ");
genSquare(s + 2, n);
}
}
}
I have created a while loop version of it, which works perfectly. I just don't have the recursive version working.
Sample inputs would be using the same number for s and n.
Here is the code for the loop version:
private void genLoop(int s, int n) {
if (isEven(s)) {
s--;
}
while (s <= n) {
if (s == 1) {
System.out.print(1 + " ");
s++;
} else if (isOdd(s)) {
System.out.print(s * s + " ");
s -= 2;
} else if (isEven(s)) {
System.out.print(s * s + " ");
s += 2;
}
}
}
The problem is in this statement:
if(s == 0 || s== 1)
genSquare(1,n);
This causes the method to recurse infinitely. In fact, when you get to the point where s is zero or one, you have to make sure that you DON'T call genSquare recursively.
That's enough of a hint for you to figure the rest out for yourself ... and fix any other bugs.
In addition, there's a simpler way of squaring an integer ...
void calculateSquare(int n)
{
// odds descending and even ascending
int t=n;
if(n<=0)
return;
if(n%2==1)
{
// Calculate square now and print it also
System.out.println(n*n);
calculateSquare(--n);
}
else
{
calculateSquare(--n);
System.out.println(t*t);
}
}
This would do the job.
Try the following approach:
Assume your example where n is equal to 8. The square of 8 should printed last so you probably first should do a recursive call, then print the square of the current number.
Thinking about the task for n=7 the order of things given above should be reverted for odd numbers.
Yes it is good example for recursion . Try this it helps u
public class RecursionEx {
static int no = 0;
public static void main(String[] args) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the Number");
try
{
no = Integer.parseInt(bufferedReader.readLine());
getSquares(no,0);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static void getSquares(int number,int count)
{
if(number==1)
{
System.out.print(number);
count=1;
getSquares(number+1, count);
}
else
{
if(number%2!=0&&count==0)
{
System.out.print(number*number+",");
getSquares(number-2,0);
return;
}
if(count==0)
getSquares(number-1,0);
if(number%2==0&&count==1)
{
if(number<=no)
System.out.print(","+number*number);
if(number>=no)
return;
getSquares(number+2, count);
}
}
}
}