Conditional and iterators in ruby - java

I'm trying to translate the following code into ruby:
public void discardWeapon(Weapon w){
if(!weapons.isEmpty()){
boolean discarded = false;
Iterator<WeaponType> it = weapons.iterator();
while(it.hasNext() && !discarded){
WeaponType wtaux = it.next();
if(wtaux == w.getWeaponType()){
it.remove();
discarded = true;
}
}
}
}
But, when it comes to the while loop, I can't really find a practical way to do it in ruby. I've got the following structure so far:
def discardWeapon(w)
if(!#weapons.empty?)
discarded = false
#weapons.each do |wtaux|
end
end
end
But, how can I check my condition is met when using the .each iterator?
Thanks in advance.

I am not sure if I read your Java code correctly, but it feels to me like you have an instance variable #weapons that holds an array of weapons and you want to discard one instance of a weapon w from that list.
def discard_weapon(weapon)
index = #weapons.index(weapon)
#weapons.delete_at(index) if index
end
Array#index returns the index of the first match. And Array#delete_at deletes the element at the index when there was an element found.
When it is possible that the same weapon is included in the array multiple times and you want to discard all matching weapons then you can use the following one-liner:
def discard_weapon(weapon)
#weapons.delete(weapon)
end

Related

ArrayList to Stream in Java by grouping

I would like to get the highest score group by Id .If two highest score's are same then i would like get the highest score based on lowest Optional ID.I would like to get it in Java Stream.So far this code works.Is there any efficient way to rewrite this code in java stream
Example :
records=record.Person(batchNumber);
List<Person> highestRecords = new ArrayList<>();for(
Person s:records)
{
if(!highestRecords.isEmpty()) {
boolean contains = false;
for(Person ns: new ArrayList<>(highestRecords)) {
if(s.Id().compareTo(ns.Id()) == 0) {
contains = true;
if(s.getScore.compareTo(ns.getScore()) > 0
&& s.optionalId().compareTo(ns.optionalId()) < 0) {
highestRecords.remove(ns);
highestRecords.add(s)
}
}
}
if(contains == false) {
highestRecords.add(s);
}
}else {
highestRecords.add(s);
}
}
}
Don't convert this to a stream.
There is no one pure operation happening here. There are several.
Of note is the initial operation:
if(getNewPendingMatches.size() > 0)
That's always going to be false on the first iteration and you're always going to add one element in.
On subsequent iterations, life gets weird because now you're trying to remove elements while iterating over them. A stream cannot delete values from itself while iterating over itself; it only ever processes in one direction.
As written this code should not be converted to a stream. You won't gain any benefits in doing so, and you're going to actively harm readability if you do.

Sudoku solver Recurrence stack with try and fail technique

I am building a Sudoku solver that use the Try and Fail technique to solve any problem. My algorithm is:
1)Update (method that remove any possible value that already given as a final value to element in the same Row, column or squar)
2)Get the minimum element that has minimum number of possible values
3)start solve assuming the first possible value is the final value
4)save the current sate into a stack
5)Try to solve
5-a)If solved, return
5-b)if not solved and with invalid Sudoku, then Pop previous state
6)Repeat step 3) for all possible vaues (9)
7)Repeat step 2) until the puzzel is solved
This is my code
Stack<Element[][]> myStack= new Stack<>();
private Element[][] mySudoku;
public void solve(){
update();//remove all final values from all possible values for each element
if(isSudokuSolved(mySudoku)){
return;
}
//find a cell that is not confirmed and has the minimal candidates
int celli=-1,cellj=-1, p=10;
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(mySudoku[i][j].getValue()==0){
if(mySudoku[i][j].getPossibleValues().size()<p){
celli=i;
cellj=j;
p=mySudoku[i][j].getPossibleValues().size();
}
}
}
}
try {
for (int c = 0; c < mySudoku[celli][cellj].getPossibleValues().size() - 1; c++) {
//save state
Element[][] copy=deepCopy(mySudoku);//copy the current state
myStack.push(copy);
//apply candidate to cell
mySudoku[celli][cellj].setValue(mySudoku[celli][cellj].getPossibleValues().get(c));
update();//check is solved
if(checkValidInputSudoku(mySudoku)){
solve();
}else{
try {
mySudoku = myStack.pop();
} catch (EmptyStackException est) {
//do nothing
}
}
}
} catch (Exception e) {
}
//if we have reached here then we are at the last possible value for the candidates so confirm candidate in cell
if(celli!=-1 && cellj!=-1 && p!=10) {//Some problems happen here "out of Boundry -1 Error"
mySudoku[celli][cellj].setValue(mySudoku[celli][cellj].getPossibleValues().get(mySudoku[celli][cellj].getPossibleValues().size()-1));
}
}//end of solve method
I have spent more than 6 hours trying to find out the problem. I have checked for the Update() method, deepCopy() method and checkValidInputSudoku() method. They all works fine. Thank you in Advance
I can see one problem in your code. You have a loop that is sawing off the branch it sits on:
for(int c = 0; c < mySudoku[celli][cellj].getPossibleValues().size() - 1; c++) {
...
mySudoku[celli][cellj].setValue(mySudoku[celli]cellj].getPossibleValues().get(c));
...
}
Apart from that, you are missing one of the values, it should be for(c=0; c!=size; ++c), i.e. not size - 1. Also, calling getPossibleValues() just once would make this code much more readable. Lastly, catching and ignoring a stack underflow is just stupid, because it hides errors in your algorithm, as far as I can tell. If you don't know how to handle an error, don't just silence it. Since java requires you to catch it, put it in the outermost place possible or at least abort or do something, but don't ignore it!
One more thing: You are recursing and passing the context data via mySodoku and myStack. This is completely missing the point of recursion (or at least the way it's typically used), because the function call stack is the only stack you need. Using these to pass parameters only makes things more complicated than necessary. Instead, the function should return a partial sodoku puzzle and return either the fully solved puzzle or null. Using is easier to distinguish than the exception you're using now, and it's a regular and expected thing, not really exceptional. Then, when trying different choices, you set the cell to the values in turn and recurse, until the call doesn't return null. If none of the choices returns a solution, you clear the cell and return null yourself.
solve(sodoku):
if sodoku is solved:
return true
if sodoku is invalid:
return false
c = some empty cell
for v in 1...9:
// set to a value and recurse
c = v
if solve(sodoku):
// found a solution
return true
// no solution found, clear cell and return failure
c = null
return false
BTW: This strategy is called "backtracking". Using a cell with the least amount of possible values is called "pruning", which allows you to cut off whole branches from the search tree. Actually determining the possible values also helps avoiding a few futile attempts.

Cannot figure out how to incorporate backtracking into my psuedo-recursive method

This is for a sudoku-solver and each square has this method. My idea is that if one instance of this method goes through the loop without finding any valid values, it will return to the previous method that called it and continue the loop - trying the next value from the for-loop. I was hoping that this would suffice for backtracking, but all my test fail and I am completely clueless as to how I'm going to solve this one. /end noob-lament
public boolean recursive() {
for(int i = 1; i <= boardSize; i++) {
if(!validValue(i)) {
continue;
} else {
setValue(i);
if(getNext() == null) // This signifies that I am at the end of the list
return true;
else
getNext().recursive(); // same method in the next sudoku square
}
}
return false;
}
Two correctness issues here:
You should check if the result from the recursive invokation was true - and if it is, you should stop the recursion - you have found a solution, don't override it!
You should bubble up the return value of the recursion, specifically - if getNext().recursive(); yields true - you should bubble this true up [and as said in (1) - stop the recursion, you have a solution!]
OK - so since a fellow peer of mine helped me out with this one and managed to get me to understand what was missing, I thought I'd like to share it here in case anyone would be interested to know what was missing.
After the loop is done, the method needs to reset its value. If not the old values that were previously tested before the backtrack would remain after the backtrack. That would mean that when the isValid() method would check the column, row and box that the given square belongs to, the isValid() method would find a lot of values set previously.
All that was needed was one line before 'return false;'
//(end of for-loop)
setValue(0);
return false;
//(method ends)
You're calling getNext() twice. If it doesn't return null in your if statement, you call it again. Are you sure you want to do that?

How shall I execute an ArrayList program with a loop that renders each index of the list one at a time?

How shall I execute a program where as long as the array/list [idk which one to use yet but I've been told that with ArrayList I don't have to predefine a size so I'll use that] it will keep looping and the values are observed or rendered one at a time?
I've tried using the while loop but basically all I got were errors asking for an array or saying incompatible types or something like that.
while (myList!=0) //Can I actually do this? Because I didn't define a data type for my list.
if myList(0).equals ("A") //problem here is that I need to go through every index of the list. I've tried to use a counter like if myList(counter).equals ("A") but it says its incompatible types?
{
//print something.
} else if myList(0).equals ("B")
{
//print something
}
I know the question is kinda confusing but the code [even if it's full of errors] is exactly what I want to do. I just don't know how to apply it. Any help, answers, links, articles, tutorials would be reaaaaly appreciated.
Looks like you're thinking of it in terms of a C pointer. The List always points to a List, never to a Node or anything like that. So you'd do something like this intsead:
for(String s : myList) {
if("A".equals(s)) {
} else if("B".equals(s)) {
}
}
If you're using an ArrayList or some other implementation of the List interface you aren't going to have direct access to the data using brackets or parentheses, meaning that saying something like myList[0] is meaningless. Instead, what you are going to want to do is use the get method and then compare it to whatever values you need. You will be able to get the length of your List by using the .size() method, so your code will look something like this
for(int i=0; i<myList.size(); i++)
{
if(myList.get(i).equals("A"))
{
//print something
}
else if(myList.get(i).equals("B"))
{
//print something else
}
else
{
//print something still different
}
}
The response that glowcoder gave is a more compact syntax for looping over ArrayLists and other Lists in Java and results in nicer code, but this is how you'd do it sans syntactic sugar.
Is this answer suitable for your question?
for (int i = 0; i < myList.length; i++) {
if ("A".equals(myList[i])) {
// print something.
} else if ("B".equals(myList[i])) {
// print something
}
}
This should be working and quite close to what you tried so far:
int counter = 0;
while(counter < myList.size()) {
if (myList.get(counter).equals("A") )
{
//print something.
} else if (myList.get(counter).equals("B"))
{
//print something
}
counter = counter + 1;
}
Note that this is not the preferred way of looping over a list, see glowcoder's answer for something more elegant.

Javabat substring counting

public boolean catDog(String str)
{
int count = 0;
for (int i = 0; i < str.length(); i++)
{
String sub = str.substring(i, i+1);
if (sub.equals("cat") && sub.equals("dog"))
count++;
}
return count == 0;
}
There's my code for catDog, have been working on it for a while and just cannot find out what's wrong. Help would be much appreciated!*/
EDIT- I want to Return true if the string "cat" and "dog" appear the same number of times in the given string.
One problem is that this will never be true:
if (sub.equals("cat") && sub.equals("dog"))
&& means and. || means or.
However, another problem is that your code looks like your are flailing around randomly trying to get it to work. Everyone does this to some extent in their first programming class, but it's a bad habit. Try to come up with a clear mental picture of how to solve the problem before you write any code, then write the code, then verify that the code actually does what you think it should do and that your initial solution was correct.
EDIT: What I said goes double now that you've clarified what your function is supposed to do. Your approach to solving the problem is not correct, so you need to rethink how to solve the problem, not futz with the implementation.
Here's a critique since I don't believe in giving code for homework. But you have at least tried which is better than most of the clowns posting homework here.
you need two variables, one for storing cat occurrences, one for dog, or a way of telling the difference.
your substring isn't getting enough characters.
a string can never be both cat and dog, you need to check them independently and update the right count.
your return statement should return true if catcount is equal to dogcount, although your version would work if you stored the differences between cats and dogs.
Other than those, I'd be using string searches rather than checking every position but that may be your next assignment. The method you've chosen is perfectly adequate for CS101-type homework.
It should be reasonably easy to get yours working if you address the points I gave above. One thing you may want to try is inserting debugging statements at important places in your code such as:
System.out.println(
"i = " + Integer.toString (i) +
", sub = ["+sub+"]" +
", count = " + Integer.toString(count));
immediately before the closing brace of the for loop. This is invaluable in figuring out what your code is doing wrong.
Here's my ROT13 version if you run into too much trouble and want something to compare it to, but please don't use it without getting yours working first. That doesn't help you in the long run. And, it's almost certain that your educators are tracking StackOverflow to detect plagiarism anyway, so it wouldn't even help you in the short term.
Not that I really care, the more dumb coders in the employment pool, the better it is for me :-)
choyvp obbyrna pngQbt(Fgevat fge) {
vag qvssrerapr = 0;
sbe (vag v = 0; v < fge.yratgu() - 2; v++) {
Fgevat fho = fge.fhofgevat(v, v+3);
vs (fho.rdhnyf("png")) {
qvssrerapr++;
} ryfr {
vs (fho.rdhnyf("qbt")) {
qvssrerapr--;
}
}
}
erghea qvssrerapr == 0;
}
Another thing to note here is that substring in Java's built-in String class is exclusive on the upper bound.
That is, for String str = "abcdefg", str.substring( 0, 2 ) retrieves "ab" rather than "abc." To match 3 characters, you need to get the substring from i to i+3.
My code for do this:
public boolean catDog(String str) {
if ((new StringTokenizer(str, "cat")).countTokens() ==
(new StringTokenizer(str, "dog")).countTokens()) {
return true;
}
return false;
}
Hope this will help you
EDIT: Sorry this code will not work since you can have 2 tokens side by side in your string. Best if you use countMatches from StringUtils Apache commons library.
String sub = str.substring(i, i+1);
The above line is only getting a 2-character substring so instead of getting "cat" you'll get "ca" and it will never match. Fix this by changing 'i+1' to 'i+2'.
Edit: Now that you've clarified your question in the comments: You should have two counter variables, one to count the 'dog's and one to count the 'cat's. Then at the end return true if count_cats == count_dogs.

Categories

Resources