Fixing MEL FOR loop - mel

I have been stuck doing this for if loop for the last few days.
Basically, it's a loop that starts at the height of 6 and decreases within the FOR loop, when the height (y) hits 1 I want it to start increasing by 1.
At the moment the loop hits 1, the height increases by 1 but then because it loops back around it does not increase the next shape by another 1.
I know its a bit confusing but I hope I can grab some help!
Thanks!
int $f = 6;
for ($e = 24 ; $e <= 31; $e++)
{
if ($f <= 1) {
string $currentObject = $objects[$e];
select -r $currentObject ;
setAttr ($currentObject+".sy") ($f++);
}
else {
string $currentObject = $objects[$e];
select -r $currentObject ;
setAttr ($currentObject+".sy") ($f--);
}
}

If I understand your problem correctly, you only want to switch the direction of increment or decrement at the extremes, not between, i. e. you need another variable that codes the direction (incrementing or decrementing). I called that $diff in this code:
int $f = 6;
int $diff = -1;
for ($e = 24 ; $e <= 31; $e++)
{
if ($f <= 1) {
$diff = 1;
} else if ($f >= 6) {
$diff = -1;
}
string $currentObject = $objects[$e];
select -r $currentObject ;
setAttr ($currentObject+".sy") ($f);
$f = $f + $diff;
}

Related

function to find the longest increasing subsequence without arrays

I need to make a program in C with those instructions:
the problem is its kinda easy to do with arrays but without them,I cant think anything else.
we need to write a function that takes int n and then takes the sequences of numbers, the function need to return us the sum of the biggest sequence.
for n = 8 and the sequence = 2,4,6,8,11,14,17,9' (there is 2 long sequences of 4, (when 8 starts the new sequence and closes the current sequence) here we will get the print 50.`
for n = 2 and the sequence 7,19 the function will print 26.
for n = 8 and the sequence 8,6,4,2,11,14,15,16
the longest length is 4 so the function will print 20.
can't find any solution here without arrays
printf("please choose a n");
scanf("%d", &n);
y = n;
if (n == 1)
{
printf("Please enter the next number ");
scanf("%d", &series);
return series;
}
else
if (n == 2)
{
while (i < 2) {
{
printf("Please enter the next number ");
scanf("%d", &series);
sum += series;
}
return sum;
}
printf("Plase choose another number");
scanf("%d", &last);
sum += last;
printf("please choose another number");
scanf("%d", &series);
d = series - last;
sum = series + last;
bSum = sum;
for (i = 2; i < n; i++)
{
last = series;
printf("Please write another number; ");
scanf("%d", &series);
if (series - last == d)
{
sum += series;
count++;
}
if (series - last != d)
{
if (count > length)
{
bSum = sum;
length = count;
}
else if (count == length && sum > bSum)
{
bSum = sum;
}
}
}
I had coded this up, but needed clarification from OP (see my top comments).
As a result ...
I added code to pick a sequence of equal length to the best but with a larger sum.
Because it was minimal changes to my code, I chose that the longest sequence wins:
For input of -2 -1 1 2, this is a sequence of 4 with sum 0. It is not two sequences of 2 -2 -1 and 1 2 with sum 3.
For input of 1 1 1 1 1, this is a sequence of 5 with sum 5 and not 5 sequences of 1 [each] with sum 1
Here is the code. It is annotated:
#include <stdio.h>
int
main(void)
{
// get count of sequence numbers
int n;
scanf("%d",&n);
// length of current sequence
int curlen = 0;
// sum of current sequence
int cursum = 0;
// value of current number
int curval;
// value of previous number
int oldval;
// get the first number
scanf("%d",&oldval);
// add it to the current sequence
curlen += 1;
cursum += oldval;
// initialize the best sequence from the current one
int bestsum = cursum;
int bestlen = curlen;
// get all remaining numbers in the sequence
for (int i = 1; i < n; ++i, oldval = curval) {
// get new current number
if (scanf("%d",&curval) != 1) {
fprintf(stderr,"too short\n");
break;
}
// reset the current sequence if we're not increasing
if (curval < oldval) {
cursum = 0;
curlen = 0;
}
// add to the current sequence
cursum += curval;
curlen += 1;
// save off the longest sequence we've seen
if (curlen > bestlen) {
bestlen = curlen;
bestsum = cursum;
continue;
}
// save off a sequence that is the same length as the best but has a
// larger sum
if ((curlen == bestlen) && (cursum > bestsum)) {
bestsum = cursum;
continue;
}
}
// print the final/best sum
printf("%d\n",bestsum);
return 0;
}
Input:
4
-2 -1 1 2
Output: 0
Input:
5
1 1 1 1 1
Output: 5
Input:
2
7 19
Output: 26
Input:
8
2 4 6 8 11 14 17 9
Output: 62
Input:
8
8 6 4 2 11 14 15 16
Output: 58
Input:
12
1 2 3 4
2 3 4 5
3 4 5 6
Output: 18
Input:
2
2 1
Output: 2
Here is the perl script that I used to generate the tests:
Edit: Updated for example below.
#!/usr/bin/perl
# runseq -- run sequence program
#
# options:
# "-D" -- cc -D options
# "-S<sfile>" -- source file (DEFAULT: seq.c)
# "-clip" -- send output to xclip program
# "-d" -- debug runseq script
#
# arguments:
# 1-- [optional] comma separated list of sequence numbers (e.g. 3,7 2,1)
master(#ARGV);
exit(0);
# master -- master control
sub master
{
my(#argv) = #_;
optdcd(\#argv,
"+opt_D","opt_S","opt_clip");
# get source file
$sroot = $opt_S;
$sroot //= "seq";
$sroot =~ s/[.].+$//;
zprtx("compiling %s ...\n",$sroot);
$sfile = "$sroot.c";
sysfault("runseq: no source file\n")
unless (-e $sfile);
push(#cc,"cc");
push(#cc,"-o$sroot");
foreach $opt (#opt_D) {
push(#cc,"-D$opt");
}
push(#cc,$sfile);
$cmd = join(" ",#cc);
zprtx("%s\n",$cmd);
$code = vxsystem(#cc);
exit(1) if ($code);
$tmpfile = "inp.txt";
# send to xclip program
if ($opt_clip) {
open($xfout,"|xclip");
}
else {
$xfout = \*STDOUT;
}
{
# take tests from command line
if (#argv > 0) {
foreach $arg (#argv) {
$arg =~ s/,/ /g;
#body = ($arg);
dosum();
}
last;
}
# get test data from below
$xfdata = \*seq::DATA;
while ($dat = <$xfdata>) {
chomp($dat);
# ignore comments
next if ($dat =~ /^\s*#/);
# blank line separates tests
if ($dat =~ /^\s*$/) {
dosum();
next;
}
push(#body,$dat);
}
}
# do final test
dosum()
if (#body > 0);
close($xfout)
if ($opt_clip);
}
# optdcd -- decode command line options
sub optdcd
{
my(#syms) = #_;
my($argv);
my($arg);
my($ary);
my($symlhs,$symrhs,$val,$match);
$argv = shift(#syms);
# get options
while (#$argv > 0) {
$arg = $argv->[0];
last unless ($arg =~ /^-/);
shift(#$argv);
$match = 0;
foreach $symrhs (#syms) {
$symlhs = $symrhs;
$ary = ($symlhs =~ s/^[+]//);
$opt = $symlhs;
$opt =~ s/^opt_/-/;
zprt("optdcd: TRYARG arg='%s' symrhs='%s' symlhs='%s' opt='%s' ary=%d\n",
$arg,$symrhs,$symlhs,$opt,$ary);
if ($arg =~ /^$opt(.*)$/) {
$val = $1;
$val =~ s/^=//;
$val = 1
if ($val eq "");
if ($ary) {
zprt("optdcd: PUSH val=%s\n",$val);
push(#$symlhs,$val);
}
else {
zprt("optdcd: SET val=%s\n",$val);
$$symlhs = $val;
}
$match = 1;
last;
}
}
sysfault("optdcd: unknown option -- '%s'\n",$arg)
unless ($match);
}
}
sub dosum
{
my($bf);
my(#rhs);
my(#n);
zprtx("\n")
if ($opt_clip);
$xfdst = xfopen(">$tmpfile","dosum");
# get count of sequence values (i.e. "n")
foreach $bf (#body) {
#rhs = split(" ",$bf);
push(#n,#rhs);
}
printf($xfdst "%d\n",scalar(#n));
foreach $bf (#body) {
zprtx("dosum: %s\n",$bf)
if ($opt_clip);
print($xfdst $bf,"\n");
}
$xfdst = xfclose($xfdst);
# run program
my($outval) = (`./$sroot < $tmpfile`);
chomp($outval);
# output test input data and program output
outf("\n");
outf("----------\n")
if ($opt_clip);
outf("Input:\n");
outf("```\n")
if ($opt_clip);
$xfsrc = xfopen("<$tmpfile","dosum");
while ($buf = <$xfsrc>) {
outf("%s",$buf);
}
$xfsrc = xfclose($xfsrc);
outf("```\n")
if ($opt_clip);
outf("\n")
if ($opt_clip);
outf("Output: %d\n",$outval);
undef(#body);
}
sub outf
{
printf($xfout #_);
}
sub zprt
{
goto &zprtx
if ($opt_d);
}
sub zprtx
{
printf(STDERR #_);
}
sub sysfault
{
zprtx(#_);
exit(1);
}
sub xfopen
{
my($file,$who) = #_;
my($xf);
open($xf,$file) or
sysfault("xfopen: unable to open '%s' -- $!\n",$file);
$xf;
}
sub xfclose
{
my($xf) = #_;
close($xf);
undef($xf);
$xf;
}
sub vxsystem
{
my($cmd);
$cmd = join(" ",#_);
system($cmd);
$? >> 8;
}
package seq;
__DATA__
-2 -1 1 2
1 1 1 1 1
7 19
2 4 6 8 11 14 17 9
8 6 4 2 11 14 15 16
1 2 3 4
2 3 4 5
3 4 5 6
2 1
UPDATE:
Here is a version that adds some debug printing (-DDEBUG). And, selection of <= vs < (-DLE).
I've updated the runseq script above to handle this version [it is backwards compatible].
#include <stdio.h>
#if DEBUG
#define dbgprt(_fmt...) \
fprintf(stderr,_fmt)
#else
#define dbgprt(_fmt...) \
do { } while (0)
#endif
int
main(void)
{
// get count of sequence numbers
int n;
scanf("%d", &n);
// length of current sequence
int curlen = 0;
// sum of current sequence
int cursum = 0;
// value of current number
int curval;
// value of previous number
int oldval = 0;
// get the first number
scanf("%d", &curval);
// add it to the current sequence
curlen += 1;
cursum += curval;
dbgprt("OLD: oldval=%d curval=%d cursum=%d curlen=%d\n",
oldval,curval,cursum,curlen);
oldval = curval;
// initialize the best sequence from the current one
int bestsum = cursum;
int bestlen = curlen;
// get all remaining numbers in the sequence
for (int i = 1; i < n; ++i, oldval = curval) {
// get new current number
if (scanf("%d", &curval) != 1) {
fprintf(stderr, "too short\n");
break;
}
// reset the current sequence if we're not increasing
#if LE
if (curval <= oldval) {
cursum = 0;
curlen = 0;
dbgprt("ZAPLE\n");
}
#else
if (curval < oldval) {
cursum = 0;
curlen = 0;
dbgprt("ZAPLT\n");
}
#endif
// add to the current sequence
cursum += curval;
curlen += 1;
dbgprt("CUR: oldval=%d curval=%d cursum=%d curlen=%d\n",
oldval,curval,cursum,curlen);
// save off the longest sequence we've seen
if (curlen > bestlen) {
dbgprt("NEWLEN\n");
bestlen = curlen;
bestsum = cursum;
continue;
}
// save off a sequence that is the same length as the best but has a
// larger sum
if ((curlen == bestlen) && (cursum > bestsum)) {
dbgprt("NEWSUM\n");
bestsum = cursum;
continue;
}
}
// print the final/best sum
printf("%d\n", bestsum);
return 0;
}

how to build a loop that write previous number's 1.8 times

How to write a for loop which has the step of 1.8
for example
for ($i = 1; $i <= 11; $i++) {echo $i;}
$i should give me an output like : 1, 1.8, 3.24, 5.8 , 10.5
$i++ means that you are incrementing the value of $i variable by 1 unit (the initial value you assigned to 1. Each following iteration it will be increased by 1 until it reaches 11 (including 11)). If I understood correctly the question, you want to have a step of 1.8
for ($i = 1; $i <= 11; $i= $i * 1.8) {
echo $i;
}
Or another alternative would be:
$result = 1;
for ($i = 1; $i <= 11; $i++) {
$result *= 1.8;
echo $result;
}
In Java it's simple as:
for (double i = 1; i <= 11; i *= 1.8) {
System.out.println(i);
}
I guess you can convert it to the language you use.

Dividing elements in arrays on specific numbers

I have N arrays like this (4 in example but number can be different)
k1 = [1,0,0,0,1,0,1]
k2 = [0,1,1,0,1,0,1]
k3 = [1,0,0,0,1,0,0]
k4 = [0,0,0,0,1,1,1]
I need to get the following arrays:
k1 = [0.5,0,0,0,0.25,0,0.33]
k2 = [0, 1,1,0,0.25,0,0.33]
k3 = [0.5,0,0,0,0.25,0,0]
k4 = [0, 0,0,0,0.25,1,0.33]
The idea is to divide each element on number of "1" occurrences for the same index in other arrays. So you always get 1 as sum of k1[i]+k2[i]+k3[i]+k4[i]+...kn[i]
You have to create a new array with the sum of all elements and then divide like this :
there must be a "cleaner" way to do this but this works :
$k1 = [1,0,0,0,1,0,1];
$k2 = [0,1,1,0,1,0,1];
$k3 = [1,0,0,0,1,0,0];
$k4 = [0,0,0,0,1,1,1];
//we create an array with names of n array, i took 4 just to test it but it will works with n
$name=[];
for ($v = 1; $v <= 4; $v++) {
$name[$v]="k".$v;
}
$sum=[0,0,0,0,0,0,0];
for ($k = 0; $k <= 6; $k++) {
for ($j = 1; $j <= 4; $j++) {
$sum[$k]=$sum[$k]+${$name[$j]}[$k];
}
}
//and now we update
for ($l = 0; $l <= 6; $l++) {
if($sum[$l]!==0){
for ($q = 1; $q <= 4; $q++) {
${$name[$q]}[$l]=${$name[$q]}[$l]/$sum[$l];
}
}
}
//display to test
for ($m = 0; $m <= 6; $m++) {
echo $k1[$m];
echo " | ";
}

Perl: Using hash instead of array

while ($word = <STDIN>) {
$length = length($word) -1; # Subtract 1 for included newline char
$wordLength[$length]++;
}
print "Word length \t\t Occurrences \n\n";
for ( my $i =1; $i <= $#wordLength; $i++ ) {
if (not exists $wordLength[$i]) {
print "$i \t\t\t 0 \n";
}
else {
print "$i \t\t\t $wordLength[$i] \n";
}
}
This works great reading in a txt file and outputting as such:
Word Length Occurrence
1 27
2 104
3 1039
4 3505
5 7181
6 11765
7 15898
I am trying to get this to work using hash instead of an array but it doesn't seem to work. This is my attempt:
while ($word = <STDIN>) {
chomp($word);
$length = length($word);
$wordLength{$word} = "$length";
}
foreach $word (sort keys %wordLength) {
print "$word, $wordLength{$word}\n"; # print key and value
}
Why? Any array works great here.
my #occurrences_by_length;
while (my $word = <>) {
chomp($word);
my $length = length($word);
++$occurrences_by_length[$length];
}
print "Length Occurrences\n";
for my $length (1..$#occurrences_by_length) {
my $occurrences = $occurrences_by_length[$length]
or next;
printf "%6d %11d\n", $length, $occurrences;
}
A hash, while less efficient, could easily be used with next to no changes.
my %occurrences_by_length;
while (my $word = <>) {
chomp($word);
my $length = length($word);
++$occurrences_by_length{$length};
}
print "Length Occurrences\n";
for my $length (sort { $a <=> $b } keys(%occurrences_by_length)) {
my $occurrences = $occurrences_by_length{$length};
printf "%6d %11d\n", $length, $occurrences;
}

Build Lowest Number by Removing n digits from a given number

It takes as input a number(string) and then the task is to remove n numbers to give a resulting lowest possible number, but you have to take care of the order, that is the constraint. You cannot change the order of the original numbers.
I wanted it to work in O(n), so I did this:
#!/usr/bin/perl
#lowestNS.pl
#Date: 2016-06-28
use warnings;
use strict;
use utf8;
(#ARGV == 2) or die "2 args needed";
my $num = $ARGV[0];
my $d = $ARGV[1];
my #arr;
int($num) > 0 or die "Enter positive number";
print "Number in: $num\nDel: $d\n";
if(int($num) == 0) {
print "Result: 0\n";
exit;
}
else {
my $str = $num;
#arr = split(//, $str); #/Split on each number
#Split and multiply by reverse index, to give precedence to the order of numbers
for(my $i = 0; $i < #arr; $i++) {
$arr[$i] *= (#arr - $i);
}
}
print "arr: " . join(',' , #arr) . "\n";
for (my $j = 0; $j < $d; $j++) {
my $max = $arr[0];
my $m_index = -1;
#replace nth maximum with -1
for (my $i = 0; $i < #arr; $i++) {
if($max <= $arr[$i]) {
$max = $arr[$i];
$m_index = $i;
}
}
$arr[$m_index] = -1;
}
#return all numbers with value other than -1
my $result = "";
for (my $i = 0; $i < #arr; $i++) {
if($arr[$i] != -1){
$result = $result . "" . $arr[$i]/(#arr - $i);
}
}
print "Result: $result\n";
It works in all cases, except, cases like:
Number = 765028321
Delete = 5
The problem is the removal of 765028321 when it should have removed the 765028321.
because 2*5 > 3*3.
I think, the algorithm is straightforward:
Suppose, N is the number of digits to delete;
1. Find the first smallest digit in the first N digits, delete digits to the left of it, decrease N by the number of digits deleted.
2. if N>0 take the digits to the right and repeat the steps above.
Of course, we need to check for marginal cases, and to ensure the final number does not start with 0.
Here is the code draft:
#!/usr/bin/perl
use strict;
use warnings;
my ($number, $del)=#ARGV;
my #num = $number=~m{.}g;
my $curpos=0;
my #finalnum;
for(;;) {
last if $del <=0 || $curpos+$del>=#num;
my $minpos=$curpos;
for (my $i=$curpos;$i<$curpos+$del+1 && $i < #num;$i++) {
if ($num[$i]<$num[$minpos] && !($curpos==0 && $num[$i]==0)) {
$minpos=$i;
}
}
push #finalnum, $num[$minpos];
$del-=($minpos-$curpos);
$curpos=$minpos+1;
}
push #finalnum, #num[$curpos+$del..$#num] if $curpos+$del < #num;
print join '', #finalnum;
A possible solution can be:
Create an array having count of all digits, eg. in your case, this array will look like: 1,1,2,1,0,1,1,1,1,0
Then, in a greedy manner, remove all big digits, as many as can be done. So, you remove 9s, but since its count is 0, you still need to remove 5 digits. Remove 8s, so you still need to remove 4 digits and so on.
This case is kind of trivial, so you will be left with 2 2's, 1 1's and 1 0's. In there were, say 3 4's also in the number, you will then need to remove 1 4. So, you will remove the leftmost of partial removals required.
Its a greedy approach, and works in O(n).

Resources