Last active
January 18, 2024 20:42
-
-
Save rjlutz/3c26a1be877529de8dd28049d12415d0 to your computer and use it in GitHub Desktop.
Bits to build a palindrome app, class with static method that tests a string to see if its a palindrome
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// useful link to understand the use of state | |
// https://developer.android.com/jetpack/compose/state#:~:text=mutableStateOf%20creates%20a%20MutableState%20%2C%20which,preserve%20the%20state%20across%20recompositions. | |
import android.os.Bundle | |
import android.util.Log | |
import androidx.activity.ComponentActivity | |
import androidx.activity.compose.setContent | |
import androidx.compose.foundation.Image | |
import androidx.compose.foundation.layout.* | |
import androidx.compose.material.* | |
import androidx.compose.material.icons.Icons | |
import androidx.compose.material.icons.filled.Info | |
import androidx.compose.runtime.Composable | |
import androidx.compose.runtime.MutableState | |
import androidx.compose.runtime.mutableStateOf | |
import androidx.compose.runtime.remember | |
import androidx.compose.ui.Alignment | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.res.painterResource | |
import androidx.compose.ui.text.input.TextFieldValue | |
import androidx.compose.ui.text.toLowerCase | |
import androidx.compose.ui.tooling.preview.Preview | |
import androidx.compose.ui.unit.dp | |
import androidx.compose.ui.unit.sp | |
import edu.ggc.lutz.palindrome.ui.theme.PalindromeComposeTheme | |
class MainActivity : ComponentActivity() { | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContent { | |
PalindromeComposeTheme { | |
// A surface container using the 'background' color from the theme | |
Surface(color = MaterialTheme.colors.background) { | |
UI() | |
} | |
} | |
} | |
} | |
} | |
@Preview(showBackground = true) | |
@Composable | |
fun UI() { | |
val snackbarVisibleState = remember { mutableStateOf(false) } | |
Scaffold( | |
floatingActionButton = { | |
FloatingActionButton( | |
onClick = { snackbarVisibleState.value = !snackbarVisibleState.value } | |
) { | |
Icon(Icons.Filled.Info, "") | |
} | |
} | |
) { | |
Column( | |
Modifier | |
.fillMaxSize() | |
.padding(10.dp), | |
verticalArrangement = Arrangement.SpaceBetween, | |
horizontalAlignment = Alignment.CenterHorizontally | |
) { | |
val textState = remember { mutableStateOf(TextFieldValue()) } | |
OutlinedTextField( | |
modifier = Modifier.fillMaxWidth().padding(top = 16.dp), | |
value = textState.value, | |
onValueChange = { | |
textState.value = it | |
Log.v("Palindrome", textState.value.text) | |
}, | |
label = { Text("Enter Text") } | |
) | |
Results(name = textState.value.text) | |
Snacktime(snackbarVisibleState) | |
} | |
} | |
} | |
@Composable | |
private fun Snacktime(snackbarVisibleState: MutableState<Boolean>) { | |
if (snackbarVisibleState.value) { | |
Snackbar( | |
modifier = Modifier.padding(bottom = 60.dp), | |
action = { | |
Button(onClick = { snackbarVisibleState.value = false }) { | |
Text("Dismiss") | |
} | |
} | |
) { | |
Text(text = "Palindrome Checker 1.0.0") | |
} | |
} | |
} | |
@Composable | |
fun Results(name: String) { | |
var imageResult = R.drawable.check | |
var textResult = "Is a Palindrome" | |
// if (!Palindrome.check(name)) { // the java way | |
if (!check(name)) { // the kotlin way | |
imageResult = R.drawable.x | |
textResult = "Is NOT a Palindrome" | |
} | |
Image( | |
modifier = Modifier.size(200.dp, 200.dp), | |
painter = painterResource(imageResult), | |
contentDescription = null | |
) | |
Text( | |
textResult, | |
modifier = Modifier.padding(bottom = 46.dp), | |
style = MaterialTheme.typography.h4 | |
) | |
} | |
private fun check(_s: String): Boolean { | |
//mutate string, removing leading and trailing garbage | |
var mutant = _s.replace("^[^a-zA-Z0-9]+".toRegex(), "") | |
.replace("[^a-zA-Z0-9]+$".toRegex(), "") | |
if (mutant.length <= 1) return true // base case | |
var matches = mutant.first().toLowerCase() == mutant.last().toLowerCase() | |
return if (matches) | |
// clip first and last chars, call recursively | |
check(mutant.substring(1, mutant.lastIndex)) | |
else | |
false // call again or fail | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Palindrome { | |
public static boolean check(String _s) { | |
return check(_s, 0, _s.length()-1); | |
} | |
private static boolean check(String _s, int _start, int _end) { | |
// base case | |
if (_start >= _end) return true; | |
// do some work | |
while(!Character.isLetterOrDigit(_s.charAt(_start))) | |
(_start)++; | |
while(!Character.isLetterOrDigit(_s.charAt(_end))) | |
_end--; | |
char downcaseStart = Character.toLowerCase(_s.charAt((_start))); | |
char downcaseEnd = Character.toLowerCase(_s.charAt(_end)); | |
if (downcaseStart != downcaseEnd) return false; | |
// call simpler version | |
return check(_s, (_start)+1, _end-1); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Palindrome { | |
static check(String s) { | |
return _check(s, 0, s.length - 1); | |
} | |
static _check(String s, start, end) { | |
if (start > end) return true; | |
while (!isLetterOrDigit(s, start)) start++; | |
while (!isLetterOrDigit(s, end)) end--; | |
bool _matching = (s[start].toLowerCase() == s[end].toLowerCase()); | |
return _matching ? _check(s, start + 1, end - 1) : false; | |
} | |
} | |
bool isLetterOrDigit(String s, int idx) => | |
s[idx].contains(RegExp(r'[\da-zA-Z]')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// could be a top-level function too, perhaps too much java influence here! | |
object Palindrome { | |
fun check(_s: String): Boolean { | |
return check(_s, 0, _s.length - 1) | |
} | |
private fun check(_s: String, _start: Int, _end: Int): Boolean { | |
var start = _start; // we need start to be mutable, kotlin only passes vals (not vars) | |
var end = _end; // this makes a local copy | |
if (start >= end) return true // base case | |
while (!Character.isLetterOrDigit(_s[start])) start++ // do some work | |
while (!Character.isLetterOrDigit(_s[end])) end-- | |
val downcaseStart = Character.toLowerCase(_s[start]) | |
val downcaseEnd = Character.toLowerCase(_s[end]) | |
return if (downcaseStart == downcaseEnd) check(_s, start + 1, end - 1) else false | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// another implementation in dart, more succinct, more elegant, more confusing! | |
class TersePalindrome { | |
static check(String s) { | |
return s == String.fromCharCodes(s.runes.toList().reversed); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TextWatcher textWatcher = new TextWatcher() { | |
@Override | |
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { | |
} | |
@Override | |
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { | |
} | |
@Override | |
public void afterTextChanged(Editable editable) { | |
String entered = input.getText().toString(); | |
if (Palindrome.check(entered)) { | |
Log.v(TAG, "is a palindrome"); | |
result.setImageResource(R.drawable.check); | |
} else { | |
Log.v(TAG, "is not a palindrome"); | |
result.setImageResource(R.drawable.x); | |
} | |
} | |
}; | |
input.addTextChangedListener(textWatcher); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment