In IDA, how to optimize a long "if" condition to several "if" operation? - ida

for example:
from
if(a > 0x1000|| (b>>5)&0x10 || c)
{
return 0;
}
return 1;
to
if(a > 0x1000)
{
return 0;
}
if((b>>5)&0x10)
{
return 0;
}
if(c){
return 0;
}
return 1;
I saw a picture on twitter, he just set an option in IDA's configuration, but I didn't record it. And now I can't find it. Does anyone know it?

Related

How to fix both Found 'DD'-anomaly and only one return statement

I have some difficulties when fixing PMD warnings, this was my simplified method:
public String rank(String keyword, int pageSize, int totalPage)
{
String result = "0"; // A: DataflowAnomalyAnalysis: Found 'DD'-anomaly for variable 'result'
if (isNotBlank(keyword))
{
boolean find = false; // B: DataflowAnomalyAnalysis: Found 'DD'-anomaly for variable 'find'
for (int page = 1; page < totalPage; page++)
{
int rank = getRank(keyword, pageSize, totalPage);
if (rank != 0)
{
find = true; // B(1)
result = String.valueOf(rank); // A(1)
break;
}
}
if (!find)
{
result = format("{0}+", totalPage * pageSize - 1); // A(2)
}
}
return result;
}
I tried this and got "OnlyOneReturn" warnings:
public String rank(String keyword, int pageSize, int totalPage)
{
if (isNotBlank(keyword))
{
for (int page = 1; page < totalPage; page++)
{
int rank = getRank(keyword, pageSize, totalPage);
if (rank != 0)
{
return String.valueOf(rank); // OnlyOneReturn
}
}
return format("{0}+", totalPage * pageSize - 1); // OnlyOneReturn
}
return "0";
}
How do I have to write this code please?
A 'DD'-anomaly an a dataflow analysis tells you that you assign a variable more than once without using it between the assignments. So all but the last assignment are unnecessary. It usually indicates that you didn't separate your scenarios properly. In your case you have three scenarios:
If the keyword is blank then the return value is "0".
Otherwise loop through all pages and if getRank() returns a rank other than zero then this is the return value.
Otherwise the return value is "totalPage * pageSize - 1+"
If you implement those scenarios one by one you end up with a method that has not any dataflow or other PMD issues:
public String rank(String keyword, int pageSize, int totalPage) {
String result;
if (isNotBlank(keyword)) {
result = "0";
} else {
int rank = 0;
for (int page = 1; page < totalPage && rank == 0; page++) {
rank = getRank(keyword, pageSize, totalPage);
}
if (rank != 0) {
result = String.valueOf(rank);
} else {
result = format("{0}+", totalPage * pageSize - 1);
}
}
return result;
}
If you take a closer look at the for loop you see that page is only used for looping. It is not used inside the loop. This indicates that the for loop is probably not necessary. getRank(keyword, pageSize, totalPage) should always return the same value as its arguments never change during the loop. So it might be enough to call getRank(...) just once.

Scala , java "for" in scala

I don't know how convert java "continue" to scala.
I can use marker from bool + break, but its bad idea
Google did not help :(
It's my first program in scala... yep.. it's horrible
sort java
def sort(in: Array[Int], a:Int, b:Int)
{
var i,j,mode;
double sr=0;
if (a>=b) return; // size =0
for (i=a; i<=b; i++) sr+=in[i];
sr=sr/(b-a+1);
for (i=a, j=b; i <= j;)
{
if (in[i]< sr) { i++; continue; } // left > continue
if (in[j]>=sr) { j--; continue; } // right, continue
int c = in[i]; in[i] = in[j]; in[j]=c;
i++,j--; // swap and continue
}
if (i==a) return;
sort(in,a,j); sort(in,i,b);
}
sort scala...
def SortMerger(in:List[Int], a:Int, b:Int):Unit = {
var i = 0;
var j = 0;
var mode = 0;
var sr = 0.0;
if(a>=b) return;
i=a
while(i<=b)
{
sr+=in.ElementOf(i);
i += 1
}
sr=sr/(b-a+1)
i=a
j=b
while(i<=j)
{
if(in.ElementOf(i)<sr) {
i += 1;
// where continue??? ><
}
}
return
}
Scala has no continue statement, but what you are trying to do can be done with a simple if/else structure.
while(i<=j)
{
if(in(i) < sr) {
i += 1
} else if (in(j) >= sr) {
j -= 1
} else {
int c = in(i)
in(i) = in(j)
in(j) = c
i += 1
j -= 1
}
}
Note that the type of in here should be Array, not List

Is it possible to de-duplicate if statements and their body in Rust, perhaps by using macros?

Say we have a large block:
mod module {
pub const fiz: u32 = (1 << 0);
// etc...
}
flag = {
if (var & module::fiz) != 0 { module::fiz }
else if (var & module::foo) != 0 { module::foo }
else if (var & module::bar) != 0 { module::bar }
else if (var & module::baz) != 0 { module::baz }
// .. there could be many more similar checks
};
With simply replacement macro its possible to do:
#define TEST(f) ((var) & (f)) != 0 { f }
Allowing:
flag = {
if TEST(module::fiz)
else if TEST(module::foo)
else if TEST(module::bar)
else if TEST(module::baz)
}
It seems Rust doesn't allow a macro to declare part of an if statement.
I managed to avoid repetition using assignment, but its quite ugly.
flag = {
let f;
if (var & {f = module::fiz; f }) != 0 { f }
else if (var & {f = module::foo; f }) != 0 { f }
else if (var & {f = module::bar; f }) != 0 { f }
else if (var & {f = module::baz; f }) != 0 { f }
};
Does Rust provide some convenient/elegant way to allow repetition in this case?
I don't think flag checking is the important part of this question, the issue is that you may want to repeat content in the check again in the body of an if statement, e.g.:
if (foo && OTHER_EXPRESSION) { do(); something_with(OTHER_EXPRESSION) }
else if (foo && SOME_EXPRESSION) { do(); something_with(SOME_EXPRESSION) }
I think you have an X/Y problem here, so I am going to solve this without using if/else.
What you seem to be doing is checking for the presence of a bit pattern, and prioritise the order in which said patterns are checked for (unclear if it matters, but let's assume it does).
So, let's do this the functional way:
let constants = [fiz, foo, bar, baz];
let flag = constants.iter().filter(|v| var & *v == **v).next();
And it just works, no macro or repetitive stuff.
If you want to use macros, you can write it like this:
mod module {
pub const fiz: u32 = (1 << 0);
pub const foo: u32 = (1 << 1);
pub const bar: u32 = (1 << 2);
pub const baz: u32 = (1 << 3);
}
macro_rules! check_bits {
([$($Constant:expr),*]) => {
|var: u32| {
$(if ($Constant & var) != 0 {
return $Constant;
})*
return 0;
}
}
}
fn main() {
let var = 5;
let checker = check_bits!([module::bar, module::fiz, module::foo, module::baz]);
assert_eq!(checker(var), module::bar);
println!("All OK");
}

How to determine if a string can be manipulated to be rewritten as a palindrome?

I believe this can be achieved by counting the instances for each character in that string. Even if a single character in that string is repeated at least twice, we can declare that string as a palindrome.
For example: bbcccc can be rewritten as bccccb or ccbbcc.
edified can be rewritten as deified.
Some book mentioned we should be using hash table. I think we can just use a list and check for the character count.
Do you think the logic is correct?
Yes, the main idea is to count the times of each char existing in the string. And it will be true if the string has at most one char occurs odd times and all others even times.
For example:
aabbcc => acbbca
aabcc => acbca
aabbb => abbba
No. You don't have to use a hash map (as some of the other answers suggest). But the efficiency of the solution will be determined by the algorithm you use.
Here is a solution that only tracks odd characters. If we get 2 odds, we know it can't be a scrambled palindrome. I use an array to track the odd count. I reuse the array index 0 over and over until I find an odd. Then I use array index 1. If I find 2 odds, return false!
Solution without a hash map in javascript:
function isScrambledPalindrome(input) {
// TODO: Add error handling code.
var a = input.split("").sort();
var char, nextChar = "";
var charCount = [ 0 ];
var charIdx = 0;
for ( var i = 0; i < a.length; ++i) {
char = a[i];
nextChar = a[i + 1] || "";
charCount[charIdx]++;
if (char !== nextChar) {
if (charCount[charIdx] % 2 === 1) {
if (charCount.length > 1) {
// A scrambled palindrome can only have 1 odd char count.
return false;
}
charIdx = 1;
charCount.push(0);
} else if (charCount[charIdx] % 2 === 0) {
charCount[charIdx] = 0;
}
}
}
return true;
}
console.log("abc: " + isScrambledPalindrome("abc")); // false
console.log("aabbcd: " + isScrambledPalindrome("aabbcd")); // false
console.log("aabbb: " + isScrambledPalindrome("aabbb")); // true
console.log("a: " + isScrambledPalindrome("a")); // true
Using a hash map, I found a cool way to only track the odd character counts and still determine the answer.
Fun javascript hash map solution:
function isScrambledPalindrome( input ) {
var chars = {};
input.split("").forEach(function(char) {
if (chars[char]) {
delete chars[char]
} else {
chars[char] = "odd" }
});
return (Object.keys(chars).length <= 1);
}
isScrambledPalindrome("aba"); // true
isScrambledPalindrome("abba"); // true
isScrambledPalindrome("abca"); // false
Any string can be palindrome only if at most one character occur odd no. of times and all other characters must occur even number of times.
The following program can be used to check whether a palindrome can be string or not.
vector<int> vec(256,0); //Vector for all ASCII characters present.
for(int i=0;i<s.length();++i)
{
vec[s[i]-'a']++;
}
int odd_count=0,flag=0;
for(int i=0;i<vec.size();++i)
{
if(vec[i]%2!=0)
odd_count++;
if(odd_count>1)
{
flag=1;
cout<<"Can't be palindrome"<<endl;
break;
}
}
if(flag==0)
cout<<"Yes can be palindrome"<<endl;
My code check if can it is palindrome or can be manipulated to Palindrome
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
//Tested on windows 64 bit arhc by using cygwin64 and GCC
bool isPalindrome (char *text);
int main()
{
char text[100]; // it could be N with defining N
bool isPal,isPosPal = false;
printf("Give me a string to test if it is Anagram of Palindrome\n");
gets(text);
isPal = isPalindrome(text);
isPosPal = isAnagramOfPalindrome(text);
if(isPal == false)
{
printf("Not a palindrome.\n");
}
else
{
printf("Palindrome.\n");
}
if(isPosPal == false)
{
printf("Not Anagram of Palindrome\n");
}
else
{
printf("Anagram of Palindrome\n");
}
return 0;
}
bool isPalindrome (char *text) {
int begin, middle, end, length = 0;
length = getLength(text);
end = length - 1;
middle = length/2;
for (begin = 0; begin < middle; begin++)
{
if (text[begin] != text[end])
{
return false;
}
end--;
}
if (begin == middle)
return true;
}
int getLength (char *text) {
int length = 0;
while (text[length] != '\0')
length++;
printf("length: %d\n",length);
return length;
}
int isAnagramOfPalindrome (char *text) {
int length = getLength(text);
int i = 0,j=0;
bool arr[26] = {false};
int counter = 0;
//char string[100]="neveroddoreven";
int a;
for (i = 0; i < length; i++)
{
a = text[i];
a = a-97;
if(arr[a])
{
arr[a] = false;
}
else
{
arr[a] = true;
}
}
for(j = 0; j < 27 ; j++)
{
if (arr[a] == true)
{
counter++;
}
}
printf("counter: %d\n",counter);
if(counter > 1)
{
return false;
}
else if(counter == 1)
{
if(length % 2 == 0)
return false;
else
return true;
}
else if(counter == 0)
{
return true;
}
}
as others have posted, the idea is to have each character occur an even number of times for an even length string, and one character an odd number of times for an odd length string.
The reason the books suggest using a hash table is due to execution time. It is an O(1) operation to insert into / retrieve from a hash map. Yes a list can be used but the execution time will be slightly slower as the sorting of the list will be O(N log N) time.
Pseudo code for a list implementation would be:
sortedList = unsortedList.sort;
bool oddCharFound = false;
//if language does not permit nullable char then initialise
//current char to first element, initialise count to 1 and loop from i=1
currentChar = null;
currentCharCount = 0;
for (int i=0; i <= sortedList.Length; i++) //start from first element go one past end of list
{
if(i == sortedList.Length
|| sortedList[i] != currentChar)
{
if(currentCharCount % 2 = 1)
{
//check if breaks rule
if((sortedList.Length % 2 = 1 && oddCharFound)
|| oddCharFound)
{
return false;
}
else
{
oddCharFound = true;
}
}
if(i!= sortedList.Length)
{
currentCharCount = 1;
currentChar = sortedList[i];
}
}
else
{
currentCharCount++;
}
}
return true;
Here is a simple solution using an array; no sort needed
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[256] = { 0 };
unsigned char i[] = {"aaBcBccc"};
unsigned char *p = &i[0];
int c = 0;
int j;
int flag = 0;
while (*p != 0)
{
a[*p]++;
p++;
}
for(j=0; j<256; j++)
{
if(a[j] & 1)
{
c++;
if(c > 1)
{
flag = 1;
break;
}
}
}
if(flag)
printf("Nope\n");
else
printf("yup\n");
return 0;
}
C#:
bool ok = s.GroupBy(c => c).Select(g => g.Count()).Where(c => c == 1).Count() < 2;
This solution, however, does use hashing.
Assuming all input characters are lower case letters.
#include<stdio.h>
int main(){
char *str;
char arr[27];
int j;
int a;
j = 0;
printf("Enter the string : ");
scanf("%s", str);
while (*str != '\0'){
a = *str;
a = a%27;
if(arr[a] == *str){
arr[a]=0;
j--;
}else{
arr[a] = *str;
j++;
}
*str++;
}
if(j==0 || j== -1 || j==1){
printf ("\nThe string can be a palindrome\n");
}
}

Change Value of Duplicate Object in NSMutableArray?

I have the method below, which in my Blackjack app will get the value of the hand which is an NSMutableArray. The problem here is that when 2 Ace's are in a hand, it should be a 12, but because it counts Ace's as 11, it results in being 22, which then makes lowValue returned.
How can I make it so that I can check and see if the for loop has already found an Ace and if it finds another, makes the next Ace worth only 1, not 11?
Thanks!
int getHandValue(NSMutableArray *hand) {
int lowValue = 0;
int highValue = 0;
for (KCCard *aCard in hand) {
if (aCard.value == Ace) {
lowValue+= 1;
highValue+= 11;
} else if (aCard.value == Jack || aCard.value == Queen || aCard.value == King) {
lowValue += 10;
highValue += 10;
} else {
lowValue += aCard.value;
highValue += aCard.value;
}
}
return (highValue > 21) ? lowValue : highValue;
}
Perhaps you can add a boolean value before the for loop setting it initially to NO. When an Ace is found then you can break from the for loop after setting the boolean to YES, that way if you encounter another Ace && your boolean value == YES you can handle the case accordingly.
int getHandValue(NSMutableArray *hand) {
int lowValue = 0;
int highValue = 0;
BOOL isFoundAce = NO;
for (KCCard *aCard in hand) {
if (aCard.value == Ace) {
if (isFoundAce) {
lowValue+= 1;
highValue+= 1;
}
else {
lowValue+= 1;
highValue+= 11;
isFoundAce= YES;
}
} else if (aCard.value == Jack || aCard.value == Queen || aCard.value == King) {
lowValue += 10;
highValue += 10;
} else {
lowValue += aCard.value;
highValue += aCard.value;
}
}
return (highValue > 21) ? lowValue : highValue;
}
My example without a redundant code from zsxwing's example:
int getHandValue(NSMutableArray *hand) {
int cardValue = 0;
int aceCount = 0;
for (KCCard *aCard in hand) {
if (aCard.value == Ace) {
aceCount++;
cardValue += 11;
} else if (aCard.value == Jack || aCard.value == Queen || aCard.value == King) {
cardValue += 10;
} else {
cardValue += aCard.value;
}
}
while ((cardValue > 21) && (aceCount > 0)) {
cardValue -= 10;
aceCount--;
}
return cardValue;
}