need ideas for the minRow method - java

I have java worksheet, which uses arraylist. It is making a excel sheet. There are functions like total, count, getters and setters which i could solve it easily but I cannot seem to do the min method below, the requirements are as followed
The data looks something like this:
A(0) B(1) C(2) D(3) E(4) F(5)
0 - - - - - -
1 - - 8.8 - 0.0 -0.1
2 - - - -6.5 - -
3 - - - - - -
4 - - - 1.8 -1.4 -
5 - - - - - -
6 0 1.9 - - - -
---------------------------
value of the first row for which there is a EntryData object
in the list data
return null if there is no data
public Integer minRow() {
return null; //to be completed
}
The test data is here to check if the function works:
public void testMinRow() {
assertNotNull(sheet.minRow());
assertTrue(sheet.minRow()==1);
assertNull(empty.minRow());
}
I got this far, but only the first test works here:
public Integer minRow() {
int firstRow = 0;
for(DataEntry item: data) {
if(item.getRow() > firstRow)
firstRow = item.getRow();
}
return firstRow; //to be completed
}

Why not using foreach to go throug the single lines, than save the value of the line and compare to the next value in this line and so on. at every compare, only save the smaller (min) value and at the end print this value out

Related

Java sorting by spread between two BigDecimal

Please help with sorting in Java. I have a simple example (looks like this).
I need to sort list by the difference between two BigDecimals.
My Data class (I cut getters)
public class Quotation {
private final long id;
private final BigDecimal askPrice;
private final BigDecimal bidPrice;
public Quotation(long id, BigDecimal bidPrice, BigDecimal askPrice) {
this.id = id;
this.askPrice = askPrice;
this.bidPrice = bidPrice;
}
}
Here we store our records.
storeQuotation(new Quotation(1000,new BigDecimal("99"), new BigDecimal("104")));
storeQuotation(new Quotation(1001,new BigDecimal("69"), new BigDecimal("72")));
storeQuotation(new Quotation(1002,new BigDecimal("65"), new BigDecimal("69")));
storeQuotation(new Quotation(1003,new BigDecimal("70"), new BigDecimal("71")));
storeQuotation(new Quotation(1004,new BigDecimal("71"), new BigDecimal("73")));
storeQuotation(new Quotation(1005,new BigDecimal("90"), new BigDecimal("95")));
storeQuotation(new Quotation(1006,new BigDecimal("92"), new BigDecimal("93")));
storeQuotation(new Quotation(1007,new BigDecimal("94"), new BigDecimal("98")));
storeQuotation(new Quotation(1008,new BigDecimal("90"), new BigDecimal("92")));
storeQuotation(new Quotation(1009,new BigDecimal("92"), new BigDecimal("95")));
out - Not Sorted
id - 1000. Bid - 99. Ask - 104. Spread = 5
id - 1001. Bid - 69. Ask - 72. Spread = 3
id - 1002. Bid - 65. Ask - 69. Spread = 4
id - 1003. Bid - 70. Ask - 71. Spread = 1
id - 1004. Bid - 71. Ask - 73. Spread = 2
id - 1005. Bid - 90. Ask - 95. Spread = 5
id - 1006. Bid - 92. Ask - 93. Spread = 1
id - 1007. Bid - 94. Ask - 98. Spread = 4
id - 1008. Bid - 90. Ask - 92. Spread = 2
id - 1009. Bid - 92. Ask - 95. Spread = 3
And I just need to sort this list by the difference between bidPrice and askPrice.
I tried this method...
public static List<Quotation> getSpreadsList(boolean decreasing) {
List<Quotation> sortedBySpread = QuotationsStoreImpl.quotationList;
Collections.sort(sortedBySpread, (a, b) ->
(a.getBidPrice().intValue() - b.getAskPrice().intValue()));
// sortedBySpread.sort((a, b) ->
// (a.getBidPrice().intValue() - b.getAskPrice().intValue()));
if (decreasing) {
Collections.reverse(sortedBySpread);
}
return sortedBySpread;
}
}
But without success...
out - Sorted
id - 1002. Bid - 65. Ask - 69. Spread = 4
id - 1003. Bid - 70. Ask - 71. Spread = 1
id - 1004. Bid - 71. Ask - 73. Spread = 2
id - 1001. Bid - 69. Ask - 72. Spread = 3
id - 1008. Bid - 90. Ask - 92. Spread = 2
id - 1009. Bid - 92. Ask - 95. Spread = 3
id - 1006. Bid - 92. Ask - 93. Spread = 1
id - 1007. Bid - 94. Ask - 98. Spread = 4
id - 1005. Bid - 90. Ask - 95. Spread = 5
id - 1000. Bid - 99. Ask - 104. Spread = 5
The list is mixed but not sorted according to my criteria !
Spread not sorted !
How can I sort this list correct, by spread ?
I don't have much experience in java.
And all my attempts have come to nothing.
Collections.sort(sortedBySpread, (a, b) -> (a.getBidPrice().intValue() - b.getAskPrice().intValue())); does some math that makes little since since it subtracts the ask from the bid of two different quotes.
Instead you should calculate the spread of a and then subtract the spread of b:
Collections.sort(sortedBySpread, (a, b) -> (a.getBidPrice().intValue() - a.getAskPrice().intValue()) - (b.getBidPrice().intValue() - b.getAskPrice().intValue()));
Generally this could be expanded into the following to make it more clear what is going on:
Collections.sort(sortedBySpread, (Quotation a, Quotation b) -> {
int spreadA = a.getBidPrice().intValue() - a.getAskPrice().intValue();
int spreadB = b.getBidPrice().intValue() - b.getAskPrice().intValue();
return spreadA - spreadB;
});
But starting with the first snippet IntelliJ suggest the arguably far cleaner solution
Collections.sort(sortedBySpread, Comparator.comparingInt(a -> (a.getBidPrice().intValue() - a.getAskPrice().intValue())));
And going from there it might make sense to have a getSpread on Quotation:
public int getSpread() {
return bidPrice.intValue() - askPrice.intValue();
}
which would then allow
Collections.sort(sortedBySpread, Comparator.comparingInt(Quotation::getSpread));
And finally
sortedBySpread.sort(Comparator.comparingInt(Quotation::getSpread));
without the need for Collections.sort.
For demo, I put your values in a list. I also added the following to your class.
public BigDecimal getSpread() {
return askPrice.subtract(bidPrice);
}
public String toString() {
return "id - %d bid - %6.2f ask - %6.2f spread - %6.2f".formatted(id, bidPrice, askPrice,getSpread());
}
The data
List<Quotation> quotes = new ArrayList<>(List.of(
(new Quotation(1000,new BigDecimal("99"), new BigDecimal("104"))),
(new Quotation(1001,new BigDecimal("69"), new BigDecimal("72"))),
(new Quotation(1002,new BigDecimal("65"), new BigDecimal("69"))),
(new Quotation(1003,new BigDecimal("70"), new BigDecimal("71"))),
(new Quotation(1004,new BigDecimal("71"), new BigDecimal("73"))),
(new Quotation(1005,new BigDecimal("90"), new BigDecimal("95"))),
(new Quotation(1006,new BigDecimal("92"), new BigDecimal("93"))),
(new Quotation(1007,new BigDecimal("94"), new BigDecimal("98"))),
(new Quotation(1008,new BigDecimal("90"), new BigDecimal("92"))),
(new Quotation(1009,new BigDecimal("92"), new BigDecimal("95")))));
The sorting part is simple. Just use a comparator, referencing the spread.
quotes.sort(Comparator.comparing(Quotation::getSpread));
And print
for(Quotation q : quotes) {
System.out.println(q);
}
Prints
id - 1003 bid - 70.00 ask - 71.00 spread - 1.00
id - 1006 bid - 92.00 ask - 93.00 spread - 1.00
id - 1004 bid - 71.00 ask - 73.00 spread - 2.00
id - 1008 bid - 90.00 ask - 92.00 spread - 2.00
id - 1001 bid - 69.00 ask - 72.00 spread - 3.00
id - 1009 bid - 92.00 ask - 95.00 spread - 3.00
id - 1002 bid - 65.00 ask - 69.00 spread - 4.00
id - 1007 bid - 94.00 ask - 98.00 spread - 4.00
id - 1000 bid - 99.00 ask - 104.00 spread - 5.00
id - 1005 bid - 90.00 ask - 95.00 spread - 5.00

How should i send data to java method from mapping with Odi12c

Recently I started working with Odi12c procedures, until now there was only work with mappings. Now, I have a mapping with different tables and joins, and I need to do calculations by columns. For that, I must use a java method, so I have something like this:
public void static List<Map<String, String>> seg( List<Map<String, String>> comp) {
for (Map<String, String> map : comp) {
if (total > 0 && min1 != min1_fin) {
rest = total - min1;
total-=min1;
map.replace("min1_fin",rest);
map.replace("total",total);
} else {a= true}
if (a) { //(operation for next column)
if (total > 0 && min2 != min2_fin) {
rest = total - min2;
.
..
...
}
return comp;
}
My list:
KEY TOTAL MIN1 MIN2 MIN1_FIN MIN2_FIN
------ -------- -------- ------- --------- ----------
1 35,14 61,85 91,85 0 0
1 35,14 8,09 58,32 0 0
2 85,67 6 6 0 0
2 85,67 67,6 71,47 0 0
I have thought about putting everything in a package and my code in a procedure directly or in a jar and calling it (I still don't know how).
But is it possible to do that? How can I send the data to my java method that way and read it when I return?
Using Java to do the transformation is not the best pattern if the result needs to be stored in a database. Doing it in SQL will be much more efficient.
Anyway, if you really want to use Java you can pass data from the Source command to the Target command of any Procedure step or KM step by binding it. Here is the doc about it : https://docs.oracle.com/cd/E15586_01/integrate.1111/e12643/procedures.htm#CHDGDJGB
Make sure to select the "Multi-Connections" checkbox in the definition of the Produre. The data will pass though the execution agent.

Mancala game in Java - using int array in while loop

I am working on a Mancala game project. In case you are interested in the GUI, here it is:
https://s32.postimg.org/hxzmhxt1x/mancala.png
I am working on a method that will cause the computer player to select the pit closest to their store that will allow it to capture stones from the human player. A capture is made when the last stone lands in an empty pit directly across from a pit with stones on the other side. I am including the relevant method below. The parameter "theBoard" is an int array to represent all of the pits including the stores and how many stones are contained in each pit of the array. Here is the code I have for the method:
public int selectPit(int[] theBoard) {
int pitChoice = theBoard.length - 2;
while (pitChoice >= theBoard.length / 2) {
int destinationPit = theBoard[pitChoice] + pitChoice;
int opposite = (theBoard.length - 2) - destinationPit;
if (theBoard[destinationPit] == 0 && theBoard[opposite] > 0 && destinationPit <= (theBoard.length - 2) && destinationPit > (theBoard.length / 2)) {
return pitChoice;
} else {
pitChoice--;
}
}
return this.selectClosestPitWithStones(theBoard);
}
The last line that calls the selectClosestPitWithStones is a call to a backup method just in case there are no options that would allow a capture. The functionality of this backup method works as intended. However, my selectPit method keeps returning incorrect results or "ArrayIndexOutOfBoundsException: -1".
I am using JUnit tests that are correctly written to test this method. Here is one such test:
#Test
public void testCapturePit0() {
this.setUp();
int[] theBoard = {6, 0, 0, 0, 2, 0, 0, 0};
assertEquals(4, this.strategy.selectPit(theBoard));
}
Any ideas on what could be causing incorrect results?
Debug it and verify that variables have the values you expect.
The problem at the moment is one of the variables going out of the bounds of the array. Remember that array indexes go from 0 to length minus one. Both int destinationPit = theBoard[pitChoice] + pitChoice; and int destinationPit = theBoard[pitChoice] + pitChoice; could go out of bounds depending on the input or the state of the array.

Guessing at Battleship program

I'm having some problems with a battleship solution I'm creating using Java. A random set of ships are loaded onto a 10x10 board. 1 2hit ships 2 3hit ships 1 4hit ship and 1 5hit ship (total of 17 hits goal)
I made a nested loop to basically fire at every cell coordinate until I either used 100 shots or destroyed all the ships. The GOAL is to find a way to sink all the ships with 50 or less shots. My problem is I can't tell where the ships are in accordance to their sink location (as it only tells me if I sunk a ship, not if I hit) Also, it doesn't tell me what kind of ship I've sunk, but I can figure that out a lot easier if I know how to solve the hit issue.
So how can I deduct if I've "hit" a ship? the only "hit" i can confirm on my board is the final shot triggered by the "a ship has sunk" message.
Edit: Sorry, I should also mention I do not have access to the battleship class, I only have a class I make that will be used to solve this problem. I was given some methods of the class such as:
" public BattleShip() - you need to call the constructor once in your program to create an instance of the battleship game.
public boolean shoot(Point shot) - you need to call this function to make each shot. See the sample source code for an example use.
public int numberOfShipsSunk() - returns the total number of ships sunk at any point during the game. It is a good idea to use this method to determine when a ship has been sunk.
public boolean allSunk() - returns a boolean value that indicates whether all the ships have been sunk.
public int totalShotsTaken() - returns the total number of shots taken. Your code needs to be responsible for ensuring the same shot is not taken more than once.
public ArrayList shipSizes() - returns an ArrayList of all of the ship sizes. The length of the array indicates how many ships are present.
public enum CellState - this enum object is very useful for marking cells has either Empty, Hit or Miss. It also has a convenience toString method so that can be used for printing purposes. You may also create your own Enum / Class for this in your code, but it is suggested that you use this instead of integers / characters to mark a Cell state"
The CellState property doesn't actually exist/is private so i can't use that. This is my loop.
x = 0;
for(int i = 0; i < 10; i++)
{
y = 0;
for(int j = 0; j < 10;j++)
{
if(x <=9 && y <=9) //X and Y are less than or equal to 9...
{
Point shot = new Point(x, y);
// At the end of each decision on where to fire next you need to shoot
if(shotTracker[x][y] == '-') // if space is free...
{ battleShip.shoot(shot);
if (sunkShip != battleShip.numberOfShipsSunk())
{
shotTracker[x][y] = 'O'; //The hit that sunk the ship
sunkShip++;
}
else
shotTracker[x][y] = '*'; // set space to fired miss
}
}
gameShots = battleShip.totalShotsTaken();
System.out.printf("You've shot %d times. The last shot's location was (%d,%d). You've hit something (not sure) times. You've sunk %d ships.\n", gameShots, x, y, battleShip.numberOfShipsSunk() );
if(battleShip.allSunk() || gameShots >= shotLimit)
{
break;
}
y+=3;
}
if(battleShip.allSunk() || gameShots >= shotLimit)
{
break;
}
x++;
}
if( gameShots >= shotLimit)
{
break;
}
}
And the output:
* - - * - - * - - *
* - - * - - * - - *
* - - * - - * - - *
* - - * - - * - - *
* - - * - - * - - *
* - - O - - * - - *
* - - * - - * - - *
* - - * - - * - - *
* - - * - - * - - *
This is a random output. I took a shot every 3 cells, and as you can see I sunk a ship but the O only tells me that was the finishing hit, so that was a vertical ship of unknown size on a random game...
Whatever code you are using to determine if a ship has been sunk should be able to tell you if a ship is hit. Otherwise, how does it aggregate to know its sunk?
I figured it out. My shot command
battleShip.shoot(shot)
evaluates to true or false, or hit or miss. When i check if true use "O" else use "*" O's pop up, so I guess I can do more work now. Thanks for trying to help!

Learning Java - Do not fully understand how this sequence is calculated (Fibonacci) [duplicate]

This question already has answers here:
Java recursive Fibonacci sequence
(37 answers)
Closed 8 years ago.
I am learning Java and I have this code from the internet and running it in Eclipse:
public class Fibonacci {
public static void main (String [] args) {
for (int counter = 0; counter <= 3; counter++){
System.out.printf("Fibonacci of %d is: %d\n", counter, fibonacci(counter));
}
public static long fibonacci(long number) {
if ((number == 0) || (number == 1))
return number;
else
return fibonacci(number - 1) + fibonacci(number - 2);
}
}
I've tried to understand it but cannot get it. So I run through the code and counter gets passed in through the fibonacci method. As counter starts at 0 and this is what gets passed first, then 1 and I understand the method passes back 0 and then 1.
When it reaches 2: it will return 2-1 + 2-2 = 2 and it does return this.
When it reaches 3: it will return 3-1 + 3-2 = 3 but it does not return 3 it returns 2.
Please can someone explain to me why as I cannot figure this out?
Thanks
First, I have to tell you that this recursive version has a dramatic exponential cost. Once you understand how it works, my advice for you would be to learn about tail recursivity, write a tail-recursive solution, an iterative solution, and compare them to your current method for high values of "number".
Then, your function basically uses the mathematical definition of the Fibonacci sequence :
f0 = 1, f1 = 1, fn = fn-1 + fn-2 for all n >= 2
For example if we call fibonacci(3), this will return fibonacci(2) + fibonacci(1). fibonacci(2) will be executed first and will return fibonacci(1) + fibonnacci(0). Then fibonacci(1) will return immediately 1 since it is a terminal case. It happens the same thing with fibonnacci(0), so now we have computed fibonnacci(2) = 1 + 0 = 1. Let's go back to fibonacci(3) which has been partially evaluated at this point : 1 + fibonnacci(1). We just have to compute fibonnacci(1) and we can finally return 1 + 1 = 2.
Even in this little example, you can see that we evaluated twice fibonacci(1), that is why this version is so slow, it computes many times the same values of the sequence, and it gets worth when "number" is high.

Categories

Resources