|
Hi every one.
I want to create all rhythmic figures in music. I have an array for durations:
public static double[] duration_fltarray = new double[7];
duration_fltarray[0] = 1;
duration_fltarray[1] = 0.5;
duration_fltarray[2] = 0.25;
duration_fltarray[3] = 0.125;
duration_fltarray[4] = 0.625;
duration_fltarray[5] = 0.3125;
duration_fltarray[6] = 0.15625;
This array shows music times: 1 - 1/2 - 1/4 - 1/8 and so on.
I think it should be written by recursive function, because I couldn't do it by while and for loop.
Now, I need all sorted figures that sum of them are equal 1. For example:
1
1/2 - 1/2
1/2 - 1/4 - 1/4
1/4 - 1/2 - 1/4
1/4 - 1/4 - 1/2
1/4 - 1/4 - 1/4 - 1/4
1/8 - 1/2 - 1/4 - 1/8
1/8 - 1/2 - 1/8 - 1/4
1/8 - 1/2 - 1/8 - 1/8 - 1/8
...
Of course, number of figures will be too many more if we add 1/16 and 1/32 and ... .
I can print them in a web page(response.write) or in a c console; it's not important. But the algorithm should be as simple as possible.
Thank you all.
|
|
|
|
|
Where are you stuck?
There are only 10 types of people in the world, those who understand binary and those who don't.
|
|
|
|
|
I think write my code truly, but it doesn't works.
|
|
|
|
|
OK. But how can anyone help you?
There are only 10 types of people in the world, those who understand binary and those who don't.
|
|
|
|
|
Sounds like homework. And I think your implementation so far is going to cause trouble -- particularly due to the use of floating-point values (integers will suffice). And I definitely wouldn't use recursion.
I'd also like to pass along a hint. Rather than starting from 1/1 and splitting, consider starting from 1/16 - 1/16 ... and work up to 16/16 (or 32/32 , whatever).
I have finished an implementation that uses an enumeration to define the values and returns an IEnumerable of Lists of the values; it's pretty slick and not much code. What do you have so far?
Edit: Due to poor performance when considering 1/32 and 1/64, I may look into a stack-based approach rather than the brute-force iterative approach.
Comparisons between the iterative and stack implementations:
// 1/4
6 rhythms found in 00:00:00.0000072
6 rhythms found in 00:00:00.0000057
// 1/4, with dots
8 rhythms found in 00:00:00.0000121
8 rhythms found in 00:00:00.0000064
// 1/8
56 rhythms found in 00:00:00.0015299
56 rhythms found in 00:00:00.0008122
// 1/8, with dots
114 rhythms found in 00:00:00.0015542
114 rhythms found in 00:00:00.0008210
// 1/16
5272 rhythms found in 00:00:00.0055043
5272 rhythms found in 00:00:00.0024528
// 1/16, with dots
24098 rhythms found in 00:00:00.0125192
24098 rhythms found in 00:00:00.0074718
So it looks like the stack-based algorithm generally takes about half the time as the iterative version.
I still haven't performed a full run on 1/32 or 1/64.
modified 30-Sep-14 13:36pm.
|
|
|
|
|
PIEBALDconsult wrote: I have finished an implementation that uses an enumeration to define the values and returns an IEnumerable of Lists of the values; it's pretty slick And wilt Thou share Thy shining-glory-code with mere mortals, here, below, on the darkling plain ?
« I had therefore to remove knowledge, in order to make room for belief » Immanuel Kant
|
|
|
|
|
Please stand by for a Friday Programming Challenge...
|
|
|
|
|
Thank you for your answer.
1- How do I able to use 1/4(0.25) with integer?
2- I got what you said; good idea.
Of course, usually people start music with simple duration such as 1.
Could you please guide me more? I tried too much.
|
|
|
|
|
1) What I did was pick the smallest fraction I wanted to use ( 1/4, 1/8, 1/16, etc.) and then keep track of how many I had. The denominator doesn't change; so you only need to keep track of the numerator. The resulting fraction can be reduced later if desired -- that's only a matter of display.
I also found that using 1/32 and 1/64 took a very long time with my technique.
Here are some of my enumerations and results:
public enum Duration4
{
[System.ComponentModel.DescriptionAttribute("1/4")]
Quarter = 1,
[System.ComponentModel.DescriptionAttribute("2/4")]
Half = 2,
[System.ComponentModel.DescriptionAttribute("4/4")]
Whole = 4
}
{ 4/4 }
{ 2/4 , 2/4 }
{ 2/4 , 1/4 , 1/4 }
{ 1/4 , 2/4 , 1/4 }
{ 1/4 , 1/4 , 2/4 }
{ 1/4 , 1/4 , 1/4 , 1/4 }
6 rhythms found in 00:00:00.0057366
public enum Duration4d
{
Quarter = 1
, Half = 2
, DottedHalf = 3
, Whole = 4
}
{ Whole }
{ DottedHalf , Quarter }
{ Half , Half }
{ Half , Quarter , Quarter }
{ Quarter , DottedHalf }
{ Quarter , Half , Quarter }
{ Quarter , Quarter , Half }
{ Quarter , Quarter , Quarter , Quarter }
8 rhythms found in 00:00:00.0034388
public enum Duration8
{
[System.ComponentModel.DescriptionAttribute("1/8")]
Eighth = 1 ,
[System.ComponentModel.DescriptionAttribute("1/4")]
Quarter = 2,
[System.ComponentModel.DescriptionAttribute("1/2")]
Half = 4 ,
[System.ComponentModel.DescriptionAttribute("1")]
Whole = 8
}
{ 1 }
{ 1/2 , 1/2 }
{ 1/2 , 1/4 , 1/4 }
{ 1/2 , 1/4 , 1/8 , 1/8 }
{ 1/2 , 1/8 , 1/4 , 1/8 }
{ 1/2 , 1/8 , 1/8 , 1/4 }
{ 1/2 , 1/8 , 1/8 , 1/8 , 1/8 }
{ 1/4 , 1/2 , 1/4 }
{ 1/4 , 1/2 , 1/8 , 1/8 }
{ 1/4 , 1/4 , 1/2 }
...
{ 1/8 , 1/8 , 1/8 , 1/4 , 1/4 , 1/8 }
{ 1/8 , 1/8 , 1/8 , 1/4 , 1/8 , 1/4 }
{ 1/8 , 1/8 , 1/8 , 1/4 , 1/8 , 1/8 , 1/8 }
{ 1/8 , 1/8 , 1/8 , 1/8 , 1/2 }
{ 1/8 , 1/8 , 1/8 , 1/8 , 1/4 , 1/4 }
{ 1/8 , 1/8 , 1/8 , 1/8 , 1/4 , 1/8 , 1/8 }
{ 1/8 , 1/8 , 1/8 , 1/8 , 1/8 , 1/4 , 1/8 }
{ 1/8 , 1/8 , 1/8 , 1/8 , 1/8 , 1/8 , 1/4 }
{ 1/8 , 1/8 , 1/8 , 1/8 , 1/8 , 1/8 , 1/8 , 1/8 }
56 rhythms found in 00:00:00.0045673
|
|
|
|
|
What musical illiterate set this? Where is the support for dot notation?
|
|
|
|
|
That would be one of my questions as well.
|
|
|
|
|
And usually 1/16 is not the sum of 1/2 and 1/8...
|
|
|
|
|
Indeed, and it's completely ignoring the fact that a musical piece may not be in common time. This approach wouldn't work with a waltz, for instance.
|
|
|
|
|
It assumes a 1/1 time. All other times derive from that.
|
|
|
|
|
Yes. You are right. I just want to get right way and extent later.
|
|
|
|
|
I don't think he claimed such.
Or do you mean the apparently errant values in
duration_fltarray[4] = 0.625;
duration_fltarray[5] = 0.3125;
duration_fltarray[6] = 0.15625;
|
|
|
|
|
How's it going? Made any progress? I now have two different algorithms that seem to do what you describe; neither is recursive.
|
|
|
|
|
I think this is related to Egyptian Fractions[^].
I would start with 1/64 - 1/64 - ... - 1/64 - 1/64 (64 times) and loop thru grouping two adjoing equal numbers, to the one above it (i.e., double). To avoid repeats, store what you have in an array and rotate each sequence n - 1 times adding only the unique sequences, and do the same for the reverse sequences adding them to your array.
Vertically shown:
1/4 | Same 3 below |
1/4 | 1/4 | 1/4 | 1/2 | |
1/4 | 1/4 | 1/2 | 1/4 | 1/2 |
1/4 | 1/2 | 1/4 | 1/4 | 1/2 | 1
Out of all permutations with 4, you only have 4 generating sequences and the rest are generated through rotating and reversing.
modified 4-Oct-14 11:29am.
|
|
|
|
|
Another thing to look into is Euler's Integer Partition.
For 1, there's 1 sequence.
For 1/2, there's 2 sequences.
For 1/4, there's 6 sequences.
For 1/8, there's 56 sequences.
Maybe there's a rule[^] out there.
8C8 = 1
1/8
1/8
1/8
1/8
1/8
1/8
1/8
1/8
7C6,1 = 7
1/4 1/8 1/8 1/8 1/8 1/8 1/8
1/8 1/4 1/8 1/8 1/8 1/8 1/8
1/8 1/8 1/4 1/8 1/8 1/8 1/8
1/8 1/8 1/8 1/4 1/8 1/8 1/8
1/8 1/8 1/8 1/8 1/4 1/8 1/8
1/8 1/8 1/8 1/8 1/8 1/4 1/8
1/8 1/8 1/8 1/8 1/8 1/8 1/4
6C4,2 = 15
1/4 1/8 1/8 1/8 1/8 1/4 1/4 1/4 1/4 1/8 1/8 1/8 1/8 1/8 1/8
1/4 1/4 1/8 1/8 1/8 1/8 1/8 1/8 1/8 1/4 1/4 1/4 1/8 1/8 1/8
1/8 1/4 1/4 1/8 1/8 1/4 1/8 1/8 1/8 1/8 1/8 1/8 1/4 1/4 1/8
1/8 1/8 1/4 1/4 1/8 1/8 1/4 1/8 1/8 1/4 1/8 1/8 1/8 1/8 1/4
1/8 1/8 1/8 1/4 1/4 1/8 1/8 1/4 1/8 1/8 1/4 1/8 1/4 1/8 1/8
1/8 1/8 1/8 1/8 1/4 1/8 1/8 1/8 1/4 1/8 1/8 1/4 1/8 1/4 1/4
5C3,2 = 10
1/4
1/4
1/4
1/8
1/8
4C4 = 1
1/4
1/4
1/4
1/4
5C4,1 = 5
1/2
1/8
1/8
1/8
1/8
4C2,1,1 = 12
1/2
1/4
1/8
1/8
3C2,1 = 3
1/2
1/4
1/4
2C2 = 1
1/2
1/2
1C1 = 1
1
modified 4-Oct-14 11:37am.
|
|
|
|
|
General solution for generating unique sequences (in increasing order or decreasing denominators) (e.g., {(1/4, 1/4, 1/2)}):
Let S1 = {(1)} and S2 = {(1/2, 1/2)} ∪ S0.
Then S2n = The set of every element in S2n-1 beginning with 1/2n-1 and ending with 1/2k concatenated with every set element in S2n-1 greater than or equal to 1/2k and every element fraction gets halved ∪ S2n-1.
If we omit the first underlined condition, we wouldn't be able to use the union of the previous set as a shortcut. If we omit the second underlined condition, we won't get the uniqueness and we won't get every permutation either.
So S4 = [ {(1/2, 1/2), (1/2, 1/2)} & {(1/2, 1/2), (1)} ] / 2 ∪ S2 = {(1/4, 1/4, 1/4, 1/4), (1/4, 1/4, 1/2)} ∪ S2.
This will not generate (1/4, 1/2, 1/4) or (1/2, 1/4, 1/4), etc.
And, thus, S8 = {(1/4, 1/4, 1/4, 1/4) concatenated with each set in S4 then halved, and (1/4, 1/4, 1/2) concatenated with each of the two sets in {(1/2, 1/2), (1)} and halved, and all of S4 once more}.
To get the count of them, you'd need to count all the permutations.
16C16 16 16's
15C14,1 14 16's 1 8's
14C12,2 12 16's 2 8's
13C12,1 12 16's 1 4's
13C10,3 10 16's 3 8's
12C10,1,1 10 16's 1 8's 1 4's
12C8,4 8 16's 4 8's
11C8,2,1 8 16's 2 8's 1 4's
10C8,2 8 16's 2 4's
9C8,1 8 16's 1 2's
11C6,5 6 16's 5 8's
10C6,3,1 6 16's 3 8's 1 4's
9C6,1,2 6 16's 1 8's 2 4's
8C6,1,1 6 16's 1 8's 1 2's
10C4,6 4 16's 6 8's
9C4,4,1 4 16's 4 8's 1 4's
8C4,2,2 4 16's 2 8's 2 4's
7C4,2,1 4 16's 2 8's 1 2's
7C4,3 4 16's 3 4's
6C4,1,1 4 16's 1 4's 1 2's
9C2,7 2 16's 7 8's
8C2,5,1 2 16's 5 8's 1 4's
7C2,3,2 2 16's 3 8's 2 4's
6C2,3,1 2 16's 3 8's 1 2's
6C2,1,3 2 16's 1 8's 3 4's
5C2,1,1,1 2 16's 1 8's 1 4's 1 2's
8C8 8 8's
7C6,1 6 8's 1 4's
6C4,2 4 8's 2 4's
5C4,1 4 8's 1 2's
5C2,3 2 8's 3 4's
4C2,1,1 2 8's 1 4's 1 2's
4C4 4 4's
3C2,1 2 4's 1 2's
2C2 2 2's
1C1 1 1's
Count(S1) =1
Count(S2) =2
Count(S4) =6
Count(S8) =56
Count(S16)=5272
Generating the count for 32 and 64 is not all that difficult manually or programmatically. Would rather do it manually myself. Generating every permutation is still an interesting exercise.
modified 26-Oct-14 14:33pm.
|
|
|
|
|
Hi,
I found lots of post with same question but none of them match with what I want to do.
I have a usercontrol with nothing special in it. I want to be able to add only button in it.
How do I prevent my usercontrol adding other stuff then Button ?
I have override the OnControlAdded event but this event is activate after the control is added. I want to prevent which mean block before it is added to the controls collection.
Is it possible ?
Regards,
|
|
|
|
|
You need to be more specific about what it is you are trying to "block:"
1. are you speaking of a design-time scenario where other developers add instances of your UserControl to a Form, and then add other Controls to it ?
2. or, are you speaking of the UserControl at run-time, when some action by the user triggers the creation of a new Control and the adding of that Control to the instance of the UserControl ?
Exactly what is it you have no control over now in terms of other Controls being added to your UserControl ?
« I had therefore to remove knowledge, in order to make room for belief » Immanuel Kant
|
|
|
|
|
Hi BillWoodruff,
Let's say I want to do this in a design-time scenario.
I add my usercontrol to the form and I want to prevent other programmer to add control in it.
[Designer(typeof(MyControlDesigner))]
public partial class GroupInput : UserControl
{
private Color _BorderColor = Color.Black;
[Category("Appearance")]
[Description("Set the border color")]
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Color BorderColor
{
get { return _BorderColor; }
set {
_BorderColor = value;this.Refresh();
}
}
public GroupInput()
{
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
ControlPaint.DrawBorder(e.Graphics, this.ClientRectangle, this._BorderColor, ButtonBorderStyle.Solid);
}
}
internal class MyControlDesigner : ParentControlDesigner
{
private const int glyphSize = 6;
private const int hitBoundSize = glyphSize + 4;
private GroupInput _groupInput = null;
public override void Initialize(IComponent component)
{
base.Initialize(component);
_groupInput = (GroupInput)component;
}
public override void InitializeNewComponent(IDictionary defaultValues)
{
base.InitializeNewComponent(defaultValues);
PropertyDescriptor colorPropDesc =
TypeDescriptor.GetProperties(Component)["BorderColor"];
if (colorPropDesc != null &&
colorPropDesc.PropertyType == typeof(Color) &&
!colorPropDesc.IsReadOnly &&
colorPropDesc.IsBrowsable)
{
colorPropDesc.SetValue(Component, Color.LightBlue);
}
}
protected override void OnPaintAdornments(System.Windows.Forms.PaintEventArgs pe)
{
_groupInput = (GroupInput)Component;
base.OnPaintAdornments(pe);
ControlPaint.DrawBorder(pe.Graphics, _groupInput.ClientRectangle, _groupInput.BorderColor, ButtonBorderStyle.Solid);
}
}
|
|
|
|
|
Let me do a little reality check and make sure we are talking about the same thing
1. you created your UserControl by creating a new WindowsFormsControlLibrary Project whose compiled output is a Class Library (dll)
2. the way you expect users of your UserControl to use it at design-time in their projects is by setting a reference to it in the Project/References, then installing it in the ToolBox in the usual way, and then drag-dropping it on to a Form from the ToolBox.
3. all this is working fine now ... you've tested this.
4. you understand that any Control drag-dropped from the ToolBox, and dropped inside the bounds of an instance of your UserControl on some other user's Form, will never be added to your UserControl's Control Collection. In fact there is a way to modify your UserControl to allow other Controls to be added by drag-drop at design-time, but I assume that's not of interest to you right now.
If all this is correct, then the only way a user could add new Controls to the instance of your UserControl, would be in code, and in your code you can add an EventHandler for 'ControlAdded:
private void UserControl1_ControlAdded(object sender, ControlEventArgs e)
{
Control controlAdded = e.Control;
if (e.Control.GetType() != typeof (Button))
{
this.Controls.Remove(controlAdded);
MessageBox.Show("bad add: UC Controls count = " + this.Controls.Count.ToString());
}
} To reverse the addition of any Control whose Type is not 'Button.
I don't like this technique ... it's a smelly hack ... but, it does work; I'd like to see a better way to do this where any Control could be prevented from being added to the UserControl.
My hope is that the questions asked here, and the brief code example, will, at least, lead to your clarifying exactly what you want to achieve ... since I'm still not sure I understand that fully
« I had therefore to remove knowledge, in order to make room for belief » Immanuel Kant
|
|
|
|
|
Thank you,
Like you said, it's a smelly hack but it does work.
Regards,
Philippe
|
|
|
|
|