EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, sub code=0x0). error while making data structure - swift

I am practicing my array form of data structure with swift.
I made a class "student"
and there are functions like display() and delete()
However, the application is not working.
There is an error message that
EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, sub code=0x0).
I think this error is about "optional" problem.
Here is my code.
class student
{
var studentArray = [[String]?]()
var numberOfStudents : Int = 10;
func display()
{
for (var i = 0; i < numberOfStudents ; i++)
{
print("{");
for (var j = 0; j < 2; j++)
{
print(studentArray[i]![j] + " ");
}
print("}");
}
}
func delete( value : String)
{
var i = 0
for ( i = 0; i < numberOfStudents ; i++)
{
if (value == studentArray[i]![1])
{
break;
}
}
if (i == numberOfStudents - 1 )
{
print("not found");
}
else
{
for (var k = i; k < numberOfStudents - 1 ; k++)
{
studentArray[k]![1] = studentArray[k+1]![1];
studentArray[k]![0] = studentArray[k+1]![0];
}
numberOfStudents--;
}
}
}
var hello = student()
hello.studentArray = [["0","0ee"],["9","9ee", ]]
hello.display() // I have a error at this point
hello.studentArray
Could anyone explain what is about it for me?

There are several mistakes in your code. The actual error is caused by your numberOfStudents variable, which is hard coded to 10, even though the array only contains 2 elements. Use studentArray.count in your for loop, not 10. Then read the Swift manual. You should not be using optionals nor C-style for loops in this example.
Here's how I would do it...
class Student { // Capitalise your classes
// Unnecessary whitespace removed
var studentArray: [[String]] = [] // No need for optionals here
/*
var numberOfStudents : Int = 10; // var is useless & wrong, also no need for semi-colon
*/
func display() {
/* A Swift-ier way to do this is
for student in studentArray {
print("{")
for field in student {
print(field + " ")
}
print("}")
}
However, using indexing:
*/
for i in 0 ..< studentArray.count {
print("{")
for j in 0 ..< studentArray[i].count { // Don't *know* this will be 2
print(studentArray[i][j] + " ") // Don't need semi-colons unless you want to put multiple statements on the same line
}
print("}")
}
}
/* func delete() not used in question, so removed from answer */
}
var hello = Student()
hello.studentArray = [["0","0ee"], ["9","9ee", ]] // Note spurious (but not wrong) comma
hello.display()
hello.studentArray

Related

How to Convert JS Password Strength Meter to Swift

I'm trying to convert this javascript password score function to swift, so I can use the same logic on mobile as we do on web. Here is the JS fiddle with the code to test:
function scorePassword(pass) {
var score = 0;
if (!pass)
return score;
// award every unique letter until 5 repetitions
var letters = new Object();
for (var i=0; i<pass.length; i++) {
letters[pass[i]] = (letters[pass[i]] || 0) + 1;
score += 5.0 / letters[pass[i]];
}
// bonus points for mixing it up
var variations = {
digits: /\d/.test(pass),
lower: /[a-z]/.test(pass),
upper: /[A-Z]/.test(pass),
nonWords: /\W/.test(pass),
}
variationCount = 0;
for (var check in variations) {
variationCount += (variations[check] == true) ? 1 : 0;
}
score += (variationCount - 1) * 10;
return parseInt(score);
}
function checkPassStrength(pass) {
var score = scorePassword(pass);
if (score > 80)
return "Strong";
if (score > 60)
return "Good";
if (score >= 30)
return "Weak";
return "";
}
I'm having an issue in converting this part:
var letters = new Object();
for (var i=0; i<pass.length; i++) {
letters[pass[i]] = (letters[pass[i]] || 0) + 1;
score += 5.0 / letters[pass[i]];
}
I've tried to create a dictionary to store the character as key and then increment the value with each occurrences of that key, but it's not working as expected.
let string = "Testing22!"
var score = 0
var dictionary = [String.Element: Int]()
for x in string {
let value = dictionary[x] ?? 0
dictionary[x] = value + 1
score += 5 / value
}
print(dictionary) //["s": 1, "T": 1, "g": 1, "2": 2, "n": 1, "i": 1, "!": 1, "t": 1, "e": 1]
print(score)
I'm also not sure of the most efficient way to handle the regex checks for the bonus points section.
I'd port it over to swift like this, I'm sure there are some improvements to be made, but thats a quick conversion:
func scorePassword(_ inputString: String?) -> Double {
var score: Double = 0
guard let string = inputString, !string.isEmpty else { return score }
// award every unique letter until 5 repetitions
let countedSet = NSCountedSet()
for x in string {
countedSet.add(x)
score += 5.0 / Double(countedSet.count(for: x))
}
// bonus points for mixing it up
let variations = [
"^(?=.*[0-9]).*$",
"^(?=.*[a-z]).*$",
"^(?=.*[A-Z]).*$",
"^(?=.*\\W).*$"
]
var variationCount: Double = 0
for check in variations {
print(string.testRegex(check))
variationCount += string.testRegex(check) ? 1 : 0
}
score += (variationCount - 1) * 10
return floor(score)
}
func checkPassStrength(_ inputString: String?) -> String {
let score = scorePassword(inputString)
if score > 80 {
return "Strong"
} else if score > 60 {
return "Good"
} else if score > 30 {
return "Weak"
}
return ""
}
extension String {
func testRegex(_ regex: String) -> Bool {
let test = NSPredicate(format: "SELF MATCHES %#", regex)
return test.evaluate(with: self)
}
}
You can run js code inside Swift and get the result from it, so you can share code between platforms.
let jsSource = """
function scorePassword(pass) {
var score = 0;
if (!pass)
return score;
// award every unique letter until 5 repetitions
var letters = new Object();
for (var i=0; i<pass.length; i++) {
letters[pass[i]] = (letters[pass[i]] || 0) + 1;
score += 5.0 / letters[pass[i]];
}
// bonus points for mixing it up
var variations = {
digits: /d/.test(pass),
lower: /[a-z]/.test(pass),
upper: /[A-Z]/.test(pass),
nonWords: /W/.test(pass),
}
variationCount = 0;
for (var check in variations) {
variationCount += (variations[check] == true) ? 1 : 0;
}
score += (variationCount - 1) * 10;
return parseInt(score);
}
function checkPassStrength(pass) {
var score = scorePassword(pass);
if (score > 80)
return "Strong";
if (score > 60)
return "Good";
if (score >= 30)
return "Weak";
return "";
}
"""
let context = JSContext()
context?.evaluateScript(jsSource)
let testFunction = context?.objectForKeyedSubscript("scorePassword")
let result = testFunction?.call(withArguments: ["1234"])
print("js result : " , result )
Note; I edited the part "digits: /\d/.test(pass)" to "digits: /d/.test(pass)"

VS Code extension how to edit in context?

Her is the class I use automatically capitalize true, false, ...
export class StUpdater {
private _lines: number;
private _strings: Array<string>;
constructor() {
this._lines = 0;
this._strings = ['true', 'false', 'exit', 'continue', 'return'];
}
Update(Cntx: boolean = false) {
let editor = window.activeTextEditor;
if (!editor || (editor.document.languageId != 'st')) {
window.showErrorMessage('No editor!')
return;
}
let doc = editor.document;
if (Cntx == false) {
if (this._lines >= doc.lineCount) {
this._lines = doc.lineCount;
return;
}
this._lines = doc.lineCount;
let AutoFormat = workspace.getConfiguration('st').get('autoFormat');
if (!AutoFormat) {
return;
}
}
let edit = new WorkspaceEdit();
for (let line = 0; line < doc.lineCount; line++) {
const element = doc.lineAt(line);
for (let i = 0; i < this._strings.length; i++) {
let str = this._strings[i];
let last_char = 0;
while (element.text.indexOf(str, last_char) >= 0) {
let char = element.text.indexOf(str, last_char);
last_char = char + str.length;
edit.replace(
doc.uri,
new Range(
new Position(line, char),
new Position(line, last_char)
),
str.toUpperCase()
);
}
}
}
return workspace.applyEdit(edit);
}
public dispose() {
}
}
This code works fine, but I do not want to replace it inside the string or comment. How do I do that? I cannot find preg version of replace and even if I do, in one line I do not know if it is comment or not if it is multiple line comment.
If I understand you correctly you want capitalize only certain elements (identifiers probably), but not words in comments or strings, correct? That requires to identify lexical elements in the text, which is a mapping of a range of letters to a lexical type. This is usually done by a lexer. It's not difficult to write one by hand which walks over the characters on top of your current processing and find those ranges that can be manipulated.

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

Google Spreadsheet - How to avoid sending email duplicates?

I am having an issue with a script. I used the following script from Google Developers Website in order to do a simple merge mail. See https://developers.google.com/apps-script/articles/mail_merge
I modified a bit the script so to prevent email duplicates. However, even if the script seems to work as it marks 'EMAIL_SENT' in each row every time an email is sent. It does not pay attention if the mail as already been marked and still send the mail.
I believe there is an error at line 16 "var emailSent = rowData[6];"
I would really appreciate if someone could help me. Whoever you are thanks in advance.
Here is the modified script :
var EMAIL_SENT = "EMAIL_SENT";
function sendEmails() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var dataSheet = ss.getSheets()[0];
var dataRange = dataSheet.getRange(2, 1, dataSheet.getMaxRows() - 1, 7);
var templateSheet = ss.getSheets()[1];
var emailTemplate = templateSheet.getRange("A2").getValue();
var objects = getRowsData(dataSheet, dataRange);
for (var i = 0; i < objects.length; ++i) {
var Resume = DriveApp.getFilesByName('Resume.pdf') var Portfolio = DriveApp.getFilesByName('Portfolio.pdf') var rowData = objects[i];
var emailText = fillInTemplateFromObject(emailTemplate, rowData);
var emailSubject = "Architectural Internship";
var emailSent = rowData[6];
if (emailSent != EMAIL_SENT) {
MailApp.sendEmail(rowData.emailAddress, emailSubject, emailText, {
attachments: [Resume.next(), Portfolio.next()]
});
dataSheet.getRange(2 + i, 7).setValue(EMAIL_SENT);
SpreadsheetApp.flush();
}
}
}
function fillInTemplateFromObject(template, data) {
var email = template;
var templateVars = template.match(/\${\"[^\"]+\"}/g);
for (var i = 0; i < templateVars.length; ++i) {
var variableData = data[normalizeHeader(templateVars[i])];
email = email.replace(templateVars[i], variableData || "");
}
return email;
}
function getRowsData(sheet, range, columnHeadersRowIndex) {
columnHeadersRowIndex = columnHeadersRowIndex || range.getRowIndex() - 1;
var numColumns = range.getEndColumn() - range.getColumn() + 1;
var headersRange = sheet.getRange(columnHeadersRowIndex, range.getColumn(), 1, numColumns);
var headers = headersRange.getValues()[0];
return getObjects(range.getValues(), normalizeHeaders(headers));
}
function getObjects(data, keys) {
var objects = [];
for (var i = 0; i < data.length; ++i) {
var object = {};
var hasData = false;
for (var j = 0; j < data[i].length; ++j) {
var cellData = data[i][j];
if (isCellEmpty(cellData)) {
continue;
}
object[keys[j]] = cellData;
hasData = true;
}
if (hasData) {
objects.push(object);
}
}
return objects;
}
function normalizeHeaders(headers) {
var keys = [];
for (var i = 0; i < headers.length; ++i) {
var key = normalizeHeader(headers[i]);
if (key.length > 0) {
keys.push(key);
}
}
return keys;
}
function normalizeHeader(header) {
var key = "";
var upperCase = false;
for (var i = 0; i < header.length; ++i) {
var letter = header[i];
if (letter == " " && key.length > 0) {
upperCase = true;
continue;
}
if (!isAlnum(letter)) {
continue;
}
if (key.length == 0 && isDigit(letter)) {
continue;
}
if (upperCase) {
upperCase = false;
key += letter.toUpperCase();
} else {
key += letter.toLowerCase();
}
}
return key;
}
// Returns true if the cell where cellData was read from is empty. // Arguments: // - cellData: string function isCellEmpty(cellData) {
return typeof(cellData) == "string" && cellData == "";
}
// Returns true if the character char is alphabetical, false otherwise. function isAlnum(char) { return char >= 'A' && char <= 'Z' || char >= 'a' && char <= 'z' || isDigit(char); }
// Returns true if the character char is a digit, false otherwise. function isDigit(char) { return char >= '0' && char <= '9'; }
Your code is really hard to read and the functions that return 2 or more objects make it even harder...you are using variable names that are also a bit confusing.... but that is probably a personal pov :-)
Anyway, I think I've found the issue: when you write var rowData = objects[i];
This "object" is actually the result of the getRowData function but if you look at this function, you'll see that it returns 2 objects, the first one being itself the result of another function (getObjects) ...
You are checking the value is the 6th element of the array which is actually an object and compare it to a string. The equality will never be true.
I didn't go further in the analyse since I found it really confusing ( as I already said) but at least you have a first element to check .
I would suggest you rewrite this code in a more simple way and use more appropriate variable names to help you while debugging.
I would recommend logging both values before executing to make sure they are the same. I would also guess that the email_sent and EMAIL_SENT are different data types. Can also try forcing the value to string for comparison.
To clarify:
logger.Log(emailSent);
logger.Log(EMAIL_SENT);
if (emailSent.toString() != EMAIL_SENT.toString())
{...
Error is in this line of code -
var dataRange = sheet.getRange(startRow, 1, numRows, 2)
It's considering only 2 columns in the range. Changed 2 to 3 and it worked fine.

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");
}
}