I tried this sudoku solver http://www.emanueleferonato.com/2008/12/09/sudoku-creatorsolver-with-php/. It works fine.
Also see this spreadsheet to see more detail in calculation : spreadsheet
I understand how the row and col scanning. From the board, we know that:
index = 9*row + col
row = floor(index/9)
col = index % 9
And for the block, because it build from 3x3 board so the formula: block_index = 3*row_block + col_row. Because per block there are 3 rows and cols, so the formula for row_block = floor(row/3) and col_block = floor(col/3). From here we can conclude that:
block_index = 3*row_block + col_row
block_index = 3(floor(row/3)) + floor(col/3)
block_index = floor(row/3)*3 + floor(col/3)
This could explain for these function :
return_row
retun_col
return_block
is_possible_row
is_possible_col
But I cannot understand about is_possible_block function. Here is the function:
function is_possible_block($number,$block,$sudoku){
$possible = true;
for($x = 0;$x <= 8;$x++){
if($sudoku[floor($block / 3) * 27 + $x % 3 + 9 * floor($x / 3) + 3 * ($block % 3)] == $number){
$possible = false;
}
}
return $possible;
}
What I know about is_possible_block function is:
floor($block / 3) * 27 + $x % 3 + 9 * floor($x / 3) + 3 * ($block % 3)
= 9row+col
= 9(floor($block/3)*3 + floor($x/3)) + ($x%3 + 3*($block%3))
row = 3row_block+row_x_block
floor($block/3) = row_block
floor($x/3) = row_x_block
col = 3col_block+col_x_block
How col = 3col_block+col_x_block , because what I know, the formula should be like this : col = 3row_block+col.
I know col_x_block mean column position on 0-8 block. And row_block mean row position on 0-2 block.
How do you explain this formula? Thanks
UPDATE
Now I know. floor($block/3)*3 and 3*($block%3) determine top left corner in block. Then floor($x / 3) and $x % 3 moves each cell in the block.
I use it in c++
for(int k = ((x - 1) / 3) * 3 + 1; k < ((x - 1) / 3) * 3 + 4; k++
because of "x" is integer "/" operation return int value.
maybe 3(floor($block-1/3)) can help you.
Related
I want to know how to get variables and it's values from a variable?
Here is the sample code;
$x = 10;
$y = 20;
$z = 30;
$sum = $x * 5; // It has only one variable
echo $sum; // Page # 1
$sum = ($x * 5) + ($y * 5); // It has two variables
echo $sum; // Page # 2
$sum = ($x * 5) + ($y * 5) + ($z * 5); // It has three variables
echo $sum; // Page # 3
Now I want to get the variables inside of the variable $sum and their values to output a breakup of the calculation.
Something like this;
----- Page # 1 -----
X: 10 * 5 = 50
----- Page # 2 -----
X: 10 * 5 = 50
Y: 20 * 5 = 100
Sum: X + Y = 150
----- Page # 3 -----
X: 10 * 5 = 50
Y: 20 * 5 = 100
Z: 30 * 5 = 150
Sum: X + Y + Z = 300
Is there any PHP function or any other solution to achieve this without making any changes to the variable $sum?
I know I can do it in other ways, but the problem is; I can't change the code $sum as it's required to change it on thousands of pages. It would be highly appreciated if anyone could help me with this.
Thanks in advance :-)
There's no way to use $sum to retrieve the calculations or input values which were used to give it its current value. PHP does not work like that. As far as I am aware, no programming language currently provides that.
A variable simply contains its current value...it does not contain any other variables or calculations, or keep a history of how it got like that.
The only way to get the output you've specified is to directly echo the data explicitly from the original data, for example:
$x = 10;
$y = 20;
$z = 30;
// Page # 1
$sum = $x * 5;
echo "X: ".$x."* 5 = ".$sum;
// Page # 2
$sum = ($x * 5) + ($y * 5);
echo "X: ".$x."* 5 = ".($x * 5);
echo "Y: ".$y."* 5 = ".($y * 5);
echo "Sum: X + Y = ".$sum;
// Page # 3
$sum = ($x * 5) + ($y * 5) + ($z * 5);
echo "X: ".$x."* 5 = ".($x * 5);
echo "Y: ".$y."* 5 = ".($y * 5);
echo "Z: ".$z."* 5 = ".($z * 5);
echo "Sum: X + Y + Z = ".$sum;
Using VBA code I found in a spreadsheet to adapt to an online PHP application. The code uses the bisection method in mathematics to find optimal value for a calculation required to price options.
Upper = estimate_upper
Lower = estimate_lower
UUpper = container
Start_Iteration:
IterationCountE = 0.000000001
While (Upper - Lower) > IterationCountE
Mid = (Upper + Lower) / 2
c1 = calculations1...
c2 = calculations2...
If (c2 - c1) > 0 Then
Lower = Mid
Else
Upper = MId
End If
Wend 'Ends the while loop
If (Round(Mid, 4) = Round(UUpper, 4)) Then
Upper = 2 * UUpper
UUpper = Upper
GoTo Start_Iteration
End If
Function = Mid
For most part, I understand the mechanics of the iteration. My attempted PHP conversion is as follows:
$IterationCountE = 0.00000000001;
while ( ($Upper - $Lower) > $IterationCountE ) {
$Mid = ($Upper + $Lower) / 2;
$c1 = calculation1();
$c2 = calculation2();
if ( ($c2 - $c1) > 0 ) {
$Lower = $Mid;
} else {
$Upper = $Mid;
}
if (round($Mid, 4) == round($UUpper, 4)) {
$Upper = 2 * $UUpper;
$UUpper = $Upper;
}
}
return $Mid;
Is this the best way to approach an similar iteration in PHP? Would it be better to wrap the iteration in a function and refer back to it like in the VBA code?
I do not get the same value results when comparing the PHP output to the value from a macro.
I am using the following PHP code to calculate a CRN for BPay:
<?php
function LuhnCalc($number) {
$chars = array_reverse(str_split($number, 1));
$odd = array_intersect_key($chars, array_fill_keys(range(1, count($chars), 2), null));
$even = array_intersect_key($chars, array_fill_keys(range(0, count($chars), 2), null));
$even = array_map(function($n) { return ($n >= 5)?2 * $n - 9:2 * $n; }, $even);
$total = array_sum($odd) + array_sum($even);
return ((floor($total / 10) + 1) * 10 - $total) % 10;
}
print LuhnCalc($_GET['num']);
?>
However it seems that BPAY is version 5 of MOD 10, for which I can't find any documentation. It seems to not be the same as MOD10.
The following numbers where tested:
2005,1597,3651,0584,9675
bPAY
2005 = 20052
1597 = 15976
3651 = 36514
0584 = 05840
9675 = 96752
MY CODE
2005 = 20057
1597 = 15974
3651 = 36517
0584 = 05843
9675 = 96752
As you can see, none of them match the BPAY numbers.
This PHP function will generate BPay reference numbers based on the mod10 version 5 algorithm.
Who knows why BPay can't add this to their website. I only found an explanation by googling finding the algorithm being called "MOD10V05" instead of "Mod 10 version 5".
function generateBpayRef($number) {
$number = preg_replace("/\D/", "", $number);
// The seed number needs to be numeric
if(!is_numeric($number)) return false;
// Must be a positive number
if($number <= 0) return false;
// Get the length of the seed number
$length = strlen($number);
$total = 0;
// For each character in seed number, sum the character multiplied by its one based array position (instead of normal PHP zero based numbering)
for($i = 0; $i < $length; $i++) $total += $number{$i} * ($i + 1);
// The check digit is the result of the sum total from above mod 10
$checkdigit = fmod($total, 10);
// Return the original seed plus the check digit
return $number . $checkdigit;
}
Here's a way of implementing the "MOD10V5" algorithm (or "mod 10 version 5") using a t-sql user defined function in SQL server. It accepts a Customer ID up to 9 characters long, and return an 11 character CRN (Customer Reference Number).
I also prepended a version number onto the start of my CustomerID, you could do this too if you think you might end up changing it in the future.
CREATE Function [dbo].[CalculateBPayCRN]
(
#CustomerID nvarchar(9)
)
RETURNS varchar(11)
AS
BEGIN
DECLARE #NewCRN nvarchar(11)
DECLARE #Multiplier TINYINT
DECLARE #Sum int
DECLARE #SubTotal int
DECLARE #CheckDigit int
DECLARE #ReturnVal BIGINT
SELECT #Multiplier = 1
SELECT #SubTotal = 0
-- If it's less than 9 characters, pad it with 0's, then prepend a '1'
SELECT #NewCRN = '1' + right('000000000'+ rtrim(#CustomerID), 9)
-- loop through each digit in the #NewCRN, multiple it by the correct weighting and subtotal it:
WHILE #Multiplier <= LEN(#NewCRN)
BEGIN
SET #Sum = CAST(SUBSTRING(#NewCRN,#Multiplier,1) AS TINYINT) * #Multiplier
SET #SubTotal = #SubTotal + #Sum
SET #Multiplier = #Multiplier + 1
END
-- mod 10 the subtotal and the result is our check digit
SET #CheckDigit = #SubTotal % 10
SELECT #ReturnVal = #NewCRN + cast(#CheckDigit as varchar)
RETURN #ReturnVal
END
GO
Modula 10 V1 in PHP. Tested against my Windows dataflex routine and it is the same.
function generateBpayRef($number) {
//Mod 10 v1
$number = preg_replace("/\D/", "", $number);
// The seed number needs to be numeric
if(!is_numeric($number)) return false;
// Must be a positive number
if($number <= 0) return false;
$stringMemberNo = "$number";
$stringMemberNo = str_pad($stringMemberNo, 6, "0", STR_PAD_LEFT);
//echo " Padded Number is $stringMemberNo ";
$crn = $stringMemberNo;
for($i=0;$i<7;$i++){
$crnval = substr($crn,(5-$i),1);
$iPartVal = $iWeight * $crnval;
if($iPartVal>9){
//echo " Greater than 9: $iPartVal ";
$firstChar = substr($iPartVal,0,1);
$secondChar = substr($iPartVal,1,1);
$iPartVal=$firstChar+$secondChar;
//$iPartVal -= 9;
}
$iSum+=$iPartVal;
$iWeight++;
if ($iWeight>2){$iWeight=1;}
//echo " CRN: $crnval ] Weight: $iWeight ] Part: $iPartVal ] SUM: $iSum ";
}
$iSum %= 10;
if($iSum==0){
//echo " zero check is $iSum ";
//return $iSum;
}
else{
//return 10-$iSum;
$iSum=(10-$iSum);
}
//echo " Check is a $iSum ";
$BpayMemberNo = $stringMemberNo . $iSum ;
echo " New: $BpayMemberNo ";
return ($BpayMemberNo);
}
Here is a ruby class I whipped up quickly for Mod 10 v5
module Bpay
class CRN
attr_accessor :number, :crn
class << self
def calculate_for(number)
new(number).crn
end
end
def initialize(number)
#number = number
calculate
end
def calculate
raise ArgumentError, "The number '#{number}' is not valid" unless valid?
digits = number.to_s.scan(/\d/).map { |x| x.to_i }
raise ArgumentError, "The number '#{number}' must be at least 2 digits in length" if digits.size < 2
check_digit = digits.each_with_index.map { |d, i| d * (i + 1) }.inject(:+) % 10
#crn = "#{number}#{check_digit}"
end
def valid?
return false unless !!Integer(number.to_s) rescue false
return false if number.to_i <= 0
true
end
end
end
This is in C#, but this is what I have so far for BPay check digit generation:
private void btnBPayGenerate_Click(object sender, EventArgs e)
{
var originalChars = txtBPayNumber.Text.ToCharArray();
List<int> oddDigits = new List<int>();
List<int> evenDigits = new List<int>();
int oddTotal = 0, evenTotal = 0, total = 0, checkDigit ;
const int oddMultiplier = 3;
const int modulus = 10;
bool isOdd = true;
for (int x = 0; x < originalChars.Length; x++)
{
if(isOdd)
oddDigits.Add(Int32.Parse(originalChars[x].ToString()));
else
evenDigits.Add(Int32.Parse(originalChars[x].ToString()));
isOdd = !isOdd;
}
foreach (var digit in oddDigits)
oddTotal += digit;
foreach (var digit in evenDigits)
evenTotal += digit;
oddTotal = oddTotal * oddMultiplier;
total = oddTotal + evenTotal;
checkDigit = (modulus - (total % modulus));
lblBPayResult.Text = txtBPayNumber.Text + checkDigit.ToString();
}
I haven't completed testing this yet, I will post back once BPAY get back to me.
EDIT: try this: https://gist.github.com/1287893
I had to work out a version for javascript, this is what I came up with. It correctly generates the expected numbers in the original question.
var startingNumber = 2005;
var reference = startingNumber.toString();
var subTotal = 0;
for (var x = 0; x < reference.length; x++) {
subTotal += (x + 1) * reference.charAt(x);
}
var digit = subTotal % 10;
var bpayReference = reference + digit.toString();
Here is a function I created using vb.net to calculate a mod 10 version 5 check digit
Private Function CalcCheckDigit(ByRef psBaseNumber As String) As String
Dim lCheckDigit, iLoop As Integer
Dim dCalcNumber As Double
lCheckDigit = 0
dCalcNumber = 0
For iLoop = 0 To (psBaseNumber.Length - 1)
lCheckDigit = lCheckDigit + (psBaseNumber.Substring(iLoop, 1) * (iLoop + 1))
Next iLoop
lCheckDigit = lCheckDigit Mod 10
CalcCheckDigit = psBaseNumber & CStr(lCheckDigit)
End Function
I have a number X, consider X = 1000
And I want piecemeal this number at three times, then Y = 3, then X = (X / 3)
This will give me equal, just not always accurate, so I need: a percentage value is set, also consider K = 8, K is the percentage, but what I want to do? I want the first portion has a value over 8% in K, suppose that 8% are: 500 and the other two plots are 250, 250
The algorithm is basically what I need it, add a percentage value for the first installment and the other equals
EDIT
I just realized, this is far simpler than I made it. To find the value of $div in my original answer you can just:
$div = (int)($num / ($parcels + $percent / 100));
Then the $final_parcels will be the same as below. Basically, the line above replaces the while loop entirely. Don't know what I was thinking.
/EDIT
I think this will do what you want... unless I am missing something.
<?php
$num = 1000;
$percent = 8;
$parcels = 3;
$total = PHP_INT_MAX;
$div = (int)($num / $parcels);
while ($total > $num) {
$div -= 1;
$total = (int)($div * ($parcels + $percent / 100));
}
$final_parcels = array();
$final_parcels[] = ($num - (($parcels - 1) * $div));
for ($i = 1; $i < $parcels; $i++) {
$final_parcels[] = $div;
}
print_r($final_parcels);
This output will be
Array
(
[0] => 352
[1] => 324
[2] => 324
)
324 * 1.08 = 350.
352 + 324 * 2 = 1000.
Let $T is your total X, $n is a number of parts and $K is percentage mentioned above. Than
$x1 = $T / $n + $T * $K / 100;
$x2 = $x3 = .. = $xn = ($T - $x1) / ($n - 1);
Applied to your example:
$x1 = 1000 / 3 + 1000 * 0.03 = 363.3333333333333333333333333333
// you could round it if you want
// lets round it to ten, as you mentioned
$x1 = round($x1, -1) = 360
$x2 = $x3 = (1000 - 360) / 2 = 320
Extra for the first piece W = X*K/100
Remaining Z = X-W
Each non-first piece = Z/Y = (X-W)/Y = (100-K)*X/(100*Y)
The first piece = W + (100-K)*X/(100*Y) = X*K/100 + (100-K)*X/(100*Y)
I need for a projet to get a color from a value.
I explain, I have datas and each data must be represented by a color.
The red color is for the maximum, and the blue for the minimum and the green is for the middle value. A kind of heatmap.
So, I need to have a function returning the right color.
I tried something like this :
function datatocolor($min, $max, $value)
{
$half = (($min + $max) / 2);
if ($value > $half)
{
$r = (255 * ($value+$min-$half)) / $half;
$g = 255 - $r;
$b = 0;
}
else {
$b = (255 * ($half-$value+$min)) / $half;
$g = 255 - $b;
$r = 0;
}
$color = array(intval($r), intval($g), intval($b));
return $color;
}
But, I get red and blue, and never green ... I tried a lot of operations, I must be stupid but I don't find the right operation ...
Thanks in advance for your help !
I'm not a php expert, but as far as I can tell, the problem isn't with this code block. I tested your algorithm in java just to be sure, and it looks to be correct:
public static void main(String[] args) {
int min = 0;
int max = 10;
int half = (min + max) / 2;
int r, g, b;
// Cycling through the values for completeness' sake.
for (int value = 0; value <= 10; value++) {
if (value > half) {
r = (255 * (value + min - half)) / half;
g = 255 - r;
b = 0;
} else {
b = (255 * (half - value + min)) / half;
g = 255 - b;
r = 0;
}
System.out.println("Value: " + value + " - " + new Color(r, g, b));
}
The output from this is what you would expect -- pure blue at minimum, pure green at the middle, and pure red at the maximum:
Value: 0 - java.awt.Color[r=0,g=0,b=255]
Value: 1 - java.awt.Color[r=0,g=51,b=204]
Value: 2 - java.awt.Color[r=0,g=102,b=153]
Value: 3 - java.awt.Color[r=0,g=153,b=102]
Value: 4 - java.awt.Color[r=0,g=204,b=51]
Value: 5 - java.awt.Color[r=0,g=255,b=0]
Value: 6 - java.awt.Color[r=51,g=204,b=0]
Value: 7 - java.awt.Color[r=102,g=153,b=0]
Value: 8 - java.awt.Color[r=153,g=102,b=0]
Value: 9 - java.awt.Color[r=204,g=51,b=0]
Value: 10 - java.awt.Color[r=255,g=0,b=0]
Based on what you've provided, the problem seems to be either in the way you're calling the function, or in the way you're using the array it returns.