I'm making a form text input box for an inventory list. I type everything into the form and it breaks everything down to be put into SQL(not at the SQL part yet).
Input would look something like this
5-1 1/2 black 90° sch 40 (have 10 of the sch 80 ones)
amount - size - fitting name ( comments)
I got everything in their own variable now I just need to remove the "(comments)" part from the fitting name. str_replace should do the trick but it seems to only work "some times" ? I'm not sure why it doesn't always work. The picture below show that it only worked 2 times. As for my regex, I'm really bad at them. lol Thanks for any help you can give with my little problem.
foreach ($components as $value) {
$value=stripslashes($value);
// get rid of empty lines
if (empty($value)) { continue; }
// will Split the amount of fittings from the value.
$quantity = explode("-", $value);
//Will split the name of the fitting and also give the size of the fittings.
$test=preg_split('/([a-w]|[A-W])/', $quantity[1],2, PREG_SPLIT_DELIM_CAPTURE);
//split the comments from the fitting name.
$comments = explode("(", $test[2]);
//removes the remaining ) from the left side
$comments =preg_replace("/\)/", "" , $comments[1]);
if(!empty($comments)) {
$fitting_name = str_replace("($comments)","", $test[1].$test[2]);
}else{
$fitting_name = $test[1].$test[2];
}
// The table format is just to make sure everything is working right before inputting into SQL
echo "
<tr>
<td>$value</td>
<td>". $quantity[0] ."</td>
<td>$test[0]</td>
<td>$fitting_name</td>
<td>$comments </td>
</tr>
<tr>
";
}
echo "</tr>
</table>";
}
Input
0-1/2 PP union
1- 1 1/2x1 1/4 copper PP fitting red
9- 1 1/2" copper PP 90°
5-2" copper PP 90° (have 10 of the sch 80 ones)
13-2" copper PP Tee (have 10 of the sch 80 ones)
10-1*1*3/4 copper PP tee
60- 3/4" PP cap and chain value
50 - 3/4" PP value (we only have 4 more)
19- 3/4" threaded cap and chain value
0-2" threaded value
0- 2 1/2" threaded value (have 10 of the sch 80 ones)
5- 3/4" black Street 90°
0 - 3/4 black union
0- 1" black union
0-1" black tee
1 - 1 1/2 black union
6-1 1/4 black cap
7-1 1/2" * 1" black bushing
3 - 1 1/2 black coupling
5-1 1/2 black 90° sch 40? (have 10 of the sch 80 ones)
4 - 3/8" rod 6'
4-3/8" rod 10'
6 - 1/2" rod 6'
0-5/8" rod 6"
0-5/8" rod 10'
0-3/4 rod 6'
2 - 1" rod 6'(have 10 of the sch 80 ones)
I would first remove the comment before doing any parsing, to cleanse the input.
You can extract it with a RegEx :
\s*\(.*?\)
\s* matches 0 or more white spaces
\( matches a parenthesis
.*? matches any characters (lazy match)
\) matches a parenthesis
Now, you can replace this by an empty string :
<?php
$input = [
"0-1/2 PP union ",
"1- 1 1/2x1 1/4 copper PP fitting red",
"9- 1 1/2\" copper PP 90°",
"5-2\" copper PP 90° (have 10 of the sch 80 ones) ",
"13-2\" copper PP Tee (have 10 of the sch 80 ones) ",
"10-1*1*3/4 copper PP tee",
"",
"",
"60- 3/4\" PP cap and chain value ",
"50 - 3/4\" PP value (we only have 4 more)",
"19- 3/4\" threaded cap and chain value ",
"0-2\" threaded value ",
"0- 2 1/2\" threaded value (have 10 of the sch 80 ones) ",
"",
"",
"5- 3/4\" black Street 90°",
"0 - 3/4 black union ",
"0- 1\" black union ",
"0-1\" black tee ",
"1 - 1 1/2 black union ",
"6-1 1/4 black cap",
"7-1 1/2\" * 1\" black bushing",
"3 - 1 1/2 black coupling ",
"5-1 1/2 black 90° sch 40? (have 10 of the sch 80 ones) ",
"",
"",
"",
"4 - 3/8\" rod 6'",
"4-3/8\" rod 10'",
"6 - 1/2\" rod 6'",
"0-5/8\" rod 6\"",
"0-5/8\" rod 10'",
"0-3/4 rod 6'",
"2 - 1\" rod 6'(have 10 of the sch 80 ones) "
];
foreach ($input as $value)
{
$newValue = preg_replace("#\s*\(.*?\)#", "", $value);
echo $newValue . PHP_EOL;
}
Output :
0-1/2 PP union
1- 1 1/2x1 1/4 copper PP fitting red
9- 1 1/2" copper PP 90°
5-2" copper PP 90°
13-2" copper PP Tee
10-1*1*3/4 copper PP tee
60- 3/4" PP cap and chain value
50 - 3/4" PP value
19- 3/4" threaded cap and chain value
0-2" threaded value
0- 2 1/2" threaded value
5- 3/4" black Street 90°
0 - 3/4 black union
0- 1" black union
0-1" black tee
1 - 1 1/2 black union
6-1 1/4 black cap
7-1 1/2" * 1" black bushing
3 - 1 1/2 black coupling
5-1 1/2 black 90° sch 40?
4 - 3/8" rod 6'
4-3/8" rod 10'
6 - 1/2" rod 6'
0-5/8" rod 6"
0-5/8" rod 10'
0-3/4 rod 6'
2 - 1" rod 6'
Try it yourself
Plese try changing the following line
$fitting_name = str_replace("($comments)","", $test[1].$test[2]);
to
$fitting_name = str_replace("(" . trim($comments).")","", $test[1].$test[2]);
and see the effect. Please let us know the result.
Related
My English is poor. I'm sorry if there is anything rude.
Thank you for taking the time to read my question.
When I use PHP function json_decode(), i get null and json_last_error() throws 4.
Thanks for helping!
my PHP code is
$str = file_get_contents("cache.txt");
$str = htmlspecialchars_decode($str);
$arr = json_decode($str, true);
print_r($arr);
echo $errorinfo = json_last_error();
the content of File named cache.txt is:
[[1,[0,"wWfxgeyEgrRf1M",["https://encrypted-tbn0.gstatic.com/images?q\u003dtbn%3AANd9GcTFekou1VcAkVW23s69_Q53CsUJD0syjACwY0jHbRYcRIcr5cyp",225,225],["https://www.hijordan.com/image/cache/catalog/Jordan-Retro-1/Jordan-Retro-1-16-1080x1080.jpg",1080,1080],null,2,"rgb(160,42,51)",null,false,{"2001":[null,null,null,21,18,3,3,null,null,null,[]],"2003":[null,"M3A7LEiRdcA0DM","https://www.aljadid.com/efabshop/air-jordan-retro-1-red-black-white-p-16.html","Nike Air Jordan Retro 1 Red Black White - Buy Air Jordan 1 Retro ...",null,false,null,null,null,false,null,null,"Al Jadid",null,null,null,null,null,null,null,null,null,false,false,false,{"26":[null,2]}],"2006":[null,[4.0,null,"Air Jordan Retro 1 red black white",null,"A stepping stone to the world of Air Jordan is the Original air jordan 1 (I) White Black Red, which was worn by Michael Jordan the majority of the ...",null,true,5,60.85,"USD"]],"2008":[null,"Nike Air Jordan Retro 1 Red Black White ..."],"183836587":["aljadid.com"]}],null,[177,158,null,null,null,177,177,null,null,-10,null,null,false,true,null,null,[]],0,null,null,"wWfxgeyEgrRf1M",1,null,null,null,null,[[1580879352798185,178652430,3708684377],null,2]],[1,[0,"sFUMQKdZQFRaGM",["https://encrypted-tbn0.gstatic.com/images?q\u003dtbn%3AANd9GcSV5L3VvYWthX-IG9QO5QfLN_6eLvA687_og435LmF6_5NmGSI4",225,225],["https://www.hijordan.com/image/cache/catalog/air-jordan-12/air-jordan-12-49-1080x1080.jpg",1080,1080],null,2,"rgb(160,58,51)",null,false,{"2001":[null,null,null,21,18,3,6,null,null,null,[]],"2003":[null,"pTPqQEjGfZF7JM","https://togaf9-cert.opengroup.org/bcabshop/air-jordan-12-retro-black-varsity-red-p-1138.html","Air Jordan 12 Retro Black Varsity Red , Price: $89.90 - Air Jordan ...",null,false,null,null,null,false,null,null,"TOGAF? 9 Certification",null,null,null,null,null,null,null,null,null,false,false,false,{"26":[null,2]}],"2006":[null,[4.0,null,"Air Jordan 12 Retro Black Varsity Red","Nike","You should not miss the chance if you have not got one like the Air Jordan 12 Retro Black Varsity Red. Fine craftsmanship with premium materials like ...",null,true,5,89.9,"USD"]],"2008":[null,"Air Jordan 12 Retro Black Varsity Red ..."],"183836587":["togaf9-cert.opengroup.org"]}],],]
I can separate data from the plain text below with Regex.
Plain text:
190.A 42-year-old male patient has been delivered to a hospital in a grave condition with dyspnea, cough with expectoration of purulent
sputum, fever up to 39,5 oC.The ?rst symptoms appeared 3 weeks ago.
Two weeks ago, a local therapist diagnosed him wi- th acute
right-sided pneumonia. Over the last 3 days, the patient’s condition
deteriorated: there was a progress of dyspnea, weakness, lack of
appetite. Chest radiography con?rms a rounded shadow in the lower lobe
of the right lung with a horizontal?uid level, the right si- nus is
not clearly visualized. What is the most likely diagnosis? A.Abscess
of the right lung B.Acute pleuropneumonia C.Right pulmonary empyema
D.Atelectasis of the right lung E.Pleural effusion 191.An 11-year-old
boy complains of general weakness, fever up to 38,2 oC, pain and
swelli- ng of the knee joints, feeling of irregular heartbeat. 3 weeks
ago, the child had quinsy. Knee joints are swollen, the overlying skin
and skin of the knee region is reddened, local temperature is
increased, movements are li- mited. Heart sounds are muf?ed,
extrasystole is present, auscultation reveals apical systolic murmur
that is not conducted to the left ingui- nal region. ESR is 38 mm/h.
CRP is 2+, anti- streptolysin O titre - 40 0. What is the most likely
diagnosis? A.Acute rheumatic fever B.Vegetative dysfunction
C.Non-rheumatic carditis D.Juvenile rheumatoid arthritis E.Reactive
arthritis 192.A 28-year-old male patient complains of sour
regurgitation, cough and heartburn that occurs every day after having
meals, when bending forward or lying down. These problems have been
observed for 4 years. Objective status and laboratory values are
normal. FEGDS revealed endoesophagitis. What is the leading factor in
the development of this disease? A.Failure of the lower esophageal
sphincter B.Hypersecretion of hydrochloric acid C.Duodeno-gastric
re?ux D.Hypergastrinemia E.Helicobacter pylori infection 193.On
admission a 35-year-old female reports acute abdominal pain, fever up
to 38,8 oC, mucopurulent discharges. The pati- ent is nulliparous, has
a history of 2 arti?cial abortions. The patient is unmarried, has
sexual Krok 2 Medicine 20 14 24 contacts. Gynecological examination
reveals no uterus changes. Appendages are enlarged, bilaterally
painful. There is profuse purulent vaginal discharge. What study is
required to con?rm the diagnosis? A.Bacteriologic and bacteriascopic
studies B.Hysteroscopy C.Curettage of uterine cavity D.Vaginoscopy
E.Laparoscopy
What did I do for this?
For the question section:
/(\d+)\.\s*([A-Z].*?)\s+([A-Z]\..*?)(?=\d+\.\s*[A-Z]|$)/s
For the options of question section:
/\s+(?=[A-Z0-9][,.:])
PHP:
$soruAlimPattern = [
'q&a' => '/(\d+)\.\s*([A-Z].*?)\s+([A-Z]\..*?)(?=\d+\.\s*[A-Z]|$)/s',
'answers' => '/\s+(?=[A-Z0-9][,.:])/'
];
$res = [];
if (preg_match_all($soruAlimPattern['q&a'], $temizSoruCikisi, $out, PREG_SET_ORDER) > 0) {
foreach ($out AS $k => $v) {
// remove the full match ($0)
$res[$k] = array_slice($v, 1, 3);
// split the answers
$res[$k][2] = preg_split($soruAlimPattern['answers'], $res[$k][2]);
}
}
$sorularJsonKodlaniyor = json_encode($res);
[...]
I can distinguish between question and question options, but is it possible to use a single Regex code instead of 2 different Regex?
I don't know how quality the PHP code is but it works.
My problem:
1. Sometimes there are unidentifiable letters in the question and these
undefined characters are indicated with a question mark. For
example: `fever up to 39,5 oC.The ?rst symptoms` or `..39,5 oC.The ?rst symptoms..`
2. Due to the numerical values in the question, the Regex code divides the question in half. For example: `... anti- streptolysin O titre - 40 0. What is the most likely diagnosis? ` In fact, the question divides the question because of the number "zero".
Expected JSON Format:
[
{
"question": "190.A 42-year-old male patient has been delivered to a hospital in a grave condition with dyspnea, cough with expectoration of purulent sputum, fever up to 39,5 oC.The ?rst symptoms appeared 3 weeks ago. Two weeks ago, a local therapist diagnosed him wi- th acute right-sided pneumonia. Over the last 3 days, the patient’s condition deteriorated: there was a progress of dyspnea, weakness, lack of appetite. Chest radiography con?rms a rounded shadow in the lower lobe of the right lung with a horizontal?uid level, the right si- nus is not clearly visualized. What is the most likely diagnosis? ",
"answers": [
"A.Abscess of the right lung ",
"B.Acute pleuropneumonia ",
"C.Right pulmonary empyema ",
"D.Atelectasis of the right lung ",
"E.Pleural effusion 1"
]
},
{
"question": "191.An 11-year-old boy complains of general weakness, fever up to 38,2 oC, pain and swelli- ng of the knee joints, feeling of irregular heartbeat. 3 weeks ago, the child had quinsy. Knee joints are swollen, the overlying skin and skin of the knee region is reddened, local temperature is increased, movements are li- mited. Heart sounds are muf?ed, extrasystole is present, auscultation reveals apical systolic murmur that is not conducted to the left ingui- nal region. ESR is 38 mm/h. CRP is 2+, anti- streptolysin O titre - 40 0. What is the most likely diagnosis? ",
"answers": [
"A.Acute rheumatic fever ",
"B.Vegetative dysfunction ",
"C.Non-rheumatic carditis ",
"D.Juvenile rheumatoid arthritis ",
"E.Reactive arthritis 1"
]
},
{
"question": "192.A 28-year-old male patient complains of sour regurgitation, cough and heartburn that occurs every day after having meals, when bending forward or lying down. These problems have been observed for 4 years. Objective status and laboratory values are normal. FEGDS revealed endoesophagitis. What is the leading factor in the development of this disease? ",
"answers": [
"A.Failure of the lower esophageal sphincter ",
"B.Hypersecretion of hydrochloric acid ",
"C.Duodeno-gastric re?ux ",
"D.Hypergastrinemia ",
"E.Helicobacter pylori infection 1"
]
},
{
"question": "193.On admission a 35-year-old female reports acute abdominal pain, fever up to 38,8 oC, mucopurulent discharges. The pati- ent is nulliparous, has a history of 2 arti?cial abortions. The patient is unmarried, has sexual Krok 2 Medicine 20 14 24 contacts. Gynecological examination reveals no uterus changes. Appendages are enlarged, bilaterally painful. There is profuse purulent vaginal discharge. What study is required to con?rm the diagnosis? ",
"answers": [
"A.Bacteriologic and bacteriascopic studies ",
"B.Hysteroscopy ",
"C.Curettage of uterine cavity ",
"D.Vaginoscopy ",
"E.Laparoscopy 1"
]
}
]
How can I overcome these problems?
What you might do is use preg_split to get all the strings with the right characters at the start like 190.A or A.
\b(?=(?:\d+|[A-Z])\.[A-Z])
\b Word boundary
(?= Positive lookahead, assert what is on the right is
(?:\d+|[A-Z]) Match either 1+ digits or a single char A-Z
\.[A-Z] Match . and a single char A-Z
) Close positive lookahead
Regex demo | Php demo
If you have all those entries in an array, you could for example use array_reduce to the get array structure that you need for the json output.
$pattern = "/\b(?=(?:\d+|[A-Z])\.[A-Z])/";
$result = preg_split($pattern, $data, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$result = array_reduce($result, function($carry, $item){
// If the string starts with a digit
if (ctype_digit(substr($item, 0, 1))) {
// Create the questions key
$carry[] = ["question" => $item];
return $carry;
}
// Get reference to the last added array in $carry
end($carry);
$last = &$carry[key($carry)];
// Create the answers key
array_key_exists("answers", $last) ? $last["answers"][] = $item : $last["answers"] = [$item];
return $carry;
}, []);
print_r(json_encode($result))
Output
[
{
"question": "190.A 42-year-old male patient has been delivered to a hospital in a grave condition with dyspnea, cough with expectoration of purulent sputum, fever up to 39,5 oC.The ?rst symptoms appeared 3 weeks ago. Two weeks ago, a local therapist diagnosed him wi- th acute right-sided pneumonia. Over the last 3 days, the patient\u2019s condition deteriorated: there was a progress of dyspnea, weakness, lack of appetite. Chest radiography con?rms a rounded shadow in the lower lobe of the right lung with a horizontal?uid level, the right si- nus is not clearly visualized. What is the most likely diagnosis? ",
"answers": [
"A.Abscess of the right lung ",
"B.Acute pleuropneumonia ",
"C.Right pulmonary empyema ",
"D.Atelectasis of the right lung ",
"E.Pleural effusion "
]
},
{
"question": "191.An 11-year-old boy complains of general weakness, fever up to 38,2 oC, pain and swelli- ng of the knee joints, feeling of irregular heartbeat. 3 weeks ago, the child had quinsy. Knee joints are swollen, the overlying skin and skin of the knee region is reddened, local temperature is increased, movements are li- mited. Heart sounds are muf?ed, extrasystole is present, auscultation reveals apical systolic murmur that is not conducted to the left ingui- nal region. ESR is 38 mm\/h. CRP is 2+, anti- streptolysin O titre - 40 0. What is the most likely diagnosis? ",
"answers": [
"A.Acute rheumatic fever ",
"B.Vegetative dysfunction ",
"C.Non-rheumatic carditis ",
"D.Juvenile rheumatoid arthritis ",
"E.Reactive arthritis "
]
},
{
"question": "192.A 28-year-old male patient complains of sour regurgitation, cough and heartburn that occurs every day after having meals, when bending forward or lying down. These problems have been observed for 4 years. Objective status and laboratory values are normal. FEGDS revealed endoesophagitis. What is the leading factor in the development of this disease? ",
"answers": [
"A.Failure of the lower esophageal sphincter ",
"B.Hypersecretion of hydrochloric acid ",
"C.Duodeno-gastric re?ux ",
"D.Hypergastrinemia ",
"E.Helicobacter pylori infection "
]
},
{
"question": "193.On admission a 35-year-old female reports acute abdominal pain, fever up to 38,8 oC, mucopurulent discharges. The pati- ent is nulliparous, has a history of 2 arti?cial abortions. The patient is unmarried, has sexual Krok 2 Medicine 20 14 24 contacts. Gynecological examination reveals no uterus changes. Appendages are enlarged, bilaterally painful. There is profuse purulent vaginal discharge. What study is required to con?rm the diagnosis? ",
"answers": [
"A.Bacteriologic and bacteriascopic studies ",
"B.Hysteroscopy ",
"C.Curettage of uterine cavity ",
"D.Vaginoscopy ",
"E.Laparoscopy"
]
}
]
I want to remove duplicates, if these duplicates got a length of more then 4 characters.
How can we achieve that? My current code also remove the duplicate - values.
CODE:
$seoproducttitle = 'HP Chromebook Chromebook 11 G5 EE - 11.6 inch - Intel® Celeron® - 4LT18EA#ABH';
$productnamestring = $seoproducttitle;
$findseo = array('/\h+inch (?:(i[357])-\w+|\h+\w+)?/', '/(\w+)#\w+/');
$replaceseo = array('" $1', '$1');
$productnamingseo = preg_replace($findseo, $replaceseo, $productnamestring);
echo implode(' ', array_unique(explode(' ', $productnamingseo)));
This outputs: HP Chromebook 11 G5 EE - 11.6" Intel® Celeron® 4LT18EA
It should output: HP Chromebook 11 G5 EE - 11.6" - Intel® Celeron® - 4LT18EA
Or: Apple MacBook Air MacBook Air - 13.3 inch - Intel Core i5-8e - MRE82N/A
Should be: Apple MacBook Air - 13.3 inch - Intel Core i5-8e - MRE82N/A
EXAMPLE: http://sandbox.onlinephpfunctions.com/code/5bcaaf47ca97d6dee359802f2d71c2d889c0d091
Update
Based on comments from OP, the required regex is
/(^| )(.{4,}) (.*)\2/
This looks for a group of 4 or more characters preceded by either a space or the start of the line and followed by a space, some number of other characters and then the group repeated again. The regex is replaced by $1$2 $3 which effectively removes the duplicate string. A couple of examples:
$seoproducttitle = 'Apple MacBook Air MacBook Air - 13.3 inch - Intel Core i5-8e - MRE82N/A';
echo preg_replace('/(^| )(.{4,}) (.*)\2/', "$1$2 $3", $seoproducttitle) . "\n";
$seoproducttitle = 'HP Chromebook 11 G5 EE Chromebook - 11.6 inch - Intel® Intel® Celeron® - 4LT18EA#ABH 4LT18EA#ABH';
echo preg_replace('/(^| )(.{4,}) (.*)\2/', "$1$2 $3", $seoproducttitle) . "\n";
Output:
Apple MacBook Air - 13.3 inch - Intel Core i5-8e - MRE82N/A Array
HP Chromebook 11 G5 EE - 11.6 inch - Intel® Celeron® - 4LT18EA#ABH
Updated demo on 3v4l.org
Original Answer
You could use this regex:
\b([^ ]{4,})( |$)(.*)\1
It looks for a group of 4 or more non-blank characters, followed by a space or end-of-string, followed by some number of other characters and then the first group repeated. The regex is replaced by $1$3 which effectively removes the duplicate string. e.g.
$seoproducttitle = 'HP Chromebook 11 G5 EE Chromebook - 11.6 inch - Intel® Intel® Celeron® - 4LT18EA#ABH 4LT18EA#ABH';
echo preg_replace('/\b([^ ]{4,})( |$)(.*)\1/', "$1$3", $seoproducttitle);
Output:
HP Chromebook11 G5 EE - 11.6 inch - Intel® Celeron® - 4LT18EA#ABH
Demo on 3v4l.org
Computers only do what we tell them, so you first need to explain the process to yourself in plain language. Then translate that to code. Then if you're having trouble doing that you've at least got a proper description of the problem to post on StackOverflow .
$words = explode(' ', $productnamingseo);
// start with an empty list of words we've seen
$output = [];
// for every word
foreach($words as $word) {
// if it's longer than 4 chars and we've already seen it
if( mb_strlen($word) >= 4 && in_array($word, $output) ) {
// debug: show omitted words
// $output[] = str_repeat('X', mb_strlen($word));
// skip it
continue;
}
// otherwise, add it to the list of words we've already seen
$output[] = $word;
}
var_dump(
$productnamingseo,
implode(' ', $output)
);
I try to make a virutal money system and dont get the "number_format"
I want it like the number "7951753" and want that output:
795 17 53
Other example:
$money = 10001;
1 0 1
How I can make that?
You may use substr
$mynumber=7951753;
echo substr($mynumber, 0, 3)." Gold ". substr($mynumber, 3, 2)." Silver " . substr($mynumber, 5, 2)." Bronze ";
above code produces output:-
795 Gold 17 Silver 53 Bronze
You may do same with 10001 to get 1 Gold 0 Silver 1 Bronze :)
Have a try!
Sorry, display fail on posting that here:
Number: 7951753
Output: 795 Gold 17 Silver 53 Bronze
Other example:
Number: 10001
Output: 1 Gold 0 Silver 1 Bronze
Here is a problem that I wld like to formulate:
The painter intends to frame his square canvases of different sizes in centimeters:
25cm x 35cm -- 20 pcs,
50 x 30 -- 30 pcs,
90 x 50 -- 40 pcs,
110 x 60 -- 25 pcs,
The painter will purchase wooden stretcher bars of 200cm and cut them accordingly.
Condition is "each frame edge should be single continuous bar. No gluing".
Unlimited wooden stretcher bars available in length 200 cm.
how many bars of (200 cm) the Painter should buy?
How to calculate the optimized number of bars, with least wastage of bars?
Is this problem related to optimization (mathematical programming) or AI?
PHP, Perl, vbscript codes welcome.
==============
For clarification purpose, here are the exact lengths to be produced from 200cm bars.
LENGTH PIECES TOTAL LENGTH
110 cm 50 pcs 5500 cm
90 cm 80 pcs 7200 cm
60 cm 50 pcs 3000 cm
50 cm 140 pcs 7000 cm
35 cm 40 pcs 1400 cm
30 cm 60 pcs 1800 cm
25 cm 40 pcs 1000 cm
===========================================
ALL TOTAL: 26900 cm
it is equal to 134.5 bars, if we were allowed to glue small remaining pieces.
It will be practical to guide the painter what lengths should be cut from each bar.
Otherwise he will not know what to do with the bars supplied.
You'll need width of stretcher bars to calculate length for angles (spending additional 2*$stretcher_width for each side of canavas)
use strict;
use warnings;
my $stretcher_length = 200;
my $stretcher_width = 0;
my $wasted_per_side = 2*$stretcher_width;
my #sc = (
{w=> 25, h=> 35, pcs=> 20},
{w=> 50, h=> 30, pcs=> 30},
{w=> 90, h=> 50, pcs=> 40},
{w=> 110, h=> 60, pcs=> 25},
);
# all possible bars needed from longest to shortest
my #all = sort { $b <=> $a } map {
(
($_->{w}+$wasted_per_side) x2, ($_->{h}+$wasted_per_side) x2
)x $_->{pcs};
}
#sc;
# lets cut from 200cm bars
my #rest;
for my $len (#all) {
my $cut_from;
# do we already have bar which can be used?
for my $len_have (#rest) {
# yes, we have
if ($len_have >= $len) { $cut_from = \$len_have; last; }
}
# no, we need another 200cm bar
if (!$cut_from) {
print "Taking new $stretcher_length cm bar\n";
push #rest, $stretcher_length;
$cut_from = \$rest[-1];
}
# cut it
print "Now you have at least one bar $$cut_from long and cut away $len\n";
$$cut_from -= $len;
# keep #rest bars sorted from shortest to longest
#rest = sort { $a <=> $b } #rest;
}
print scalar #rest;
# print "#rest\n"; # left overs
it is actually cutting stock problem
Wikipedia article
There is a C implementation
CPSOL
Solves above problem with 135 sticks.
Unfortunately, failed to find a Perl implementation