Using specific numbers to reach a target number - java

For my assignment, I have to allow the player to select 6 numbers from two different lists as they please.
List<Integer> large = Arrays.asList(25, 50, 75, 100);
List<Integer> small = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10);
After they have selected their numbers say [100, 3, 5, 6, 9, 5] they then generate a target number of lets say for example 299 and they then can only use the numbers selected as a means of reaching the target using ONLY multiplication, addition, subtraction and division. So they could input for instance, 100 * 3 + 5 - 6 to reach the 299 target and this would be checked and scored appropriately.
Unfortunately I don't really have much to go on and I'm a bit confused on how to go about even starting to do that, I'm not looking for a straight up answer, maybe some pointers or external help would be much appreciated.

If we follow Bedmas (brackets exponents division multiplication addition subtraction) we can break this down into a simple function.
First turn the equation into a list of components:
100 * 3 + 5 - 6
changes to
["100", "*", "3", "+", "5", "-", "6"]
Now evaluate every element to make sure that they are valid. ie) Each value in the list of components must be in the selection list or have the value, */+-, Also if there are n nums, then there should be n-1 syms
To get the result we can then evaluate the list,.. merging num-sym-num sections as we go, in the order of bedmas
In pseudo:
func int compute_val(ListString eqn)
while not eqn.length is 1
if "*" in eqn
index = eqn.getIndex("*")
replace eqn[index -1:index +1] with str((int) eqn[index -1] * (int)eqn[index +1])
else if "/" in eqn
index = eqn.getIndex("/")
replace eqn[index -1:index +1] with str((int) eqn[index -1] / (int)eqn[index +1])
else if "+" in eqn
index = eqn.getIndex("+")
replace eqn[index -1:index +1] with str((int) eqn[index -1] + (int)eqn[index +1])
else if "-" in eqn
index = eqn.getIndex("-")
replace eqn[index -1:index +1] with str((int) eqn[index -1] - (int)eqn[index +1])
return (int)eqn[0]
This would be the progression of the list as the equation is evaluated in the loop
["100", "*", "3", "+", "5", "-", "6"] --> ["300", "+", "5", "-", "6"] -->
["305", "-", "6"] --> ["299"]

Is this helpful?
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class JavaApplication97 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] s = {1, 2, 3, 4};
List<Integer> large = new ArrayList<>(Arrays.asList(25, 50, 75, 100));
List<Integer> small = new ArrayList<>(Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10));
List<Integer> yourNumbers = new ArrayList<>();
int numbersToSelect = 6;
while (numbersToSelect > 0) {
System.out.println("Choose " + numbersToSelect + " numbers from these numbers : " + large + " or " + small);
Integer input = in.nextInt();
boolean isItThere = false;
if (large.contains(input)) {
isItThere = true;
large.remove(input);
} else if (small.contains(input)) {
isItThere = true;
small.remove(input);
}
if (isItThere) {
yourNumbers.add(input);
numbersToSelect--;
System.out.println("Number " + input + " is added");
} else {
System.out.println("There is no such number");
}
}
}
}
Sample output :
Choose 6 numbers from these numbers : [25, 50, 75, 100] or [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10]
25
Number 25 is added
Choose 5 numbers from these numbers : [50, 75, 100] or [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10]
25
There is no such number
Choose 5 numbers from these numbers : [50, 75, 100] or [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10]
5
Number 5 is added
Choose 4 numbers from these numbers : [50, 75, 100] or [1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10]
5
Number 5 is added
Choose 3 numbers from these numbers : [50, 75, 100] or [1, 1, 2, 2, 3, 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10]
5
There is no such number
Choose 3 numbers from these numbers : [50, 75, 100] or [1, 1, 2, 2, 3, 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10]
100
Number 100 is added
Choose 2 numbers from these numbers : [50, 75] or [1, 1, 2, 2, 3, 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10]
6
Number 6 is added
Choose 1 numbers from these numbers : [50, 75] or [1, 1, 2, 2, 3, 3, 4, 4, 6, 7, 7, 8, 8, 9, 9, 10, 10]
50
Number 50 is added

You need multiple steps, and as I guess this is a homework task I'm not going to give a complete answer, however:
Parse the input string of the user
Calculate the result
Check if the result equals the target number
While 2 and 3 are trivial, the first part is probably the hardest for you and the core of the task. You can get more information on that task here: Smart design of a math parser?

Related

Quicksort went wrong (added some duplicates)

I'm new to sorting algorithms and can't seem to figure out what went wrong. With an unsorted array of int [] uArr = {5,2, 10, 7, 6, 0, 8, 1, 9}, i'm given 0,1,2,5,5,6,8,10 (the nine in the org. array was replaced with a duplicate 5 and the 7 was lost). If I add duplicates to the array, I get more duplicates after the array is sorted and a few more missing numbers.
public static void main(String args[]){
int [] uArr = {5,2, 10, 7, 6, 0, 8, 1, 9};
qSort(uArr, 0, 8);
}
public static void qSort(int [] A, int low, int high){
if (low < high){
int pivotL = partition(A, low, high);
qSort(A, low, pivotL);
qSort(A, pivotL+1, high);
}
}
public static int partition(int [] arr, int low, int high){
int pivot = arr[low];
int leftwall = low;
for (int i = low + 1; i < high; i++){
if (arr[i] < pivot){
int temp = arr[i];
arr[i] = arr[leftwall];
arr[leftwall] = temp;
leftwall += 1;
}
}
int temp2 = pivot;
pivot = arr[leftwall];
arr[leftwall] = temp2;
return leftwall;
}
}
So one thing you should seriously do is start writing documentation. Even though this is a small program, you seem to have forgotten what you were doing as you were writing the code.
For example, there are 9 elements in the array, and you pass in the offsets to sort, inclusive, as 0 through 8:
qSort( uArr, 0, 8 );
But then in the partition routine you only sort elements less than the high value:
for( int i = low + 1; i < high; i++ ) {
And unlike you the last value in the array, 9, is never touched for me and never sorted. So that's an issue. Figure out if you want your indexes to be inclusive or not. For me writing documentation as I go helps me keep these ideas straight.
I'm still looking for other problems like the duplication.
Update: I'm going to just post these as I figure them out, as a sort of stream-of-consciousness of how I look for problems. One thing I was taught early on is that adding print statements to your code can be faster than using a debugger. So (after re-formatting your code, because the formatting you posted was frankly crap) I added this:
public static void qSort( int[] A, int low, int high ) {
System.out.println( Arrays.toString( A ) + " low=" + low + " high=" + high );
And got this output:
run:
[5, 2, 10, 7, 6, 0, 8, 1, 9] low=0 high=8
[2, 0, 1, 5, 6, 5, 8, 10, 9] low=0 high=3
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=0 high=2
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=0 high=0
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=1 high=2
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=1 high=1
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=2 high=2
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=3 high=3
[0, 1, 2, 5, 6, 5, 8, 10, 9] low=4 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=4 high=5
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=4 high=4
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=5 high=5
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=6 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=6 high=6
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=7 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=7 high=7
[0, 1, 2, 5, 5, 6, 8, 10, 9] low=8 high=8
[0, 1, 2, 5, 5, 6, 8, 10, 9]
BUILD SUCCESSFUL (total time: 0 seconds)
I did have to stare at the output for a while, but what I noticed next was two things. The 5 is duplicated almost immediately, and the 5 is also the first element, which means it's going to be chosen by your partition code as the pivot. So it looks as though you have problems re-merging the pivot with the array.
Update 2: OK found another problem. This one I found by writing your array out by hand and walking through each value of i and leftwall as it makes the first partition. Problem here:
When the pivot, 5, encounters the element 0 in the array, the rest of the array has not been sorted. The 10, 7, 6, etc. are not less than the pivot and have not be touched. So when you make the swap, you sawp this:
[2, 5, 10, 7, 6, 0, 8, 1, 9]
for this:
[2, 5, 0, 7, 6, 5, 8, 1, 9]
This is because leftwall was 1 (it had been swapped with the 2 but not any other number, so it only had been incremented once) and there's the duplication and losing numbers too. I'm going to stop there because you have some pretty big problems.
What you need to do in this case is swap the 10, not the pivot, with the 0. This is going to require one additional pointer at least. Quicksort algorithms need to find the lowest and highest in the array and have two loops inside the outer for loop. What you have here is a kind of weird recursive insert sort. You'll need to think a bit more how to do this, but two more loops, nest inside the first, will be required.

Is there any way to write 2d matrix in file without using functions?

I would like to write 10 2d matrix in java (they are sudoku) but i would like to just write them in the file(by hand) without having them in my code in the first place and use them in function to write and read them from file.
I hope you can understand what I'm trying to say.
You can define the sudoku board as follows
int[][] sudoku = {
{4, 2, 9, 8, 1, 3, 5, 6, 7},
{5, 1, 6, 4, 7, 2, 9, 3, 8},
{7, 8, 3, 6, 5, 9, 2, 4, 1},
{6, 7, 2, 1, 3, 4, 8, 5, 9},
{3, 9, 5, 2, 8, 6, 1, 7, 4},
{8, 4, 1, 7, 9, 5, 6, 2, 3},
{1, 5, 8, 3, 6, 7, 4, 9, 2},
{9, 3, 4, 5, 2, 8, 7, 1, 6},
{2, 6, 7, 9, 4, 1, 3, 8, 5},
};
You can create a multidimensional array and save it to a file using JSON
{
"sudoku": [
[], [],
[], [],
[], [],
[], [],
[], [],
[], [],
[], []
]
}
How to create a 2 dimensional array
int[][] twoD_arr = new int[3][2];
I think the following will do what you want:
public static void main(String[] args) {
try {
int[][] grid1 = loadGrid(9, 9, "grid_1.txt");
printGrid(grid1);
} catch (Exception e) {
e.printStackTrace();
}
}
private static int[][] loadGrid(int width, int height, String filename) throws IOException {
int[][] res = new int[width][height];
int y = 0;
for (String line : Files.readAllLines(Paths.get(filename))) {
int x = 0;
for (String n : line.split("\\s+"))
res[y][x++] = Integer.parseInt(n);
++y;
}
return res;
}
private static void printGrid(int[][] grid) {
for (int[] row : grid) {
for (int n : row)
System.out.print(n + " ");
System.out.println();
}
}
The important bit is in loadGrid. It uses readAllLines to get a List of lines from the text file, then within each line split it on the regex \s+, which means "any amount of whitespace". This produces a bunch of individual Strings that you can turn back into numbers.
The input file is just:
1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18
19 20 21 22 23 24 25 .... etc
Beware that this isn't tolerant of mistakes in the source file. You will need to handle files that have the wrong size, files with non-numeric text in, etc.

What do square brackets before a number mean in Java? e.g. []89 or [1, 2, 3]89

I'm new to Java and haven't been able to find any explanations on what the syntax such as [1, 2, 3, 4]5 means.
import java.util.*;
class SumDigPower {
static List<Long> list = new ArrayList<Long>();
public static List<Long> sumDigPow(long a, long b) {
for(long i = a; i<=b; i++) {
if(isEureka(i)) {
list.add(i);
}
}
return list;
}
public static boolean isEureka(long num) {
//convert number to string to get length and then sum each digit to the nth power
//return true or false depending on whether the number qualifies for the list
String numString = Long.toString(num);
long sum = 0;
for(int i = 0; i < numString.length(); i++) {
sum += Math.pow(Character.getNumericValue(numString.charAt(i)), i+1);
}
if(sum == num) {return true;}
else {return false;}
}
}
expected:<..., 4, 5, 6, 7, 8, 9, []89]> but was:<..., 4, 5, 6, 7, 8, 9, [1, 2, 3, 4, 5, 6, 7, 8, 9, ]89]>
JUnit uses that syntax to show why a test failed, and specifically when an expected String didn't match the actual value:
String expected = "[1, 2, 3, 4, 5, 6, 7, 8, 9, 89]";
List<Long> actualLongs = Arrays.asList(
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L,
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 89L);
String actualString = actualLongs.toString();
assertEquals(expected, actualString);
JUnit figures out the what's similar and different between the expected and actual, and uses the square brackets to highlight that. If you align the "expected" and "but was" bits, you get:
expected:<..., 4, 5, 6, 7, 8, 9, []89]>
but was:<..., 4, 5, 6, 7, 8, 9, [1, 2, 3, 4, 5, 6, 7, 8, 9, ]89]>
... so it's telling you that in that [] space, it expected nothing extra, but found the characters 1, 2, 3, 4, 5, 6, 7, 8, 9,.
The difference becomes a bit more obvious if it's not just extra characters. For instance, let's say you didn't have the extra values, but the last 89 were instead a 66. Then it would look like:
expected:<..., 4, 5, 6, 7, 8, 9, [89]]>
but was:<..., 4, 5, 6, 7, 8, 9, [66]]>
"Where I expected an 89, I found a 66."
I'm not as familiar with TestNG, but it wouldn't surprise me if it does a similar thing.
If you run the test in IDEA IntelliJ, it will even pick up on that syntax and show you a nice diff view of the expected-but-was. Again, I'm not familiar with other IDEs (like Eclipse), but it wouldn't surprise me if they do that as well.

Why does my insertion sort algorithm only work with single digit integers?

I've wrote a simple insertion sort algorithm for fun. It appears to be working just fine with one problem, it only works when all items in the array (the thing its trying to sort) are single digit integers. If an element is a multi-digit integer, it sorts everything up to that integer, then stops and throws an IndexOutOfBoundsException.
Note: Just so you understand the source code, the way my program works is like this: I pass the InsertionSort class a primative int array in construction. I then convert that to the ArrayList list. I know that the ArrayList list has the correct values copied over because I print it out and it matches up.
Example Runs:
Working:
{ 9, 2, 8, 5, 1, 6, 6, 7, 1}; //works perfectly ->
Unsorted List: [9, 2, 8, 5, 1, 6, 6, 7, 1]
Step 1: [9]
Step 2: [2, 9]
Step 3: [2, 8, 9]
Step 4: [2, 5, 8, 9]
Step 5: [1, 2, 5, 8, 9]
Step 6: [1, 2, 5, 6, 8, 9]
Step 7: [1, 2, 5, 6, 6, 8, 9]
Step 8: [1, 2, 5, 6, 6, 7, 8, 9]
Step 9: [1, 1, 2, 5, 6, 6, 7, 8, 9]
Sorted List: [1, 1, 2, 5, 6, 6, 7, 8, 9]
Not Working:
{ 9, 2, 8, 5, 1, 6, 6, 7, 1, 22, 823, 30, 244, 45, 5}; //doesn't work ->
Unsorted List: [9, 2, 8, 5, 1, 6, 6, 7, 1, 22, 823, 30, 244, 45, 5]
Step 1: [9]
Step 2: [2, 9]
Step 3: [2, 8, 9]
Step 4: [2, 5, 8, 9]
Step 5: [1, 2, 5, 8, 9]
Step 6: [1, 2, 5, 6, 8, 9]
Step 7: [1, 2, 5, 6, 6, 8, 9]
Step 8: [1, 2, 5, 6, 6, 7, 8, 9]
Step 9: [1, 1, 2, 5, 6, 6, 7, 8, 9]
java.lang.IndexOutOfBoundsException: Index: 9, Size: 9
Sorted List: [1, 1, 2, 5, 6, 6, 7, 8, 9]
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at InsertionSort.sort(InsertionSort.java:41)
at Executer.main(Executer.java:7)
Here is the relevant sorting code:
static ArrayList<Integer> list = new<Integer> ArrayList();
static ArrayList<Integer> list2 = new<Integer> ArrayList();
public static int[] sort() {
int s = 0;
System.out.println("Unsorted List: " + list.toString());
try {
for (int i = 0; i < list.size(); i++) {
s++;
if (i == 0) {
list2.add(list.get(i));
System.out.println("Step " + s + ": " + list2.toString());
continue;
} else {
int z = 0;
while (list2.get(z) < list.get(i)) {
z++;
}
list2.add(z, list.get(i));
}
System.out.println("Step " + s + ": " + list2.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Sorted List: " + list2.toString());
return toPrimative(list.toArray(new Integer[list.size()]));
}
It has nothing to do with single or multi digit numbers, in first example you were just lucky to have the biggest number as a first element in a list. There is an obvious mistake when you're choosing a position for the next element:
int z = 0;
while (list2.get(z) < list.get(i)) {
z++;
}
You increment index but don't do bounds check, so when it comes to number 22 you get an exception. The correct one would be
while (list2.get(z) < list.get(i) && z <= list2.size())
Mind debug. Problem is here:
while (list2.get(z) < list.get(i)) {
z++;
}
z exceeds list2 count if new value is the biggest.
First value 9 in small numbers example hid this problem.
I hope that solution is clear enough

Specifying random chance [duplicate]

This question already has answers here:
How to pick an item by its probability?
(13 answers)
Closed 8 years ago.
Now , I will generate random numbers between 1 to 5. I assume there has probability or chance to gain on each number . (please assume for example if you don't agree it)
1 has 20%
2 has 20%
3 has 20%
4 has 20%
5 has 20%
I would like to increase or decrease chances of some numbers as I wish..
1 has 10%
2 has 10%
3 has 35%
4 has 40%
5 has 5%
If so , I can generate random numbers as I wish. Some were hard to get and some will gain frequently.
How can I achieve it by Java ? Please support me with some examples or some useful links or anything else. I would really appreciated it. Please don't be suggest to describe some my efforted codes because I have no idea for this and I request some useful suggestions from you . Thanks in advance.
The solution is simple:
double r = random.nextDouble();
if (r < 0.1) ret = 1
else if (r < 0.2) ret = 2
else if (r < 0.55) ret = 3
...
you get the idea, use the cumulative likelihood as threshold.
First instantiate java.util.Random rand = new java.util.Random();. Do this exactly once.
From there, one approach is to use double f = rand.nextDouble(); which gives you a number between (and including) 0 to (and not including) 1.
Then transform using a series of ifs:
if (f < 0.1){
return 1;
} else if (f < 0.1 + 0.1){
return 2;
} else if (f < 0.1 + 0.1 + 0.35){
return 3;
... /*can you see the pattern*/
It's not quite the fastest way, but is clear and will get you started.
I don't know if there is a way with the Random library.
But I think you can generate a Random number between 1 and 100.
And so, you can code that between:
1 and 10 you obtain 1,
11 and 20 you obtain 2,
21 and 55 you obtain 3,
and so on
An alternative I can think about it is
int[] a = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 5, 5, 5, 5, 5};
Random r = new Random();
return a[ r.nextInt(100) ];

Categories