In LiliyPond, how do you alter a music expression? - dry

I have a situation where I have a recurring piece of music with only slight variations. I want to lay down a base piece as a variable. Then reuse it multiple times, each time altering it by replacing a few notes or measures. Here's a simplified example
base = { c4 c c c }
% pseudo function \replace MUSIC FROM TO ORIG
% FROM and To are pairs of numbers COUNT DURATION
from = #'(1 2)
to = #'(3 4)
var1 = \replace { d4 } \from \to \base
% this means replace
% from "after 1 half note into the music"
% to "after 3 quarter notes into the music"
% that is replace the third beat with { d4 }
% this will be equivalent to
var1 = { c4 c d c }
How do I do this?

A LilyPond solution to this is \tag. I haven't found a built-in functionality for altering a music expression on the fly. However, for the variations usecase, tags serve this purpose. The above example would be this
base = { c4 c \tag #'base c \tag #'var1 d c }
var1 = \keepWithTag #'var1 \base

Related

Find all numbers adding up to given number and range to use

This is not homework, but a real world application I'm getting stumped on.
The best way I can explain my problem is as follows:
Imagine you have 3 pig pens A, B, and C and 10 pigs to be kept.
The pens have restrictions in that each pen must contain at least 1 pig and A.pigs <= B.pigs <= C.pigs. List all the possible pen configurations.
The REAL application can have anywhere between 1 and 7 pens, and anywhere between numPens and numPens*30 pigs and no pen may contain more than 30 pigs. So essentially this translates into "what numbers between 1 and 30 (repeats allowed) add up to X using Y numbers"
This could be solved simply with nested loops, but thats a terrible inefficient solution especially knowing the scope of the real application:
var cnt = 0
val target = 10
for (a in 1..30) {
for (b in a..30) {
val c = target - a - b
cnt++
if (a <= b && b <= c && a + b + c == target) {
println("$a $b $c")
}
}
}
println(cnt)
output:
1 1 8
1 2 7
1 3 6
1 4 5
2 2 6
2 3 5
2 4 4
3 3 4
465
I'm sure there is a recursive solution to this problem. But I'm having trouble even finding the starting point for this one.
It seems easy to start with an array of [1, 1, 8] where each index represents a pen. Just put all the pigs in 1 pen and move them around 1 at a time while following the constraints.
Subtract from C, add to B as much as you can while keeping constraints gets us [1, 2, 7], [1, 3, 6], [1, 4, 5] but at that point I'm stuck code wise.
What I have currently:
fun main(vararg args: String) {
val list = arrayOf(1, 1, 8)
list.forEach { print("$it\t") }
println()
rec(list, list.lastIndex - 1)
}
fun rec(list: Array<Int>, index: Int) {
if (index == list.lastIndex || index < 0) {
return
}
while (list[index] + 1 <= list[index + 1] - 1) {
list[index]++
list[index + 1]--
list.forEach { print("$it\t") }
println()
}
}
Obviously I need to call rec somewhere within itself and probably need some conditionals to call rec correctly (possibly adding more parameters to it). The question is where and how? Normally not bad with recursion, but this one is stumping me.
Solution:
I got so hung up on the idea I needed recursion. This loop seems to work pretty well.
for (a in 1..30) {
// we know a and c must be at least b, so cap range
var b = a
while(b < min(target - a - b, 30)){
val c = target - a - b
cnt++
if (a <= b && b <= c && a + b + c == target) {
println("$a $b $c")
}
b++
}
}
Some inefficiencies to note:
Once you know a and b, the only value for c that could make a solution would be 10-a-b, so you don't need the innermost loop at all.
Since a<=b, the second loop should start at a, not 1.
You can also limit the top of the second loop's range based on the value of a

Calculate sum of 2D Arrays

I want to write a program to calculate the sum of 2 matrices(2D Arrays) based on the user input.
Two matrices must have an equal number of rows and columns to be added. The sum of two matrices A and B will be a matrix that has the same number of rows and columns as do A and B.
The first line of standard input is a number of rows n and number of columns m of matrix A. Next n lines are A matrix’s elements. The next line after the empty line is a number of rows n and a number of columns m of matrix B. Next n lines are B matrix’s elements.
I want to output the result of a sum of A and B matrices or ERROR message if it’s impossible. The input contains only integers.
Example
Input:
4 5
1 2 3 4 5
3 2 3 2 1
8 0 9 9 1
1 3 4 5 6
4 5
1 1 4 4 5
4 4 5 7 8
1 2 3 9 8
1 0 0 0 1
Output:
2 3 7 8 10
7 6 8 9 9
9 2 12 18 9
2 3 4 5 7
My Code:
package processor
import java.util.*
val scanner = Scanner(System.`in`)
fun main() {
MatrixProcessor().addition()
}
class MatrixProcessor {
private fun createMatrix(): Array<Array<Int>> {
val rows = scanner.nextInt()
val columns = scanner.nextInt()
return Array(rows) {Array(columns) { scanner.nextInt()} }
}
fun addition() {
val firstMatrix = createMatrix()
val secondMatrix = createMatrix()
val sum = Array(4) { IntArray(5) }
for (i in 0 until 4) {
for (j in 0 until 5) {
sum[i][j] = firstMatrix[i][j] + secondMatrix[i][j]
}
}
printSolution(sum)
}
private fun printSolution(matrix: Array<IntArray>) {
for (array in matrix) {
for (value in array) {
print("$value ")
}
println()
}
}
}
My main problem lies with sum in the addition function since I do not know how to fill it with dynamic row and column size and currently inserted a standard value of 4 and 5.
fun addition() {
val firstMatrix = createMatrix()
val secondMatrix = createMatrix()
val sum = Array(4) { IntArray(5) }
for (i in 0 until 4) {
for (j in 0 until 5) {
sum[i][j] = firstMatrix[i][j] + secondMatrix[i][j]
}
}
printSolution(sum)
}
It looks like you're storing your matrices in row-major order: you have individual arrays representing rows, and then an outer array holding all the rows.  So the size of the outer array gives you the number of rows, and the size of any of the inner arrays (such as the first) gives you the number of columns.
So you can create the sum like this:
val sum = Array(firstMatrix.size) { IntArray(firstMatrix[0].size) }
for (i in sum.indices)
for (j in sum[0].indices)
sum[i][j] = firstMatrix[i][j] + secondMatrix[i][j]
(I've used .indices instead of an explicit range, for simplicity.)
An alternative approach is to specify the values when creating the arrays, instead of filling them in afterwards.  (It doesn't make too much difference here, as numeric arrays get a default value of 0; but it can simplify things a lot when creating arrays of a non-nullable reference type.)
val sum = Array(firstMatrix.size) { row ->
IntArray(firstMatrix[0].size) { column ->
firstMatrix[row][column] + secondMatrix[row][column]
}
}
The Array() and IntArray() constructors pass the index into the lambda; while the first version ignores it, here we call it row or columns so we can use it to index the arrays we're summing.
The above assumes that all the inner arrays have the same size.  That's probably reasonable in this case, where you've created the arrays yourself — but in general you'd probably want to verify that.
Certainly, it would be a good idea to verify that the two matrices you're adding are the same size, and throw an IllegalArgumentException with a helpful message if not.  Otherwise, you'd either get an ArrayIndexOutOfBoundsException (if the first were larger), or values would get silently truncated (if the second were larger) — both of which would be much harder to track down.
(The underlying issue here is that, like most languages, Kotlin doesn't have true two-dimensional arrays.  What it does have is arrays of arrays, which are more flexible — and therefore more dangerous.  If you were doing this properly, you'd probably wrap the array-of-arrays into your own Matrix class, which would always ensure that the data was properly rectangular, provide access to the row and column counts, and make all the necessary checks.)
From what i've understood your problem is the fact that you must set a fixed size for Array. I suggest you to use ArrayList instead to solve the problem.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-array-list/
With this solution you don't need to set a size for sum anymore.
Once you'll use ArrayLists you'll never get back to Arrays.

Cyclomatic Complexity edges

So I'm trying to figure out if that blue line is in the right place, I know that I should have 9 edges but not sure if it's correct.
The code
public int getResult(int p1, int p2) {
int result = 0; // 1
if (p1 == 0) { // 2
result += 1; //3
} else {
result += 2; //4
}
if (p2 == 0) { //5
result += 3; //6
} else {
result += 4; //7
}
return result; //8 exit node
}
so 8 nodes and it should have 9 edges, right? Did I do the right thing?
Yes, the blue line is placed correctly because after the 3rd line, your program is going to jump to the 5th line.
The easiest way to compute cyclomatic complexity without drawing any flow diagram is as follows:
Count all the loops in the program for, while, do-while, if. Assign a value of 1 to each loop. Else should not be counted here.
Assign a value of 1 to each switch case. Default case should not be counted here.
Cyclomatic complexity = Total number of loops + 1
In your program, there are 2 if loops, so the cyclomatic complexity would be 3(2+1)
You can cross-check it with the standard formulae available as well which are as below:
C = E-N+2 (9-8+2=3)
OR
C = Number of closed regions + 1 (2+1=3)
According to wikipedia:
M = E − N + 2P,
where
E = the number of edges of the graph.
N = the number of nodes of the graph.
P = the number of connected components.
so:
9 - 8 + 2*1 = 3

Is there a way to simplify incremental calculations in acrobat?

Other than using a long string of if statements is there a way to program an acrobat text box to incrementally calculate based on variables entered into an other text box?
Here is what I have.
var v = this.getField("FixNum").value;
if (v == "1")
{
event.value = 84 ;
}
else if (v == "2")
{
event.value = 88 ;
}
else if (v == "3")
{
event.value = 92 ;
}
else
{
event.value = "";
}
As you can see this will get cumbersome because this goes from 1 - 9 in this pattern where 9 = 116, then 10 - 100 where 10 = 135. After 100 the pattern is 495 + 6 for every unit i.e. 101 = 501. I hope someone can understand this because I can't think of another way to ask!
Several possibilities:
• If you can come up with a formula, it would be simplest.
• If the value pairs are arbitrary, you might create a lookup table (in form of an array).
• If the input numbers are (more or less) consecutive integers, you can work with a simple array, where the index is the input number, and the element with that index number is the output number.
• If it is more complicated, you would have to create a 2-dimensional array, where each element is an array of input and output number.
• If you are looking for a simple replacement of if…else if statements, you can use the switch… statement, which would work well for totally arbitrary value pairs.
Update, following the comment by OP:
According to a comment by the OP, the input numbers are consecutive, which means that the third point above would be the method of choice. For that, proceed as follows:
Create a document-level script (the name does not matter):
var myPricesArr = [0, 12, 15, 17, 23, 27, 30, 33] ;
alternate possibility:
var myPricesArr = new Array() ;
myPricesArr[0] = 0 ;
myPricesArr[1] = 12 ;
myPricesArr[2] = 15 ;
myPricesArr[3] = 17 ;
myPricesArr[4] = 23 ;
myPricesArr[5] = 27 ;
myPricesArr[6] = 30 ;
myPricesArr[7] = 33 ;
Both variants are equivalent, but the second one is easier to maintain, but requires more typing…
Create a text field named "numFixts", formatted as number, no decimals, maybe with a maximum value (to protect the form from failing).
Create a text field named "fixtsAmt, formatted as number. In the Calculate event of this field add the following JavaScript:
event.value = myPricesArr[this.getField("numFixts").value] ;
And that should do it.

Generate combinations ordered by an attribute

I'm looking for a way to generate combinations of objects ordered by a single attribute. I don't think lexicographical order is what I'm looking for... I'll try to give an example. Let's say I have a list of objects A,B,C,D with the attribute values I want to order by being 3,3,2,1. This gives A3, B3, C2, D1 objects. Now I want to generate combinations of 2 objects, but they need to be ordered in a descending way:
A3 B3
A3 C2
B3 C2
A3 D1
B3 D1
C2 D1
Generating all combinations and sorting them is not acceptable because the real world scenario involves large sets and millions of combinations. (set of 40, order of 8), and I need only combinations above the certain threshold.
Actually I need count of combinations above a threshold grouped by a sum of a given attribute, but I think it is far more difficult to do - so I'd settle for developing all combinations above a threshold and counting them. If that's possible at all.
EDIT - My original question wasn't very precise... I don't actually need these combinations ordered, just thought it would help to isolate combinations above a threshold. To be more precise, in the above example, giving a threshold of 5, I'm looking for an information that the given set produces 1 combination with a sum of 6 ( A3 B3 ) and 2 with a sum of 5 ( A3 C2, B3 C2). I don't actually need the combinations themselves.
I was looking into subset-sum problem, but if I understood correctly given dynamic solution it will only give you information is there a given sum or no, not count of the sums.
Thanks
Actually, I think you do want lexicographic order, but descending rather than ascending. In addition:
It's not clear to me from your description that A, B, ... D play any role in your answer (except possibly as the container for the values).
I think your question example is simply "For each integer at least 5, up to the maximum possible total of two values, how many distinct pairs from the set {3, 3, 2, 1} have sums of that integer?"
The interesting part is the early bailout, once no possible solution can be reached (remaining achievable sums are too small).
I'll post sample code later.
Here's the sample code I promised, with a few remarks following:
public class Combos {
/* permanent state for instance */
private int values[];
private int length;
/* transient state during single "count" computation */
private int n;
private int limit;
private Tally<Integer> tally;
private int best[][]; // used for early-bail-out
private void initializeForCount(int n, int limit) {
this.n = n;
this.limit = limit;
best = new int[n+1][length+1];
for (int i = 1; i <= n; ++i) {
for (int j = 0; j <= length - i; ++j) {
best[i][j] = values[j] + best[i-1][j+1];
}
}
}
private void countAt(int left, int start, int sum) {
if (left == 0) {
tally.inc(sum);
} else {
for (
int i = start;
i <= length - left
&& limit <= sum + best[left][i]; // bail-out-check
++i
) {
countAt(left - 1, i + 1, sum + values[i]);
}
}
}
public Tally<Integer> count(int n, int limit) {
tally = new Tally<Integer>();
if (n <= length) {
initializeForCount(n, limit);
countAt(n, 0, 0);
}
return tally;
}
public Combos(int[] values) {
this.values = values;
this.length = values.length;
}
}
Preface remarks:
This uses a little helper class called Tally, that just isolates the tabulation (including initialization for never-before-seen keys). I'll put it at the end.
To keep this concise, I've taken some shortcuts that aren't good practice for "real" code:
This doesn't check for a null value array, etc.
I assume that the value array is already sorted into descending order, required for the early-bail-out technique. (Good production code would include the sorting.)
I put transient data into instance variables instead of passing them as arguments among the private methods that support count. That makes this class non-thread-safe.
Explanation:
An instance of Combos is created with the (descending ordered) array of integers to combine. The value array is set up once per instance, but multiple calls to count can be made with varying population sizes and limits.
The count method triggers a (mostly) standard recursive traversal of unique combinations of n integers from values. The limit argument gives the lower bound on sums of interest.
The countAt method examines combinations of integers from values. The left argument is how many integers remain to make up n integers in a sum, start is the position in values from which to search, and sum is the partial sum.
The early-bail-out mechanism is based on computing best, a two-dimensional array that specifies the "best" sum reachable from a given state. The value in best[n][p] is the largest sum of n values beginning in position p of the original values.
The recursion of countAt bottoms out when the correct population has been accumulated; this adds the current sum (of n values) to the tally. If countAt has not bottomed out, it sweeps the values from the start-ing position to increase the current partial sum, as long as:
enough positions remain in values to achieve the specified population, and
the best (largest) subtotal remaining is big enough to make the limit.
A sample run with your question's data:
int[] values = {3, 3, 2, 1};
Combos mine = new Combos(values);
Tally<Integer> tally = mine.count(2, 5);
for (int i = 5; i < 9; ++i) {
int n = tally.get(i);
if (0 < n) {
System.out.println("found " + tally.get(i) + " sums of " + i);
}
}
produces the results you specified:
found 2 sums of 5
found 1 sums of 6
Here's the Tally code:
public static class Tally<T> {
private Map<T,Integer> tally = new HashMap<T,Integer>();
public Tally() {/* nothing */}
public void inc(T key) {
Integer value = tally.get(key);
if (value == null) {
value = Integer.valueOf(0);
}
tally.put(key, (value + 1));
}
public int get(T key) {
Integer result = tally.get(key);
return result == null ? 0 : result;
}
public Collection<T> keys() {
return tally.keySet();
}
}
I have written a class to handle common functions for working with the binomial coefficient, which is the type of problem that your problem falls under. It performs the following tasks:
Outputs all the K-indexes in a nice format for any N choose K to a file. The K-indexes can be substituted with more descriptive strings or letters. This method makes solving this type of problem quite trivial.
Converts the K-indexes to the proper index of an entry in the sorted binomial coefficient table. This technique is much faster than older published techniques that rely on iteration. It does this by using a mathematical property inherent in Pascal's Triangle. My paper talks about this. I believe I am the first to discover and publish this technique, but I could be wrong.
Converts the index in a sorted binomial coefficient table to the corresponding K-indexes.
Uses Mark Dominus method to calculate the binomial coefficient, which is much less likely to overflow and works with larger numbers.
The class is written in .NET C# and provides a way to manage the objects related to the problem (if any) by using a generic list. The constructor of this class takes a bool value called InitTable that when true will create a generic list to hold the objects to be managed. If this value is false, then it will not create the table. The table does not need to be created in order to perform the 4 above methods. Accessor methods are provided to access the table.
There is an associated test class which shows how to use the class and its methods. It has been extensively tested with 2 cases and there are no known bugs.
To read about this class and download the code, see Tablizing The Binomial Coeffieicent.
Check out this question in stackoverflow: Algorithm to return all combinations
I also just used a the java code below to generate all permutations, but it could easily be used to generate unique combination's given an index.
public static <E> E[] permutation(E[] s, int num) {//s is the input elements array and num is the number which represents the permutation
int factorial = 1;
for(int i = 2; i < s.length; i++)
factorial *= i;//calculates the factorial of (s.length - 1)
if (num/s.length >= factorial)// Optional. if the number is not in the range of [0, s.length! - 1]
return null;
for(int i = 0; i < s.length - 1; i++){//go over the array
int tempi = (num / factorial) % (s.length - i);//calculates the next cell from the cells left (the cells in the range [i, s.length - 1])
E temp = s[i + tempi];//Temporarily saves the value of the cell needed to add to the permutation this time
for(int j = i + tempi; j > i; j--)//shift all elements to "cover" the "missing" cell
s[j] = s[j-1];
s[i] = temp;//put the chosen cell in the correct spot
factorial /= (s.length - (i + 1));//updates the factorial
}
return s;
}
I am extremely sorry (after all those clarifications in the comments) to say that I could not find an efficient solution to this problem. I tried for the past hour with no results.
The reason (I think) is that this problem is very similar to problems like the traveling salesman problem. Until unless you try all the combinations, there is no way to know which attributes will add upto the threshold.
There seems to be no clever trick that can solve this class of problems.
Still there are many optimizations that you can do to the actual code.
Try sorting the data according to the attributes. You may be able to avoid processing some values from the list when you find that a higher value cannot satisfy the threshold (so all lower values can be eliminated).
If you're using C# there is a fairly good generics library here. Note though that the generation of some permutations is not in lexicographic order
Here's a recursive approach to count the number of these subsets: We define a function count(minIndex,numElements,minSum) that returns the number of subsets of size numElements whose sum is at least minSum, containing elements with indices minIndex or greater.
As in the problem statement, we sort our elements in descending order, e.g. [3,3,2,1], and call the first index zero, and the total number of elements N. We assume all elements are nonnegative. To find all 2-subsets whose sum is at least 5, we call count(0,2,5).
Sample Code (Java):
int count(int minIndex, int numElements, int minSum)
{
int total = 0;
if (numElements == 1)
{
// just count number of elements >= minSum
for (int i = minIndex; i <= N-1; i++)
if (a[i] >= minSum) total++; else break;
}
else
{
if (minSum <= 0)
{
// any subset will do (n-choose-k of them)
if (numElements <= (N-minIndex))
total = nchoosek(N-minIndex, numElements);
}
else
{
// add element a[i] to the set, and then consider the count
// for all elements to its right
for (int i = minIndex; i <= (N-numElements); i++)
total += count(i+1, numElements-1, minSum-a[i]);
}
}
return total;
}
Btw, I've run the above with an array of 40 elements, and size-8 subsets and consistently got back results in less than a second.