Perl 6 - Curried Function Hangs - functional-programming

So, I wanted to be able to write a function that will figure out all the ways that you could make change for a specific amount of money, using coins of different values.
So, I wrote a function coin that tells you for a given amount, how many ways you can make change for that value, given a certain value coin, and a function that will calculate how many ways you could make change, with the same kinds of parameters for the next smaller coin.
I then tried to write a function ladder that I want to return a function that for an #array of coin values will return a function takes a single formal parameter $amt that calculates the number of ways that you could make change for that amount given the values of the coins specified in the array.
I tried to use the &coin function with an .assuming method to add in the values of coins and build up the appropriate ladder. Unfortunately, it hangs when I try to run the resulting function.
my #values = 2, 5, 10, 20, 50, 100, 200;
#the coin of value 1 is assumed as a base case
my &test = ladder(#values);
say &test(5);
sub ladder(#values) {
my &base = sub () { return #values.shift };
for #values {
&base = &coin.assuming(*,$_,&base);
}
return &base;
}
sub coin($amt,$value,&lesser) {
if $amt >= $value {
return &coin($amt-$value,$value,&lesser) + &lesser($amt);
} else {
return &lesser($amt);
}
}
To give an idea it &ladders should produce the equivalent of &twopd in the below series of functions.
sub twopd($amt) { return &coin($amt,200,&onepd) };
sub onepd($amt) { return &coin($amt,100,&fifp) };
sub fifp($amt) { return &coin($amt,50,&twep) };
sub twep($amt) { return &coin($amt,20,&tenp) };
sub tenp($amt) { return &coin($amt,10,&fivp) };
sub fivp($amt) { return &coin($amt,5,&twop) };
sub twop($amt) { return &coin($amt,2,&onep) };
sub onep($amt) { return 1 };
I was wondering if anyone might have an idea what I am doing wrong.

sub () { return #values.shift } will remove a value from #values everytime it gets called, which is not what you want.
&coin.assuming(*,$_,&base) needs to do something with the &base so that it gets the current value in &base and not what is left in it at the end of the loop. One option is to add | in front of it and another is to use <> to decontainerize the value.
It is probably a good idea to add some caching to coin as it will get called with the same arguments many times for larger values.
sub ladder ( +# ($initial, *#values) ) {
my &base = -> $ { $initial };
for #values {
&base = &coin.assuming: *, $_, &base<>;
}
return &base;
}
use experimental :cached;
sub coin ( $amt, $value, &lesser ) is cached {
if $amt >= $value {
coin( $amt - $value, $value, &lesser ) + lesser($amt);
} else {
lesser( $amt );
}
}

Related

Palindrome-Testing Function

I'm trying to make a palindrome-testing function for an http://www.freecodecamp.com/challenges/bonfire-check-for-palindromes
exercise, and I don't understand why the below function doesn't work. I took out all non-letters, made it lower-case- what is the problem?
function palindrome(str) {
if (str.replace(/[^A-Za-z]/g, '').toLowerCase().split('').reverse().join('')===str)
{
return true;
}
else {
return false;
}
}
You took out all the non-letters and converted to lowercase only the left side of the equation, then (after reversion) you are equating it to str which might still have uppercase and non-letters
Try:
function palindrome(str) {
return str.replace(/[^A-Za-z]/g, '').toLowerCase().split('').reverse().join('') === str.replace(/[^A-Za-z]/g, '').toLowerCase();
}
Note that there's no need to do if(x) return true else return false, you can just return the boolean that's inside the if.

codeigniter recursive model function returning blank but when printing it in the model showing properly

codeigniter recursive model function returning blank but when printing it in the model showing properly
here is my code,
for controller
$commision_arr=$this->billing_model->root_commision($category_manager['id']);
and in the model
public function root_commision($id)
{
$sql="SELECT * FROM tbl_mst_category WHERE id = '".$id."'";
$query = $this->db->query($sql);
$row=$query->row_array();
if($row['parent']!=0)
{
$this->root_commision($row['parent']);
}
else
return $row;
}
recursion is tricky huh?
i think the problem is that you were only returning the id for the deepest element, but not returning that to the calling method -- so it would only work for the case where the parent id was called. i can't test the code below, but it should point you in the right direction. NB, it returns the row as an object, not as an array as your code does.
On a more academic note, if the table is large it may be better to pre-calculate these root ids for each of these categories. it will make the query much faster -- recursion is not fast. look at transitive closures
public function root_commision($id,$root_found = FALSE)
{
// returns FALSE if the id is not found, or the parent row.
$query = $this->db->get_where('tbl_mst_category', array('id' => $id));
if ($query->num_rows() > 0 )
{
$row = $query->first_row();
if (($row->parent ) != 0 )
{
return $this->root_commision($row_id);
}
else
{
return $row;
}
}
else
{
return FALSE;
}
}
you have to return function at the calling time then only you can get
the value of recursive function just add "return" keyword before function call.
public function root_commision($id)
{
$sql="SELECT * FROM tbl_mst_category WHERE id = '".$id."'";
$query = $this->db->query($sql);
$row=$query->row_array();
if($row['parent']!=0)
{
return $this->root_commision($row['parent']);
}
else
return $row;
}

Recursion : method which takes a string, and for each repeating sequence of characters in the string, removes all but one of them

Complete the following method which takes a string, and for each repeating sequence of characters in the string, removes all but one of them. For example, given the input string "AAAABCCDDDDAACCCCCC", the method should return "ABCDAC".
YOUR CODE MUST BE RECURSIVE. Do not use any loops (while, do/while, or for). Do not declare any variables outside of the method. You may declare local variables inside the method.
public static String eliminateRepeats (String s)
{
The trick here is that you need a loop to solve this, so you just fake a loop by calling the method recursively with smaller and smaller parts of the string.
There is no way to divide the work into smaller parts, as one usually does when using recursion (like for example split the string in half). You just have to process one character at a time, and call the method with the rest of the string.
Example in C#:
public static string EliminateRepeats(string s) {
return
s.Length == 1 ?
s
:
(s[0] != s[1] ? s.Substring(0, 1) : "")
+ EliminateRepeats(s.Substring(1));
}
(Code inspired by Jonathan Paynes code.)
public class Recurse
{
public static void main( String args[] )
{
System.out.println( recurse( "AAAABCCDDDDAACCCCCC" ) );
}
private static String recurse( String s )
{
if ( s == null || s.equalsIgnoreCase("") )
{
return "";
}
else if ( s.length() > 1 )
{
if ( !s.substring( 0 , 1 ).equalsIgnoreCase( s.substring( 1 , 2 ) ) )
{
return s.substring( 0 , 1 ) + recurse( s.substring( 1 ) );
}
return recurse( s.substring( 1 ) );
}
else
{
return s.substring( 0 , 1 );
}
}
}
// use a default value for the lastchar for the first char,
// which is impossible to meet in an regular string
def concentrate (s: String, lastchar: Char = 0) : String = {
// recursive methods always need to know when it is enough
if (s.length == 0) s else
if (s(0) == lastchar) concentrate (s.substring (1), lastchar) else
s(0) + concentrate (s.substring (1), s(0)) }
concentrate ("AAAABCCDDDDAACCCCCC")
Here is a tailrecursive variation:
#tailrec
def concentrate (s: String, carry:String = "", lastchar: Char = 0) : String = {
if (s.length == 0) carry else
if (s(0) == lastchar) concentrate (s.substring (1), carry, lastchar) else
concentrate (s.substring (1), carry + s(0), s(0)) }
It has the recursive call in the last position, since the resulting string gets glued together on the fly, and passed as parameter. In Scala, this can be optimized by the compiler to run nearly as fast as a loop with mutable variables, and it will not blow the stack - not even for very long Strings.

Ternary usage in FizzBuzz++ 1.5 (codeacademy)

I've been running through codeacademy's tutorials and projects. On FizzBuzz++ 1.5 they want us to re-write the "Wobble" function as Wob, using ternary operators. I keep getting an error saying "missing operand" with the following code. Also the +1 on the end of the return, how does that work, does javaScript store it as a temp value because it doesn't get assigned to any var. Thanks for the help. Code is below.
var Wibble = {
Wobble: function(a, b) {
if(a===b)
//if the variables are equal return 0
return 0;
else {
//decrement the larger of the 2 values
if (a>b) {
a--;
} else {
b--;
}
//call this function again with the decremented values
//once they are equal the functions will return up the stack
//adding 1 to the return value for each recursion
return Wibble.Wobble(a,b)+1;
}
},
//This is the line of code that doesn't want to function..
Wob: function(a, b) {
(a===b) ? return 0 :(a<b) ? return this.Wob(a--,b)+1 : return this.Wob(a,b--)+1;
}
};
The following expression with the ternary operator:
result = (a) ? x : y;
is equivalent to the following:
if(a)
{
result = x;
}
else
{
result = y;
}
Note the syntactical difference, where in the ternary operator you are switching in the assignment, whereas in the if statement syntax, you are assigning in the switch.
That is to say that:
(a == b) ? return 0 : return 1;
is not equivalent to:
if(a == b)
return 0;
else
return 1;
Instead, you would want to write:
return (a == b) ? 0 : 1;

How to Hold and Continue FOR-LOOP from the same spot

Hi guys I got a for/foreach loop the calls a function inside of it. The prolem is that the function being-called doesnt fininsh it's job before the loop goes over again/
Here is my code:
private function ziv(result:Array,fail:Object):void
{
var i:uint = result.length;
for each(var f:Object in result)
{
var item:Object = f;
notfriend=item;
FacebookDesktop.fqlQuery("SELECT uid1, uid2 FROM friend WHERE uid1 = me() AND uid2 = "+item.id,myfriends);
}
}
private function myfriends(result:Object,fail:Object):void
{
if (result.length != 0)
myfriend.addItem(notfriend);
}
As you can see i want to add an item (notfriend) in MYFRIENDS function, "notfriend" is defined inside the loop, but by the time "MYFRIENDS" function finish loading the item already changes to the next item even though i was originally refering to the previous item.
Is there a way to maybe hold the FORloop until "myfriends" function finish loading.
I wanted to use Eventlistener on "myfriends" function , but then what do i do to stop\hold the loop? all i know is BREAK-which destroyes the FOR-LOOP and CONTINUE-which continue the loop from the next iterate.
10x alot , im really braking my head here!
Maybe look at not using a for loop and do your loop manually (example below uses recursion)
ie
private var index=0;
private function processArray() {
proccessArrayItem(array[index])
}
private function proccessArrayItem(obj) {
//after complete then call function recursively
index++;
if (index<array.length) proccessArrayItem(array[index])
}
U can use recursive function in some cases
like
private function setZoom():void
{
var zoomLevel:Number = new Number(myPanel);
if(zoomLevel != 100)
{
if(zoomLevel < 100)
{
myPanel.zoomIN();
setZoom();
}
else
{
myPanel.zoomOUT();
setZoom();
}
}
}
but some cases we cant do that
by only one solution we can achieve by
using TimerFunctions
setTimeout() or callLater();

Resources