Error When Trying to Out Prime Numbers in Node.js - node.js

I'm writing a node.js script that writes the first 100 prime numbers to a file, with each prime separated by a comma.
#!/usr/bin/env node
function listPrimes( max ) {
var primes = [];
var sieve = new Array( max );
for( var i = 0; i < max; i++ ) {
sieve[i] = true;
}
for( var p = 2; p < max; p++ ) {
if( sieve[p] ) {
// p is prime, save it and mark p*2, p*3, etc. as non-prime
primes.push( p );
for( var t = p * 2; t < max; t += p ) {
sieve[t] = false;
}
}
}
return primes;
}
var k = 20;
console.log("listPrimes(" + k + ")");
console.log(fmt(listPrimes(k)));
When I try to put it through I get this error:
ubuntu#ip-172-31-47-235:~$ node hw2.js
listPrimes(20)
/home/ubuntu/hw2.js:22
console.log(fmt(listPrimes(k)));
^
ReferenceError: fmt is not defined
at Object.<anonymous> (/home/ubuntu/hw2.js:22:13)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
I have no idea what's wrong, I'm a beginner so it may be very obvious.
Edit: Fixed
#!/usr/bin/env node
function listPrimes( max ) {
var primes = [];
var sieve = new Array( max );
for( var i = 0; i < max; i++ ) {
sieve[i] = true;
}
for( var p = 2; p < max; p++ ) {
if( sieve[p] ) {
// p is prime, save it and mark p*2, p*3, etc. as non-prime
primes.push( p );
for( var t = p * 2; t < max; t += p ) {
sieve[t] = false;
}
}
}
return primes;
}
var k = 100;
console.log("listPrimes(" + k + "):" + listPrimes(k));
Returns:
ubuntu#ip-172-31-47-235:~$ node hw2.js
listPrimes(100):2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97

Change the two lines
console.log("listPrimes(" + k + ")");
console.log(fmt(listPrimes(k)));
to the single line
console.log("listPrimes(" + k + "): " + listPrimes(k).join(", "));
You don't need fmt and anyway that's not how you would use it...
edited just realized that listPrimes returns an array, not a single value. Hence added the join - it allows me to put "comma, space" between the numbers which looks a bit nicer than all the digits crammed together.
As for your "afterquestion" - not sure what you are doing wrong. The following is what happens on my machine (having copied your file hw2.js to a local directory):
bigMac:node floris$ node hw2.js
listPrimes(100): 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
bigMac:node floris$ node hw2.js > output.txt
bigMac:node floris$ cat output.txt
listPrimes(100): 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
bigMac:node floris$ dir
total 16
drwxr-xr-x 4 floris floris 136 Jul 4 16:17 .
drwxr-xr-x 140 floris floris 4760 Jul 4 16:13 ..
-rw-r--r-- 1 floris floris 561 Jul 4 16:15 hw2.js
-rw-r--r-- 1 floris floris 112 Jul 4 16:17 output.txt
bigMac:node floris$
As you can see, when I run the command with the > output.txt, the output is directed to a file. Given the error you are getting, you must be doing something different - I can't figure out from your comment what it is. Did you put the > in the source file, perhaps?

You are trying to call a function 'fmt' which you haven't defined.

As others have suggested, there is no function fmt.
Since you are returning an array, your last line may as well look like:
console.log(listPrimes(k).join(","));
Yes, there is no sanity check on the return value of listPrimes() as it always returns something.

Related

Adding items to a deque() via a generator

I have a prime number generator. The yielded items are cast into a list. I can reference any item in the list.
def primes(limit):
yield 2
if limit < 3:
return
lmtbf = (limit - 3) // 2
buf = [True] * (lmtbf + 1)
for i in range((int(limit ** 0.5) - 3) // 2 + 1):
if buf[i]:
p = i + i + 3
s = p * (i + 1) + i
buf[s::p] = [False] * ((lmtbf - s) // p + 1)
for i in range(lmtbf + 1):
if buf[i]:
yield i + i + 3
x = list(primes(100))
print(x)
print(len(x), '\n')
Output:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
25
The problem is if I use x = list(primes(num)) with a very large number then the resultant list becomes
extremely large.
All I want are the last n (the largest) items in the list, but I would to be able to vary n.
I thought a deque() would be perfect for this. I was looking through documentation and I found: Appending to a deque that is full (len(d) == d.maxlen) discards items from the other end.
This, combined with the ability to specify a maxlen=n at queue creation is exactly what I want.
With that in mind, I tried this:
from collections import deque
def primes(limit):
yield 2
if limit < 3:
return
lmtbf = (limit - 3) // 2
buf = [True] * (lmtbf + 1)
for i in range((int(limit ** 0.5) - 3) // 2 + 1):
if buf[i]:
p = i + i + 3
s = p * (i + 1) + i
buf[s::p] = [False] * ((lmtbf - s) // p + 1)
for i in range(lmtbf + 1):
if buf[i]:
yield i + i + 3
x = deque([primes(100)], maxlen=10)
# x = list(primes(100))
print(x)
print(len(x), '\n')
But what I get is this:
deque([<generator object primes at 0x0000025ED8449C80>], maxlen=10)
1
I also tried:
for i in x:
print(x)
But that also does not work.
How can I use deque() as I described above to get my desired result?
I need to be able to print out the contents of the deque, which should be the last n items from the generator.
Figured it out: x = deque([x for x in primes(100)], maxlen=10)
deque([53, 59, 61, 67, 71, 73, 79, 83, 89, 97], maxlen=10)
10
x = deque([x for x in primes(1000)], maxlen=10)
deque([937, 941, 947, 953, 967, 971, 977, 983, 991, 997], maxlen=10)
10

Wrong PWM pin output?

I am fairly new to programming, and as I have a fascination for music I thought to start with building a simple sequencer using codes from the web.
Now I found a perfect code but somehow it does not behave as it needs to and I hope to get some advice here in order to learn more and eventually build my own synthesizer!
/* analog inputs:
* A0 pitch step 1 (syncPhaseInc)
* A1 pitch step 2
* A2 pitch step 3
* A3 pitch step 4
* A4 tempo
* A5 effect (grainPhaseInc)
* plus volume potentiometer
*
* audio out via 220 ohm resistor to 3.5mm jack
* audio out via 10K/10K voltage divider and 10K volume pot and 10uF cap to internal mono amp with speaker
* power switch on amp
* built with Arduino Nano on perf board powered by USB cable
*/
#include <avr/io.h>
#include <avr/interrupt.h>
uint16_t syncPhaseAcc;
uint16_t syncPhaseInc;
uint16_t grainPhaseAcc;
uint16_t grainPhaseInc;
uint16_t grainAmp;
uint8_t grainDecay;
uint16_t grain2PhaseAcc;
uint16_t grain2PhaseInc;
uint16_t grain2Amp;
uint8_t grain2Decay;
// Changing these will also requires rewriting audioOn()
#if defined(__AVR_ATmega8__)
//
// On old ATmega8 boards.
// Output is on pin 11
//
#define LED_PIN 13
#define LED_PORT PORTB
#define LED_BIT 5
#define PWM_PIN 11
#define PWM_VALUE OCR2
#define PWM_INTERRUPT TIMER2_OVF_vect
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
//
// On the Arduino Mega
// Output is on pin 3
//
#define LED_PIN 13
#define LED_PORT PORTB
#define LED_BIT 7
#define PWM_PIN 3
#define PWM_VALUE OCR3C
#define PWM_INTERRUPT TIMER3_OVF_vect
#else
//
// For modern ATmega168 and ATmega328 boards
// Output is on pin 3
//
#define PWM_PIN 3
#define PWM_VALUE OCR2B
#define LED_PIN 13
#define LED_PORT PORTB
#define LED_BIT 5
#define PWM_INTERRUPT TIMER2_OVF_vect
#endif
// Smooth logarithmic mapping
//
uint16_t antilogTable[] = {
64830, 64132, 63441, 62757, 62081, 61413, 60751, 60097, 59449, 58809, 58176, 57549, 56929, 56316, 55709, 55109,
54515, 53928, 53347, 52773, 52204, 51642, 51085, 50535, 49991, 49452, 48920, 48393, 47871, 47356, 46846, 46341,
45842, 45348, 44859, 44376, 43898, 43425, 42958, 42495, 42037, 41584, 41136, 40693, 40255, 39821, 39392, 38968,
38548, 38133, 37722, 37316, 36914, 36516, 36123, 35734, 35349, 34968, 34591, 34219, 33850, 33486, 33125, 32768
};
uint16_t mapPhaseInc(uint16_t input) {
return (antilogTable[input & 0x3f]) >> (input >> 6);
}
// Stepped chromatic mapping
//
uint16_t midiTable[] = {
17, 18, 19, 20, 22, 23, 24, 26, 27, 29, 31, 32, 34, 36, 38, 41, 43, 46, 48, 51, 54, 58, 61, 65, 69, 73,
77, 82, 86, 92, 97, 103, 109, 115, 122, 129, 137, 145, 154, 163, 173, 183, 194, 206, 218, 231,
244, 259, 274, 291, 308, 326, 346, 366, 388, 411, 435, 461, 489, 518, 549, 581, 616, 652, 691,
732, 776, 822, 871, 923, 978, 1036, 1097, 1163, 1232, 1305, 1383, 1465, 1552, 1644, 1742,
1845, 1955, 2071, 2195, 2325, 2463, 2610, 2765, 2930, 3104, 3288, 3484, 3691, 3910, 4143,
4389, 4650, 4927, 5220, 5530, 5859, 6207, 6577, 6968, 7382, 7821, 8286, 8779, 9301, 9854,
10440, 11060, 11718, 12415, 13153, 13935, 14764, 15642, 16572, 17557, 18601, 19708, 20879,
22121, 23436, 24830, 26306
};
uint16_t mapMidi(uint16_t input) {
return (midiTable[(1023 - input) >> 3]);
}
// Stepped Pentatonic mapping
//
uint16_t pentatonicTable[54] = {
0, 19, 22, 26, 29, 32, 38, 43, 51, 58, 65, 77, 86, 103, 115, 129, 154, 173, 206, 231, 259, 308, 346,
411, 461, 518, 616, 691, 822, 923, 1036, 1232, 1383, 1644, 1845, 2071, 2463, 2765, 3288,
3691, 4143, 4927, 5530, 6577, 7382, 8286, 9854, 11060, 13153, 14764, 16572, 19708, 22121, 26306
};
uint16_t mapPentatonic(uint16_t input) {
uint8_t value = (1023 - input) / (1024 / 53);
return (pentatonicTable[value]);
}
void audioOn() {
#if defined(__AVR_ATmega8__)
// ATmega8 has different registers
TCCR2 = _BV(WGM20) | _BV(COM21) | _BV(CS20);
TIMSK = _BV(TOIE2);
#elif defined(__AVR_ATmega1280__)
TCCR3A = _BV(COM3C1) | _BV(WGM30);
TCCR3B = _BV(CS30);
TIMSK3 = _BV(TOIE3);
#else
// Set up PWM to 31.25kHz, phase accurate
TCCR2A = _BV(COM2B1) | _BV(WGM20);
TCCR2B = _BV(CS20);
TIMSK2 = _BV(TOIE2);
#endif
}
long counter = 0;
long tempo;
int pattern = 0;
const byte pat0 = 4;
const byte pat1 = 5;
const byte pat2 = 6;
const byte pat3 = 7;
void setup() {
pinMode(PWM_PIN, OUTPUT);
audioOn();
pinMode(LED_PIN, OUTPUT);
pinMode(pat0, OUTPUT);
pinMode(pat1, OUTPUT);
pinMode(pat2, OUTPUT);
pinMode(pat3, OUTPUT);
digitalWrite(pat0, LOW);
digitalWrite(pat1, LOW);
digitalWrite(pat2, LOW);
digitalWrite(pat3, LOW);
// presets for 3 less important pots
grainDecay = 200 / 8;
grain2PhaseInc = mapPhaseInc(200) / 2;
grain2Decay = 200 / 4;
}
void loop() {
tempo = map(analogRead(A4), 0, 1023, 100, 4000);
counter++;
if (counter > tempo) {
counter = 0;
if (pattern == 4) {
pattern = 0;
}
switch (pattern) {
case 0:
syncPhaseInc = mapPentatonic(analogRead(A0));
digitalWrite(pat3, LOW);
digitalWrite(pat0, HIGH);
break;
case 1:
syncPhaseInc = mapPentatonic(analogRead(A1));
digitalWrite(pat0, LOW);
digitalWrite(pat1, HIGH);
break;
case 2:
syncPhaseInc = mapPentatonic(analogRead(A2));
digitalWrite(pat1, LOW);
digitalWrite(pat2, HIGH);
break;
case 3:
syncPhaseInc = mapPentatonic(analogRead(A3));
digitalWrite(pat2, LOW);
digitalWrite(pat3, HIGH);
break;
}
grainPhaseInc = mapPhaseInc(analogRead(A5)) / 2;
pattern++;
}
}
SIGNAL(PWM_INTERRUPT)
{
uint8_t value;
uint16_t output;
syncPhaseAcc += syncPhaseInc;
if (syncPhaseAcc < syncPhaseInc) {
// Time to start the next grain
grainPhaseAcc = 0;
grainAmp = 0x7fff;
grain2PhaseAcc = 0;
grain2Amp = 0x7fff;
LED_PORT ^= 1 << LED_BIT; // Faster than using digitalWrite } // Increment the phase of the grain oscillators grainPhaseAcc += grainPhaseInc; grain2PhaseAcc += grain2PhaseInc; // Convert phase into a triangle wave value = (grainPhaseAcc >> 7) & 0xff;
if (grainPhaseAcc & 0x8000) value = ~value;
// Multiply by current grain amplitude to get sample
output = value * (grainAmp >> 8);
// Repeat for second grain
value = (grain2PhaseAcc >> 7) & 0xff;
if (grain2PhaseAcc & 0x8000) value = ~value;
output += value * (grain2Amp >> 8);
// Make the grain amplitudes decay by a factor every sample (exponential decay)
grainAmp -= (grainAmp >> 8) * grainDecay;
grain2Amp -= (grain2Amp >> 8) * grain2Decay;
// Scale output to the available range, clipping if necessary
output >>= 9;
if (output > 255) output = 255;
// Output to PWM (this is faster than using analogWrite)
PWM_VALUE = output;
}
one thing I cannot explain is that the sound output pin is different from the one in the code. The code states that the output pin is PWM 3 for an ATmega328 which I use, but the sound from this pin is SUPER soft and noisy when I amplify the sound with an amplifier chip.
PWM 13 produces clean and loud sound, but putting filters and effects over the sound does not seem to work.
Does somebody know why this is the case? I would really like to use effects over the sounds. Because what is a synthesizer without awesome effects?!
Thanks in advance !!

Khan Academy Binary Search Algorithm step 3 correct, but not passing.

I'm working through the Khan Academy Binary Search problem and step three is asking for some basic additions to "...help visualize how long the search takes."
The prompt asks to "...add a println() statement that displays the total number of guesses it takes to find the result.
Your function should only print the total number of guesses when it has found the target. Your function shouldn't be printing the number of guesses every loop."
I have done this successfully with a incrementing counter and a println() with that variable. Running the code works perfectly, however, the Khan Academy pre-built environment will not let me past this step. Is there another way they are expecting?
Code here:
/* Returns either the index of the location in the array,
or -1 if the array did not contain the targetValue */
var doSearch = function(array, targetValue) {
var min = 0;
var max = array.length - 1;
var guess;
var guessTotal = 0;
while(min <= max){
guess = Math.floor((min + max) / 2);
println("You guessed " + guess);
if(array[guess] === targetValue){
println(guessTotal);
return guess;
}
else if (array[guess] < targetValue){
min = guess + 1;
}
else{
max = guess -1;
}
guessTotal ++;
}
return -1;
};
var primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97];
var result = doSearch(primes, 73);
println("Found prime at index " + result);
Program.assertEqual(doSearch(primes, 73), 20);
Note: I also tried adding returning an array with the guess and guessTotal, then printing them from the result. That also did what they asked, but did not pass either.
Here right answer
/* Returns either the index of the location in the array,
or -1 if the array did not contain the targetValue */
var doSearch = function(array, targetValue) {
var min = 0;
var max = array.length - 1;
var guess;
var guessTotal = 0;
while(min <= max) {
guess = Math.floor((max + min) / 2);
println(guess);
guessTotal++;
if (array[guess] === targetValue) {
println(guessTotal);
return guess;
}
else if (array[guess] < targetValue) {
min = guess + 1;
}
else {
max = guess - 1;
}
}
return -1;
};
var primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97];
var result = doSearch(primes, 73);
println("Found prime at index " + result);
Program.assertEqual(doSearch(primes, 73), 20);
while(min <= max) {
guess = Math.floor((max + min) / 2);
println(guess); //OMIT 1
guessTotal++; // OMIT 2
if (array[guess] === targetValue) {
println(guessTotal); // OMIT 3
return guess;
OMIT 1: You're already printing at the bottom after you run the function
OMIT 2: You're already setting your counter with guessTotal++ below;
OMIT 3: It appears here like you're trying to also print your counter which you don't need to do.
If you omit those 3 lines, your code should now run properly.
For the next step in Khan Academy's challenge (which I realized afterwards), your code is fine except for your counter that should start at 1:
var guessTotal = 1;
or
println(guessTotal + 1 );
Hope this was helpful.
Replace var guessTotal = 0 with var guessTotal = 1 or you can keep var guessTotal = 0 and increment it right after you get into while loop.
Basically you have to satisfy their condition
From Khan Academy - Note: A binary search for the target value 41 on the array primes requires 1 guess.
Your code returns 0 for the above condition

Permutation of string as substring of another

Given a string A and another string B. Find whether any permutation of B exists as a substring of A.
For example,
if A = "encyclopedia"
if B="dep" then return true as ped is a permutation of dep and ped is a substring of A.
My solution->
if length(A)=n and length(B)=m
I did this in 0((n-m+1)*m) by sorting B and then checking A
with window size of m each time.
I need to find a better and a faster solution.
There is a simpler solution to this problem.
Here: n = A.size (), m = B.size ()
The idea is to use hashing.
First we hash the characters of string B.
Suppose: B = "dep"
hash_B ['d'] = 1;
hash_B ['e'] = 1;
hash_B ['p'] = 1;
Now we run a loop over the string 'A' for each window of size 'm'.
Suppose: A = "encyclopedia"
First window of size 'm' will have characters {e, n, c}. We will hash them now.
win ['e'] = 1
win ['n'] = 1
win ['c'] = 1
Now we check if the frequency of each character from both the arrays (hash_B [] and win []) are same. Note: Maximum size of hash_B [] or win [] is 26, hence the complexity would be O(26 * N) ~ O(N).
If they are not same we shift our window.
After shifting the window we decrease the count of win ['e'] by 1 and increase the count of win ['y'] by 1.
win ['n'] = 1
win ['c'] = 1
win ['y'] = 1
During the seventh shift, the status of your win array is:
win ['p'] = 1;
win ['e'] = 1;
win ['d'] = 1;
which is same as the hash_B array. So, Print "SUCCESS" and exit.
If I only have to worry about ASCII characters, it can be done in O(n) time with O(1) space. My code also prints the permutations out, but can be easily modified to simply return true at the first instance instead. The main part of the code is located in the printAllPermutations() method. Here is my solution:
Some Background
This is a solution that I came up with, it is somewhat similar to the idea behind the Rabin Karp Algorithm. Before I understanding the algorithm, I will explain the math behind it as follows:
Let S = {A_1, ..., A_n} be a multiset list of size N that contains only prime numbers. Let the sum of the numbers in S equal some integer Q. Then S is the only possible entirely prime multiset of size N, whose elements can sum to Q.
Because of this, we know we can map every character to a prime number. I propose a map as follows:
1 -> 1st prime
2 -> 2nd prime
3 -> 3rd prime
...
n -> nth prime
If we do this (which we can because ASCII only has 256 possible characters), then it becomes very easy for us to find each permutation in the larger string B.
The Algorithm:
We will do the following:
1: calculate the sum of the primes mapped to by each of the characters in A, let's call it smallHash.
2: create 2 indices (righti and lefti). righti is initialized to zero, and lefti is initialzed to the size of A.
ex: | |
v v
"abcdabcd"
^ ^
| |
3: Create a variable currHash, and initialize it to the sum of the corresponding prime numbers mapped to by each of the characters in B, between (inclusive) righti, and lefti - 1.
4: Iterate both righti and lefti by 1, each time updating currHash by subtracting the prime mapped from the character that is no longer in the range (lefti - 1) and adding the prime corresponding to the character just added to the range (righti)
5: Each time currHash is equal to smallHash, the characters in the range must be a permutation. So we print them out.
6: Continue until we have reached the end of B. (When righti is equal to the length of B)
This solution runs in O(n) time complexity and O(1) space.
The Actual Code:
public class FindPermutationsInString {
//This is an array containing the first 256 prime numbers
static int primes[] =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
1597, 1601, 1607, 1609, 1613, 1619
};
public static void main(String[] args) {
String big = "abcdabcd";
String small = "abcd";
printAllPermutations(big, small);
}
static void printAllPermutations(String big, String small) {
// If the big one is smaller than the small one,
// there can't be any permutations, so return
if (big.length() < small.length()) return;
// Initialize smallHash to be the sum of the primes
// corresponding to each of the characters in small.
int smallHash = primeHash(small, 0, small.length());
// Initialize righti and lefti.
int lefti = 0, righti = small.length();
// Initialize smallHash to be the sum of the primes
// corresponding to each of the characters in big.
int currentHash = primeHash(small, 0, righti);
while (righti <= big.length()) {
// If the current section of big is a permutation
// of small, print it out.
if (currentHash == smallHash)
System.out.println(big.substring(lefti, righti));
// Subtract the corresponding prime value in position
// lefti. Then increment lefti
currentHash -= primeHash(big.charAt(lefti++));
if (righti < big.length()) // To prevent index out of bounds
// Add the corresponding prime value in position righti.
currentHash += primeHash(big.charAt(righti));
//Increment righti.
righti++;
}
}
// Gets the sum of all the nth primes corresponding
// to n being each of the characters in str, starting
// from position start, and ending at position end - 1.
static int primeHash(String str, int start, int end) {
int value = 0;
for (int i = start; i < end; i++) {
value += primeHash(str.charAt(i));
}
return value;
}
// Get's the n-th prime, where n is the ASCII value of chr
static int primeHash(Character chr) {
return primes[chr];
}
}
Keep in mind, however, that this solution only works when the characters can only be ASCII characters. If we are talking about unicode, we start getting into prime numbers that exceed the maximum size of an int, or even a double. Also, I'm not sure that there are 1,114,112 known primes.
Building a little on the algorithm presented by j_random_hacker in comments, it is possible to find the match in O(|A|+|B|), as follows: (Note: throughout, we use |A| to mean "the length of A".)
Create an integer array count whose domain is the size of the alphabet, initialized to all 0s.
Set distance to 0
For each character Bi in B:
Decrement count[Bi].
If the previous count of count[Bi] was 0, also increment distance.
For each character Ai in A:
Increment count[Ai]
If i is greater than |B| decrement count[Ai-|B|].
For each of the two count values modified, if the previous value was 0, then increment distance and if the new value is 0 then decrement distance.
If the result is that distance is 0 then a match has been found.
Note: The algorithm presented by j_random_hacker is also O(|A|+|B]) because the cost of comparing freqA with freqB is O(|alphabet|), which is a constant. However, the above algorithm reduces the comparison cost to a small constant. In addition, it is theoretically possible to make this work even if the alphabet is not a constant size by using the standard trick for uninitialized arrays.
This answer proposes a fixed implementation of the idea proposed by #Ephraim in his own answer.
The original answer confuses the multiplication property of a given set of primes with addition. The fixed statement would be:
Let S = {A_1, ..., A_n} be a multiset list of size N that contains only prime numbers. Let the product of the numbers in S equal some integer Q. Then S is the only possible entirely prime multiset of size N, whose elements can multiply to Q.
In order to avoid numerical overflows, the implementation uses infinite precision arithmetic based on the C++ library libgmpxx.
Under the assumption that the comparison between two numbers is in O(1), then the solution is in O(|A| + |B|). The previous assumption might actually not be the case for inputs where |B| is large enough. When |B| > |A| the function returns in O(1).
Example:
#include <iostream>
#include <string>
#include <gmpxx.h>
static int primes[] =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
1597, 1601, 1607, 1609, 1613, 1619
};
mpz_class prime_hash(std::string const &str, size_t start, size_t end)
{
mpz_class hash(1);
for (size_t i = start; i < end; ++i) {
hash *= primes[(size_t) str.at(i)];
}
return hash;
}
void print_all_permutations(std::string const &big, std::string const &small)
{
const size_t big_len = big.length();
const size_t small_len = small.length();
if (small_len <= 0 || big_len < small_len) {
// no possible permutation!
return;
}
// O(small_len)
mpz_class small_hash = prime_hash(small, 0, small_len);
mpz_class curr_hash = prime_hash(big, 0, small_len);
// O(big_len)
size_t left_idx = 0;
do {
if (curr_hash == small_hash) {
std::cout << "Permutation `" << big.substr(left_idx, small_len)
<< "' of `" << small
<< "' at index " << left_idx
<< " of `" << big
<< "'." << std::endl;
}
curr_hash /= primes[(size_t) big.at(left_idx)];
if (left_idx + small_len < big_len) {
curr_hash *= primes[(size_t) big.at(left_idx + small_len)];
}
++left_idx;
} while (left_idx + small_len < big_len);
}
int main(int argc, char *argv[])
{
// #user2826957's input
print_all_permutations("encyclopedia", "dep");
// #Ephraim's input
print_all_permutations("abcdabcd", "abcd");
// #Sam's input
print_all_permutations("cbabadcbbabbc", "abbc");
// #butt0s input
print_all_permutations("", "");
print_all_permutations("", "a");
print_all_permutations("a", "");
print_all_permutations("a", "a");
return 0;
}
The example is compiled with:
~$ g++ permstr.cpp -lgmpxx -lgmp -o run
~$ ./run
Permutation `ped' of `dep' at index 7 of `encyclopedia'.
Permutation `abcd' of `abcd' at index 0 of `abcdabcd'.
Permutation `bcda' of `abcd' at index 1 of `abcdabcd'.
Permutation `cdab' of `abcd' at index 2 of `abcdabcd'.
Permutation `dabc' of `abcd' at index 3 of `abcdabcd'.
Permutation `cbab' of `abbc' at index 0 of `cbabadcbbabbc'.
Permutation `cbba' of `abbc' at index 6 of `cbabadcbbabbc'.
Permutation `a' of `a' at index 0 of `a'.
My approach is first give yourself a big example such as
a: abbc
b: cbabadcbbabbc
Then literally go through and underline each permutation
a: abbc
b: cbabadcbbabbc
'__'
'__'
'__'
Therefore
For i-> b.len:
sub = b.substring(i,i+len)
isPermuted ?
Here is code in java
class Test {
public static boolean isPermuted(int [] asciiA, String subB){
int [] asciiB = new int[26];
for(int i=0; i < subB.length();i++){
asciiB[subB.charAt(i) - 'a']++;
}
for(int i=0; i < 26;i++){
if(asciiA[i] != asciiB[i])
return false;
}
return true;
}
public static void main(String args[]){
String a = "abbc";
String b = "cbabadcbbabbc";
int len = a.length();
int [] asciiA = new int[26];
for(int i=0;i<a.length();i++){
asciiA[a.charAt(i) - 'a']++;
}
int lastSeenIndex=0;
for(int i=0;i<b.length()-len+1;i++){
String sub = b.substring(i,i+len);
System.out.printf("%s,%s\n",sub,isPermuted(asciiA,sub));
} }
}
The below function will return true if the String B is a permuted substring of String A.
public boolean isPermutedSubstring(String B, String A){
int[] arr = new int[26];
for(int i = 0 ; i < A.length();++i){
arr[A.charAt(i) - 'a']++;
}
for(int j=0; j < B.length();++j){
if(--arr[B.charAt(j)-'a']<0) return false;
}
return true;
}
The idea is clear in above talkings. An implementation with O(n) time complexity is below.
#include <stdio.h>
#include <string.h>
const char *a = "dep";
const char *b = "encyclopediaped";
int cnt_a[26];
int cnt_b[26];
int main(void)
{
const int len_a = strlen(a);
const int len_b = strlen(b);
for (int i = 0; i < len_a; i++) {
cnt_a[a[i]-'a']++;
cnt_b[b[i]-'a']++;
}
int i;
for (i = 0; i < len_b-len_a; i++) {
if (memcmp(cnt_a, cnt_b, sizeof(cnt_a)) == 0)
printf("%d\n", i);
cnt_b[b[i]-'a']--;
cnt_b[b[i+len_a]-'a']++;
}
if (memcmp(cnt_a, cnt_b, sizeof(cnt_a)) == 0)
printf("%d\n", i);
return 0;
}
Here's a solution that's pretty much rici's answer.
https://wandbox.org/permlink/PdzyFvv8yDf3t69l
It allocates a little more than 1k stack memory for the frequency table. O(|A| + |B|), no heap allocations.
#include <string>
bool is_permuted_substring(std::string_view input_string,
std::string_view search_string) {
if (search_string.empty()) {
return true;
}
if (search_string.length() > input_string.length()) {
return false;
}
int character_frequencies[256]{};
auto distance = search_string.length();
for (auto c : search_string) {
character_frequencies[(uint8_t)c]++;
}
for (auto i = 0u; i < input_string.length(); ++i) {
auto& cur_frequency = character_frequencies[(uint8_t)input_string[i]];
if (cur_frequency > 0) distance--;
cur_frequency--;
if (i >= search_string.length()) {
auto& prev_frequency = ++character_frequencies[(
uint8_t)input_string[i - search_string.length()]];
if (prev_frequency > 0) {
distance++;
}
}
if (!distance) return true;
}
return false;
}
int main() {
auto test = [](std::string_view input, std::string_view search,
auto expected) {
auto result = is_permuted_substring(input, search);
printf("%s: is_permuted_substring(\"%.*s\", \"%.*s\") => %s\n",
result == expected ? "PASS" : "FAIL", (int)input.length(),
input.data(), (int)search.length(), search.data(),
result ? "T" : "F");
};
test("", "", true);
test("", "a", false);
test("a", "a", true);
test("ab", "ab", true);
test("ab", "ba", true);
test("aba", "aa", false);
test("baa", "aa", true);
test("aacbba", "aab", false);
test("encyclopedia", "dep", true);
test("encyclopedia", "dop", false);
constexpr char negative_input[]{-1, -2, -3, 0};
constexpr char negative_search[]{-3, -2, 0};
test(negative_input, negative_search, true);
return 0;
}
I am late to this party...
The question is also discussed in the book named Cracking the Coding Interview, 6th Edition on page number 70. The auther says there is a possiblity of finding all permutations using O(n) time complexity (linear) but she doesnt write the algorithm so I thought I should give it a go.
Here is the C# solution just in case if someone was looking...
Also, I think (not 100% sure) it finds the count of permutations using O(n) time complexity.
public int PermutationOfPatternInString(string text, string pattern)
{
int matchCount = 0;
Dictionary<char, int> charCount = new Dictionary<char, int>();
int patLen = pattern.Length;
foreach (char c in pattern)
{
if (charCount.ContainsKey(c))
{
charCount[c]++;
}
else
{
charCount.Add(c, 1);
}
}
var subStringCharCount = new Dictionary<char, int>();
// loop through each character in the given text (string)....
for (int i = 0; i <= text.Length - patLen; i++)
{
// check if current char and current + length of pattern-th char are in the pattern.
if (charCount.ContainsKey(text[i]) && charCount.ContainsKey(text[i + patLen - 1]))
{
string subString = text.Substring(i, patLen);
int j = 0;
for (; j < patLen; j++)
{
// there is no point going on if this subString doesnt contain chars that are in pattern...
if (charCount.ContainsKey(subString[j]))
{
if (subStringCharCount.ContainsKey(subString[j]))
{
subStringCharCount[subString[j]]++;
}
else
{
subStringCharCount.Add(subString[j], 1);
}
}
else
{
// if any of the chars dont appear in the subString that we are looking for
// break this loop and continue...
break;
}
}
int x = 0;
// this will be true only when we have current subString's permutation count
// matched with pattern's.
// we need this because the char count could be different
if (subStringCharCount.Count == charCount.Count)
{
for (; x < patLen; x++)
{
if (subStringCharCount[subString[x]] != charCount[subString[x]])
{
// if any count dont match then we break from this loop and continue...
break;
}
}
}
if (x == patLen)
{
// this means we have found a permutation of pattern in the text...
// increment the counter.
matchCount++;
}
subStringCharCount.Clear(); // clear the count map.
}
}
return matchCount;
}
and here is the unit test method...
[TestCase("encyclopedia", "dep", 1)]
[TestCase("cbabadcbbabbcbabaabccbabc", "abbc", 7)]
[TestCase("xyabxxbcbaxeabbxebbca", "abbc", 2)]
public void PermutationOfStringInText(string text, string pattern, int expectedAnswer)
{
int answer = runner.PermutationOfPatternInString(text, pattern);
Assert.AreEqual(expectedAnswer, answer);
}
Taking O(TEXT.length) runtime complexity.
Some of these solutions will not work when average of calculated
text value matches average of calculated pattern value. Ex - uw and
vv. Though they are not matching, some solutions above still returns
TRUE.
public static void main(String[] args) {
String pattern = "dep";
String text = "encyclopedia";
System.out.println(isPermutationAvailable(pattern, text));
}
public static boolean isPermutationAvailable(String pattern, String text) {
if (pattern.length() > text.length()) {
return false;
}
int[] patternMap = new int[26];
int[] textMap = new int[26];
for (int i = 0; i < pattern.length(); i++) {
patternMap[pattern.charAt(i) - 'a']++;
textMap[text.charAt(i) - 'a']++;
}
int count = 0;
for (int i = 0; i < 26; i++) {
if (patternMap[i] == textMap[i]) {
count++;
}
}
for (int i = 0; i < text.length() - pattern.length(); i++) {
int r = text.charAt(i + pattern.length()) - 'a';
int l = text.charAt(i) - 'a';
if (count == 26) {
return true;
}
textMap[r]++;
if (textMap[r] == patternMap[r]) {
count++;
}
else if (textMap[r] == patternMap[r] + 1) {
count--;
}
textMap[l]--;
if (textMap[l] == patternMap[l]) {
count++;
}
else if (textMap[l] == patternMap[l] - 1) {
count--;
}
}
return count == 26;
}
Based on checking the longer string with a window size of short one. Since permutation only changes the position of a character, sorted string will always be the same.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main ()
{
string shortone = "abbc";
string longone ="cbabadcbbabbcbabaabccbabc";
int s_length = shortone.length ();
int l_length = longone.length ();
string sub_string;
string unsorted_substring; // only for printing
// sort the short one
sort (shortone.begin (), shortone.end ());
if (l_length > s_length)
{
for (int i = 0; i <= l_length - s_length; i++){
sub_string = "";
//Move the window
sub_string = longone.substr (i, s_length);
unsorted_substring=sub_string;
// sort the substring window
sort (sub_string.begin (), sub_string.end ());
if (shortone == sub_string)
{
cout << "substring is :" << unsorted_substring << '\t' <<
"match found at the position: " << i << endl;
}
}
}
return 0;
}

How to select Y values at X position in Groovy?

this is sort of a mathy question...
I had a question prior to this about normalizing monthly data here :
How to produce X values of a stretched graph?
I got a good answer and it works well, the only issue is that now I need to check X values of one month with 31 days against X values of a month with 28.
So my question would be: If I have two sets of parameters like so:
x | y x2 | y2
1 | 10 1.0 | 10
2 | 9 1.81 | 9.2
3 | 8 2.63 | 8.6
4 | 7 3.45 | 7.8
5 | 6 4.27 | 7
6 | 5 5.09 | 6.2
7 | 4 5.91 | 5.4
8 | 3 6.73 | 4.2
9 | 2 7.55 | 3.4
10 | 1 8.36 | 2.6
9.18 | 1.8
10.0 | 1.0
As you can see, the general trend is the same for these two data sets.
However, if I run these values through a cross-correlation function (the general goal), I will get something back that does not reflect this, since the data sets are of two different sizes.
The real world example of this would be, say, if you are tracking how many miles you run per day:
In February (with 28 days), during the first week, you run one mile each day. During the second week, you run two miles each day, etc.
In March (with 31 days), you do the same thing, but run for one mile for eight days, two miles for eight days, three miles for eight days, and four miles for seven days.
The correlation coefficient according to the following function should be almost exactly 1:
class CrossCorrelator {
def variance = { x->
def v = 0
x.each{ v += it**2}
v/(x.size()) - (mean(x)**2)
}
def covariance = {x, y->
def z = 0
[x, y].transpose().each{ z += it[0] * it[1] }
(z / (x.size())) - (mean(x) * mean(y))
}
def coefficient = {x, y->
covariance(x,y) / (Math.sqrt(variance(x) * variance(y)))
}
}
def i = new CrossCorrelator()
i.coefficient(y values, y2 values)
Just looking at the data sets, it seems like the graphs would be exactly the same if I were to grab the values at 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10, and the function would produce a more accurate result.
However, it's skewed since the lengths are not the same.
Is there some way to locate what the values at the integers in the twelve-value data set would be? I haven't found a simple way to do it, but this would be incredibly helpful.
Thanks in advance,
5
Edit: As per request, here is the code that generates the X values of the graphs:
def x = (1..12)
def y = 10
change = {l, size ->
v = [1]
l.each{
v << ((((size-1)/(x.size() - 1)) * it) + 1)
}
v -= v.last()
return v
}
change(x, y)
Edit: Not working code as per another request:
def normalize( xylist, days ) {
xylist.collect { x, y -> [ x * ( days / xylist.size() ), y ] }
}
def change = {l, size ->
def v = [1]
l.each{
v << ((((size-1)/(l.size() - 1)) * it) + 1)
}
v -= v.last()
return v
}
def resample( list, min, max ) {
// We want a graph with integer points from min to max on the x axis
(min..max).collect { i ->
// find the values above and below this point
bounds = list.inject( [ a:null, b:null ] ) { r, p ->
// if the value is less than i, set it in r.a
if( p[ 0 ] < i )
r.a = p
// if it's bigger (and we don't already have a bigger point)
// then set it into r.b
if( !r.b && p[ 0 ] >= i )
r.b = p
r
}
// so now, bounds.a is the point below our required point, and bounds.b
// Deal with the first case (where a is null, because we are at the start)
if( !bounds.a )
[ i, list[ 0 ][ 1 ] ]
else {
// so work out the distance from bounds.a to bounds.b
dist = ( bounds.b[0] - bounds.a[0] )
// And how far the point i is along this line
r = ( i - bounds.a[0] ) / dist
// and recalculate the y figure for this point
y = ( ( bounds.b[1] - bounds.a[1] ) * r ) + bounds.a[1]
[ i, y ]
}
}
}
def feb = [9, 3, 7, 23, 15, 16, 17, 18, 19, 13, 14, 8, 13, 12, 15, 6, 7, 13, 19, 12, 7, 3, 4, 15, 6, 17, 8, 19]
def march = [8, 12, 4, 17, 11, 15, 12, 8, 9, 13, 12, 7, 3, 4, 8, 2, 17, 19, 21, 12, 12, 13, 14, 15, 16, 7, 8, 19, 21, 14, 16]
//X and Y Values for February
z = [(1..28), change(feb, 28)].transpose()
//X and Y Values for March stretched to 28 entries
o = [(1..31), change(march, 28)].transpose()
o1 = normalize(o, 28)
resample(o1, 1, 28)
If I switch "march" in the o variable declaration to (1..31), the script runs successfully. When I try to use "march," I get "
java.lang.NullPointerException: Cannot invoke method getAt() on null object"
Also: I try not to directly copy code just because it's bad practice, so one of the functions I changed basically does the same thing, it's just my version. I'll get around to refactoring the rest of it eventually, too. But that's why it's slightly different.
Ok...here we go...this may not be the cleanest bit of code ever...
Let's first generate two distributions, both from 1 to 10 (in the y axis)
def generate( range, max ) {
range.collect { i ->
[ i, max * ( i / ( range.to - range.from + 1 ) ) ]
}
}
// A distribution 10 elements long from 1 to 10
def e1 = generate( 1..10, 10 )
// A distribution 14 elements long from 1 to 10
def e2 = generate( 1..14, 10 )
So now, e1 and e2 are:
[1.00,1.00], [2.00,2.00], [3.00,3.00], [4.00,4.00], [5.00,5.00], [6.00,6.00], [7.00,7.00], [8.00,8.00], [9.00,9.00], [10.00,10.00]
[1.00,0.71], [2.00,1.43], [3.00,2.14], [4.00,2.86], [5.00,3.57], [6.00,4.29], [7.00,5.00], [8.00,5.71], [9.00,6.43], [10.00,7.14], [11.00,7.86], [12.00,8.57], [13.00,9.29], [14.00,10.00]
respectively (to 2dp). Now, using the code from the previous question, we can normalize these to the same x range:
def normalize( xylist, days ) {
xylist.collect { x, y -> [ x * ( days / xylist.size() ), y ] }
}
n1 = normalize( e1, 10 )
n2 = normalize( e2, 10 )
This means n1 and n2 are:
[1.00,1.00], [2.00,2.00], [3.00,3.00], [4.00,4.00], [5.00,5.00], [6.00,6.00], [7.00,7.00], [8.00,8.00], [9.00,9.00], [10.00,10.00]
[0.71,0.71], [1.43,1.43], [2.14,2.14], [2.86,2.86], [3.57,3.57], [4.29,4.29], [5.00,5.00], [5.71,5.71], [6.43,6.43], [7.14,7.14], [7.86,7.86], [8.57,8.57], [9.29,9.29], [10.00,10.00]
But, as you correctly state they have different numbers of sample points, so cannot be compared easily.
But we can write a method to step through each point we want in our graph, fond the two closest points, and interpolate a y value from the values of these two points like so:
def resample( list, min, max ) {
// We want a graph with integer points from min to max on the x axis
(min..max).collect { i ->
// find the values above and below this point
bounds = list.inject( [ a:null, b:null ] ) { r, p ->
// if the value is less than i, set it in r.a
if( p[ 0 ] < i )
r.a = p
// if it's bigger (and we don't already have a bigger point)
// then set it into r.b
if( !r.b && p[ 0 ] >= i )
r.b = p
r
}
// so now, bounds.a is the point below our required point, and bounds.b
if( !bounds.a ) // no lower bound...take the first element
[ i, list[ 0 ][ 1 ] ]
else if( !bounds.b ) // no upper bound... take the last element
[ i, list[ -1 ][ 1 ] ]
else {
// so work out the distance from bounds.a to bounds.b
dist = ( bounds.b[0] - bounds.a[0] )
// And how far the point i is along this line
r = ( i - bounds.a[0] ) / dist
// and recalculate the y figure for this point
y = ( ( bounds.b[1] - bounds.a[1] ) * r ) + bounds.a[1]
[ i, y ]
}
}
}
final1 = resample( n1, 1, 10 )
final2 = resample( n2, 1, 10 )
now, the values final1 and final2 are:
[1.00,1.00], [2.00,2.00], [3.00,3.00], [4.00,4.00], [5.00,5.00], [6.00,6.00], [7.00,7.00], [8.00,8.00], [9.00,9.00], [10.00,10.00]
[1.00,1.00], [2.00,2.00], [3.00,3.00], [4.00,4.00], [5.00,5.00], [6.00,6.00], [7.00,7.00], [8.00,8.00], [9.00,9.00], [10.00,10.00]
(obviously, there is some rounding here, so 2d.p. is hiding the fact that they are not exactly the same)
Phew... Must be home-time after that ;-)
EDIT
As pointed out in the edit to the question, there was a bug in my resample method that caused it to fail in certain conditions...
I believe this has now been fixed in the code above, and from the given example:
def march = [8, 12, 4, 17, 11, 15, 12, 8, 9, 13, 12, 7, 3, 4, 8, 2, 17, 19, 21, 12, 12, 13, 14, 15, 16, 7, 8, 19, 21, 14, 16]
o = [ (1..31), march ].transpose()
// X values squeezed to be between 1 and 28 (instead of 1 to 31)
o1 = normalize(o, 28)
// Then, resample this graph so there are only 28 points
v = resample(o1, 1, 28)
If you plot the original 31 points (in o) and the new graph of 28 points (in v), you get:
Which doesn't look too bad.
I have no idea what the change method was supposed to do, so I have omitted it from this code

Resources