aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/libparser/node
diff options
context:
space:
mode:
Diffstat (limited to 'src/libparser/node')
-rw-r--r--src/libparser/node/groupnode.cpp153
1 files changed, 97 insertions, 56 deletions
diff --git a/src/libparser/node/groupnode.cpp b/src/libparser/node/groupnode.cpp
index 8dab236..e6ad550 100644
--- a/src/libparser/node/groupnode.cpp
+++ b/src/libparser/node/groupnode.cpp
@@ -238,77 +238,118 @@ bool GroupNode::composeWithPrevious(DieGroup previous, qint64 first, qint64 curr
return found;
}
+DieGroup GroupNode::findPerfect(DieGroup values, int count, int currentValue) const
+{
+ for(auto it= values.rbegin(); it != values.rend(); ++it)
+ {
+ DieGroup g;
+ for(int i= 0; i < count && (it + i) != values.rend(); ++i)
+ g << *(it + i);
+
+ if(currentValue + g.getSum() == m_groupValue)
+ return g;
+ }
+ return {};
+}
+
+DieGroup GroupNode::findCombo(DieGroup values, int count, int currentValue) const
+{
+ for(auto it= values.rbegin(); it != values.rend(); ++it)
+ {
+ DieGroup g;
+ for(int i= 0; i < count && (it + i) != values.rend(); ++i)
+ g << *(it + i);
+
+ if(currentValue + g.getSum() > m_groupValue)
+ return g;
+ }
+ return {};
+}
+
QList<DieGroup> GroupNode::getGroup(DieGroup values)
{
if(values.isEmpty())
return {};
- auto first= values.takeFirst();
-
- QList<DieGroup> result;
+ bool bigger= true;
QMap<qint64, DieGroup> loseMap;
- if(first >= m_groupValue)
+ QList<DieGroup> result;
+ do
{
+ auto it= std::begin(values);
+ bigger= (*it >= m_groupValue);
+ if(!bigger)
+ continue;
+
DieGroup group;
- group << first;
- loseMap[0]= group;
- }
- else
+ group << *it;
+ result << group;
+ values.remove(0);
+
+ } while(bigger && !values.isEmpty());
+
+ auto remaining= values;
+ while(remaining.getSum() >= m_groupValue)
{
- auto it= values.rbegin();
- bool foundPerfect= false;
- qint64 cumuledValue= 0;
- DieGroup previousValue;
- while((values.rend() != it) && !foundPerfect)
+ if(remaining.isEmpty())
+ break;
+
+ QList<qint64> useless;
+ bool perfect= false;
+ // find perfect
+ do
{
- if(first + *it == m_groupValue)
- {
- foundPerfect= true;
- DieGroup group;
- group << first << *it;
- loseMap[0]= group;
- }
- else if(first + *it > m_groupValue)
- {
- DieGroup group;
- group << first << *it;
- loseMap[first + *it - m_groupValue]= group;
- }
- else if(first + *it + cumuledValue == m_groupValue)
+ auto base= remaining[0];
+ remaining.removeFirst();
+ perfect= false;
+ for(int i= 1; i <= remaining.size() && !perfect; ++i)
{
- DieGroup group;
- group << first << *it << previousValue;
- foundPerfect= true;
- loseMap[0]= group;
+ auto foundValues= findPerfect(remaining, i, base);
+ perfect= !foundValues.isEmpty();
+ if(perfect)
+ {
+ remaining.removeValue(foundValues);
+ foundValues.prepend(base);
+ foundValues.sort();
+ result.append(foundValues);
+ }
}
- else if(first + *it + cumuledValue > m_groupValue)
- {
- DieGroup group;
- group.setExceptedValue(m_groupValue);
- auto b= composeWithPrevious(previousValue, first, *it, group);
- if(b)
- loseMap[group.getLost()]= group;
- }
- previousValue << *it;
- cumuledValue+= *it;
- ++it;
- }
- }
- if(!loseMap.isEmpty())
- {
- DieGroup die= loseMap.first();
- result.append(die);
- DieGroup valueToRemove= die;
- if(!valueToRemove.isEmpty())
- {
- valueToRemove.removeFirst();
- values.removeValue(valueToRemove);
- if(values.getSum() >= m_groupValue)
+ if(!perfect)
+ useless.append(base);
+
+ } while(!remaining.isEmpty());
+
+ remaining << useless;
+
+ // find group with lost
+ bool found= false;
+ if(remaining.isEmpty())
+ break;
+ do
+ {
+ auto base= remaining[0];
+ remaining.removeFirst();
+ found= false;
+ for(int i= 1; i <= remaining.size() && !found; ++i)
{
- result.append(getGroup(values));
+
+ auto foundValues= findCombo(remaining, i, base);
+
+ found= !foundValues.isEmpty();
+ if(found)
+ {
+ remaining.removeValue(foundValues);
+ foundValues.append(base);
+ foundValues.sort();
+ foundValues.setExceptedValue(m_groupValue);
+
+ loseMap[foundValues.getLost()]= foundValues;
+ result.append(foundValues);
+ }
}
- }
+ } while(found && !remaining.isEmpty());
}
+
return result;
}