This code finds the two roots of a quadratic equation in the form ax^2+bx+c
Is my solution good time/space-complexity wise, and how I would go about allowing users to see the imaginary roots if the quadratic has any?
public function factor($a=0, $b=0, $c=0) {
$positive_solution = (-$b + sqrt($b**2-4*$a*$c))/2*$a;
$negative_solution = (-$b - sqrt($b**2-4*$a*$c))/2*$a;
if($b**2-4*$a*$c < 0) {
return "Solutions are imaginary";
}
$factor_one = $positive_solution * -1;
$factor_two = $negative_solution * -1;
$factor_one > 0 ? $factor_one = "+ " . $factor_one : $factor_one = "- " . $factor_one;
$factor_two > 0 ? $factor_two = "+ " . $factor_two : $factor_two = "- " . $factor_two;
return "Your roots are located at (0, " . $positive_solution . ")(0, " . $negative_solution . "),
Thus, the problem can be factored into (x " . $factor_one . ")(x " . $factor_two . ")";
}
the if($b**2-4*$a*$c < 0) is too late
You already used the sqrt so domain error might be thrown move the if to start
for imaginary part you just use negation or abs value
simply sqrt(-($b**2-4*$a*$c)) or sqrt(abs($b**2-4*$a*$c)) not sure if php uses abs or fabs for floats or if you even use floats... (havent code in php for ages)
I would combine this to something like this (just pseudo code as the var $ makes me dizzy :) ):
q = b*b-4*a*c
d = sqrt(abs(q))
if (q<0)
{
a0 = -b/(2*a);
b0 = +d/(2*a);
a1 = -b/(2*a);
b1 = -d/(2*a);
}
else
{
a0 = (-b + d)/(2*a);
b0 = 0
a1 = (-b - d)/(2*a);
b1 = 0
}
Where a0+i*b0 and a1+i*b1 are the 2 solutions where i=sqrt(-1)
Related
I need to print some numbers in a sequence with + and - between them. However, I don't know beforehand which number is going to be positive and which is going to be negative. Currently, I echo them like this:
echo "$a + $b + $c + $d + $e + $f";
Let's say the values of $a to $f are all positive. I will get something like: 5 + 10 + 12 + 18 + 9 + 7.
However, if some of the values are negative, I will get something like 5 + -10 + 12 + -18 + 9 + - 7. The ideal output in this case would have been 5 - 10 + 12 - 18 + 9 - 7.
Please not that I don't want to calculate the final result of addition or subtraction. I just want to print it all on the webpage with correct signs.
I could do so by writing 6 nested if() blocks but that seems like a lot of work and doing it every time will be error prone. Is there anything clever that I can do to output the right sign.
The easiest way would be to correct the operator appearance in the final string:
$s = '5 + -10 + 12 + -18 + 9 + - 7'; // result of interpolation or concatenation
$s = str_replace('+ -', '- ', $s);
// => "5 - 10 + 12 - 18 + 9 - 7"
If this is possible for you, this is as fast as it gets -- no looping (in php), no treating each number one at a time with a conditional. If you loop anyway, I'd recommend #Phils suggestion with array_reduce -- functional style php -- adapted to your needs.
Need to check for each variable manually like this:
echo "$a " . ($b < 0 ? " - " . abs($b) : " + $b") . ($c < 0 ? " - " . abs($c) : " + $c") . ($d < 0 ? " - " . abs($d) : " + $d") . ($e < 0 ? " - " . abs($e) : " + $e") . ($f < 0 ? " - " . abs($f) : " + $f");
you can use php sprintf function.
function formatNum($num){
return sprintf("%+d",$num);
}
or
function formatNum($num) {
$num = (int) $num; // or (float) if you'd rather
return (($num >= 0) ? '+' : '-') . $num; // implicit cast back to string
}
for more detail please read it :- http://php.net/manual/en/function.sprintf.php
try this
$a = 10;
$b=-20;
$text = $a." ".$b;
$text= str_replace(" ", "+", $text);
echo $text;
OUTPUT
10+-20
Put the numbers in an array and use array_reduce to create the string
$numbers = [5, -10, 12, -18, 9, -7];
$first = array_shift($numbers);
echo array_reduce($numbers, function($str, $num) {
return $str . sprintf(' %s %d', $num < 0 ? '-' : '+', abs($num));
}, $first);
Demo ~ https://eval.in/1034635
This way you can handle an arbitrary amount of numbers without duplicating logic everywhere.
I'm trying to read data from my online mySQL server using WinHttpRequest in VBA.
Dim objHTTP As New WinHttp.WinHttpRequest
With objHTTP
.Open "POST", "http://www.dname.com/ruski/php/getNewestPID.php", True
.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded; charset=""UTF-8"""
.Send "PID=" & lngPID
.WaitForResponse
Debug.Print .ResponseText
End With
<?php
$PID = $_POST['PID'];
require_once ('config.php');
if(!$PID>0){
die("##### Error: getNewestPID failed - PID='" . $PID . "' #####");
}
$phrases = mysql_query("SELECT * FROM phrases WHERE (PID > '$PID')");
if(!$phrases){
die("##### Error: getNewestPID SELECT failed - PID=" . $PID . " - " . mysql_error() . " #####");
}
mysql_close($db);
echo "data=";
while($row = mysql_fetch_array($phrases)) {
echo $row[0] . "|" . $row[1] . "|" . $row[2] . "|" . $row[3];
}
?>
All works well, but cyrillic text is returned like:
data=21361|105||Ð?алÑ?Ñ?ик игÑ?аеÑ? на ÑкÑ?ипке в Ñвоей комнаÑ?Ð
My db uses UTF-8 Unicode. I know cyrillic works in tables and forms, but views junk in the VB editor.
I tried this:
Set FileStream = CreateObject("ADODB.Stream")
FileStream.Open
FileStream.Type = 1 'Binary
FileStream.Write objHTTP.ResponseBody
FileStream.Position = 0
FileStream.Type = 2 'adTypeText
FileStream.Charset = "Windows-1251" ' https://msdn.microsoft.com/en-us/library/ms526296(v=exchg.10).aspx
strText = FileStream.ReadText
FileStream.Close
ending up with junk in the record:
Мальчик играет на скрипке в своей комнате.
The best result is with:
mb_convert_encoding($row[3], "Windows-1251", "UTF-8")
Ìàëü÷èê èãðàåò íà ñêðèïêå â ñâîåé êîìíàòå.
This is not very elegant but it worked for me when I had similar issues. It is simply a function that will manually go from 1251 into Unicode. This one works for Russian and Ukrainian but according to which language you are working with there may be different characters and you would need to add them to the if statement. Also consider adding an else if that throws a question mark in case the character you are looking for is not found.
Public Function AsciitoUni(base_cell As String) As String
AsciitoUni = ""
For i = 1 To Len(base_cell)
Dim s As String
Dim u As Integer
Dim a As Integer
s = Mid(base_cell, i, 1)
a = Asc(s)
If (a <= 127) Then
u = a
ElseIf (a >= 192) And (a <= 255) Then
u = a + 848
ElseIf (a = 184) Then
u = 1105
ElseIf (a = 186) Then
u = 1108
ElseIf (a = 179) Then
u = 1110
ElseIf (a = 191) Then
u = 1111
ElseIf (a = 168) Then
u = 1025
ElseIf (a = 170) Then
u = 1028
ElseIf (a = 178) Then
u = 1030
ElseIf (a = 175) Then
u = 1031
ElseIf (a = 185) Then
u = 8470
End If
AsciitoUni = AsciitoUni & ChrW(u)
Next
End Function
I've a littile question about preg_matches, these regex things are really hard to understand and I hope someone can give the right awnser!
I have the following text:
0A-24-423
But this can also be:
0A-242-2
or
0A-2-423
How can I use preg_matches to filter these? I was using
substr($something, 0,2)
so that it captures 0A and
substr($seat, 4,5)
This will capture 24 but when you get 242 it wont capture the last 2....
Hope someone can help creating this in preg_match!
to make it more clear what I have now:
foreach($_POST['seats'] AS $seat) {
if ($count > 0) {
$selectQuery .= " || ";
}
$selectQuery .= " ( rowId = '" . substr($seat, 0,2) . "'";
$selectQuery .= " and `order` = " . substr($seat, 3,5) . " ";
$selectQuery .= " and columnId = " . substr($seat, 6) . " ) ";
$count++;
and $seat had the following format XXXXXX and using substr I can get the right things (for example: 0J3017)
Something Like this should do it:
$selectQuery = "SELECT * from seats where ";
$count = 0;
$pattern = "I DON'T KNOW :( ";
foreach($_POST['seats'] AS $seat) {
if ($count > 0) {
$selectQuery .= " || ";
}
preg_match($pattern, $seats, $matches);
$selectQuery .= " ( rowId = '" . $matches[0] . "'";
$selectQuery .= " and `order` = " . $matches[1] . " ";
$selectQuery .= " and columnId = " . $matches[2] . " ) ";
$count++;
and $seats is explained in the beginning of the post (it has a format of XX-XXX-XXX
where the first 2 XX are 0[A-Z] (yes the 0 is correct)
where the 3 first XXX are [0-9]
Where the last 3 XXX are [0-9]
EDIT:
there are 2 ways to solve this.
Option 1:
$pattern = "/(.*)-(.*)-(.*)/";
or use explode() function.
It does not look like you need to be using regular expressions. Here's an example using explode() and list():
list($row_id, $order, $column_id) = explode('-', $seat, 3);
You could then use those three new variables in your $selectQuery.
EDIT : Since the OP has stated his requirement as a comment to my answer I have updated my answer accordingly.
You can try this:
$pattern = "/[A-Z\d]{1,2}-[A-Z\d]{1,3}-[A-Z\d]{1,3}/";
$matched = preg_match($pattern, $something);
if ($matched === 0) {
die('regex did not match');
}
$matched will give you 1 for a matched string and 0 if not matched.
Hi i have the table structure as follows
id --auto increment id
alphabet
user_id
name
and while adding i needs to insert the english alphabets to users as incremental order like this A,B,C,....Z,AA,AB,AC,...AZ,BA,BB,BC,.....BZ.
I need to get like this
id alphabet user_id name
------------------------------------------
1 A 1 name-1
2 B 1 name-2
. . . .
. . . .
26 Z 1 name-n
27 A 2 name-1
28 B 2 name-2
. . . .
. . . .
52 Z 2 name-52
53 AA 2 name-53
. . . .
. . . .
. . . .
. AZ 2 .
Thanks for your time.
It's quite easy that you use php to implement this,
please check codes below
$i = 'A';
echo $i;
echo PHP_EOL;
while($i != 'ZZ')
{
echo ++$i;
echo PHP_EOL;
}
or see the results in http://codepad.org/QB4kyV7U
Check this similar article:
Algorithm to get the excel-like column name of a number
Here's a nice simple recursive function (Based on zero indexed numbers, meaning 0 == A, 1 == B, etc)...
function getNameFromNumber($num) {
$numeric = $num % 26;
$letter = chr(65 + $numeric);
$num2 = intval($num / 26);
if ($num2 > 0) {
return getNameFromNumber($num2 - 1) . $letter;
} else {
return $letter;
}
}
And if you want it one indexed (1 == A, etc):
function getNameFromNumber($num) {
$numeric = ($num - 1) % 26;
$letter = chr(65 + $numeric);
$num2 = intval(($num - 1) / 26);
if ($num2 > 0) {
return getNameFromNumber($num2) . $letter;
} else {
return $letter;
}
}
Tested with numbers from 0 to 10000...
Sounds a lot like this SO article
MYSQL: how to "reorder" a table
Is there an absolute necessity to do what you are wanting when you can use sorting to output your data however you want?
This is more of a puzzle than anything. I've actually found a solution but it is so slow I thought I lost my internet connection (see below).
Here's the problem:
Let's say I have an array of numbers, like so:
$numbers_array = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
Let's also say that I have a number some numbers, stored in variables like so:
$sum = 15;
$sum2 = 24;
$sum3 = 400;
I am trying to create a function that will return true if any of the numbers in $numbers_array can be added together (each only used once) to form the sums:
function is_summable($array_of_nums, $sum_to_check) {
//What to put here?
}
var_dump(is_summable($numbers_array, $sum));
var_dump(is_summable($numbers_array, $sum2));
var_dump(is_summable($numbers_array, $sum3));
The above should output:
bool(true)
bool(true)
bool(false)
Because 7 + 8 = 15, 7 + 8 + 9 = 24, but no combination of 1-9 can create 200.
Here's my EXTREMELY slow solution:
function is_summable($numbers, $sum) {
//Sort provided numbers and assign numerical keys.
asort($numbers);
$numbers = array_values($numbers);
//Var for additions and var for number of provided numbers.
$total = 0;
$numbers_length = count($numbers);
//Empty var to fill below.
$code = '';
//Loop and add for() loops.
for ($i = 0; $i < $numbers_length; $i++) {
$code .= 'for ($n' . $i . ' = 0; $n' . $i . ' < ' . $numbers_length . '; $n' . $i . '++) {';
if ($i != 0) {
$code .= 'if ($n' . $i . ' != $n' . ($i - 1) . ') {';
}
$code .= '$total += intval($numbers[$n' . $i . ']);';
$code .= 'if ($total == $sum) {';
$code .= 'return true;';
$code .= '}';
}
//Add ending bracket for for() loops above.
for ($l = 0; $l < $numbers_length; $l++) {
$code .= '$total -= intval($numbers[$n' . $i . ']);';
if ($l != 0) {
$code .= '}';
}
$code .= '}';
}
//Finally, eval the code.
eval($code);
//If "true" not returned above, return false.
return false;
}
$num_arr = array(1,2,3,4,5,6,7,8,9);
var_dump(is_summable($num_arr, 24));
http://pastebin.com/1nawuwXK
As always, help is appreciated!!
Your problem is in fact a standard algorithmic problem (as Jon mentioned knapsack problem), more specifically Subset sum problem. It can be solved in polynomial time (have look on wiki page).
Pseudocode:
initialize a list S to contain one element 0.
for each i from 1 to N do
let T be a list consisting of xi + y, for all y in S
let U be the union of T and S
sort U
make S empty
let y be the smallest element of U
add y to S
for each element z of U in increasing order do
//trim the list by eliminating numbers close to one another
//and throw out elements greater than s
if y + cs/N < z ≤ s, set y = z and add z to S
if S contains a number between (1 − c)s and s, output yes, otherwise no