Converting C++ to PowerShell - powershell

I had an assignment for which I need to list the first 100 Prime Numbers in PowerShell Script. So I coded using C++ and try to convert to PowerShell Script. And the output in PowerShell was not what I am expected.
Note: I am new to PowerShell. Just start learning since past 2 days
I tried to understand the PowerShell syntax and convert it
C++:
int i, j, count = 1, b = 0;
for ( i = 3; i > 0; ++i )
{
for ( j = 2; j <= i / 2; ++j )
{
if ( i % j == 0 )
{
b = 1;
break;
}
}
if ( b == 0 )
{
cout << i << endl;
count++;
}
b = 0;
if ( count == 101 )
break;
}
PowerShell:
$i
$j
$count = 0
$prime = 0
for ( $i = 3; $i -lt 0; ++$i )
{
for ( $j = 2; $j -le $i / 2; ++$j )
{
if ( $i % $j -eq 0 )
{
$prime = 1
break
}
}
if ( $prime -eq 0 )
{
Write-Host("$i 'r 'n")
$count++
}
$prime = 0
if ( $count -eq 101 )
{
break
}
}
I expect the result will be first 100 prime numbers from 3 to 547
But I get 3 2 from PowerShell.
Any advice is welcomed. Thank you in advance

You were close.
> is -gt, you used -lt in your script.
$i = 0
$j = 0
$count = 0
$prime = 0
for ($i = 3; $i -gt 0; ++$i) {
for ($j = 2; $j -le $i / 2; ++$j) {
if ($i % $j -eq 0 ) {
$prime = 1
break
}
}
if ($prime -eq 0) {
Write-Output $i
$count++
}
$prime = 0
if ($count -eq 100) {
break
}
}

Related

powershell Fibonacci sequence stops early

when i enter 55 i want the function to print the fibonacci sequence 55 times but the sequence stops at 55
function Get-Fibonacci ($n) {
$current = 0 ;
$previous = 1;
while ($current -lt $n) {
$current;
$current,$previous = ($current+$previous),$current
}
}
function Get-Fibonacci ($n) {
$current = 0 ;
$previous = 1;
for ($i=0; $i -lt $n; $i++) {
$current;
$current,$previous = ($current+$previous),$current
}
}
Here's an answer which doesn't rewrite using a for loop:
function Get-Fibonacci ($n) {
$current = 0 ;
$previous = 1;
$position=0
while ($position -lt $n) {
$position++
'{0} : {1}' -f $position,$current
$current,$previous = ($current+$previous),$current
}
}

modify this code to print elements that differ a x number from previous position

I wrote this code to find substrings every x elements:
print "enter file path\n";
$letters = <>;
chomp ($letters);
$sequence = "";
open (LETTERS, $letters) or die "error opening\n";
print "how many letters at a shot\n";
$number = <>;
chomp ($number);
$size = length $sequence;
chomp ($size);
for ($i = 0; $i < $size; $i++) {
$test = substr ($sequence, $i, $number);
print "> Test $i\n";
print "$test\n";
if ($i >= $size - $number) {
last;
}
}
so if I open a file with this string and choose x = 3:
abcdefg
I get this result:
> Test 0 abc
> Test 1 bcd
> Test 2 cde
> Test 3 def
> Test 4 efg
Each substring differs from one position from the previous substring, I'd like to be able to control this number and dislocate the substring by 2 for example. So the result would be:
> Test 0 abc
> Test 2 cde
> Test 4 efg
Any suggestions? Thanks
Add:
...
$step = <>;
...
And change:
for ($i = 0; $i < $size; $i++) {
to
for ($i = 0; $i < $size; $i+=$step) {
for ($i = 0; $i < $size; $i += 2) {

Powershell: HSL to RGB

I need to convert HSL color values to RGB, or to be more precise HSL-values to a System.Drawing.Color object with Powershell.
There are a few solutions in other prog.-languages out there (like LINK). But while it looks simple, I dont get it converted it into Powershell.
Function HSLtoRGB ($H,$S,$L) {
$H = [double]($H / 360)
$S = [double]($S / 100)
$L = [double]($L / 100)
if ($s -eq 0) {
$r = $g = $b = $l
}
else {
if ($l -lt 0.5){
$q = $l * (1 + $s)
}
else {
$q = $l + $s - $l * $s
}
$p = (2 * $L) - $q
$r = (Hue2rgb $p $q ($h + 1/3))
$g = (Hue2rgb $p $q $h )
$b = (Hue2rgb $p $q ($h - 1/3))
}
$r = [Math]::Round($r * 255)
$g = [Math]::Round($g * 255)
$b = [Math]::Round($b * 255)
return ($r,$g,$b)
}
function Hue2rgb ($p, $q, $t) {
if ($t -lt 0) { $t++ }
if ($t -gt 0) { $t-- }
if ($t -lt 1/6) { return ( $p + ($q + $p) * 6 * $t ) }
if ($t -lt 1/2) { return $q }
if ($t -lt 2/3) { return ($p + ($q - $p) * (2/3 - $t) * 6 ) }
return $p
}
HSLtoRGB 63 45 40 # result should be R 145 G 148 B 56
Let's start with the line you're having trouble with translating:
$q = l < 0.5 ? l * (1 + s) : l + s - l * s; #could not translate this line
This construct:
statement ? someValue : anotherValue;
is known as a ternary operation. It basically means:
if(statement){
someValue
} else {
anotherValue
}
So in PowerShell that becomes:
$q = if($l -lt 0.5){
$l * (1 + $s)
} else {
$l + $s - $l * $s
}
Your translation of the inline Hue2Rgb function has two typos that greatly change the calculation:
function Hue2rgb ($p, $q, $t) {
if ($t -lt 0) { $t++ }
if ($t -gt 0) { $t-- } # This condition should be ($t -gt 1)
if ($t -lt 1/6) { return ( $p + ($q + $p) * 6 * $t ) } # The innermost calculation should be ($q - $p) not ($q + $p)
if ($t -lt 1/2) { return $q }
if ($t -lt 2/3) { return ($p + ($q - $p) * (2/3 - $t) * 6 ) }
return $p
}
Regarding the input values, if you take a look at the comments in the original script:
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
So if you want to pass your input values as degrees (hue) and percentages (saturation + luminance), you'll have to handle a conversion to a relative value between 0 and 1:
Function HSLtoRGB ($H,$S,$L) {
$H = [double]($H / 360)
$S = [double]($S / 100)
$L = [double]($L / 100)
# rest of script
}
Lastly, you can use Color.FromArgb() to return an actual Color object:
$r = [Math]::Round($r * 255)
$g = [Math]::Round($g * 255)
$b = [Math]::Round($b * 255)
return [System.Drawing.Color]:FromArgb($r,$g,$b)

Perl - Trouble With Loop Variables

I'm fairly new to coding in Perl and am used to using C-style for loops. I'm not sure why the following program never prints a value of 4 for $l:
use strict;
use warnings;
my $minL = 4;
for (my $l = $minL; $l > 0; $l--) {
for (my $i = 0; $i + $l < $minL; $i++) {
print "$i $l\n";
}
}
Many thanks in advance.
Your inner for loop has the condition $i + $l < $minL. If $l == $minL, then $i + $l < $minL will be false even if $i is 0, so the loop runs 0 times and never prints anything.
Maybe you wanted to use <= for the condition?
By the way, here is how you could write the same thing (assuming the <= condition) using Perl-style foreach loops:
my $minL = 4;
for my $l (reverse 1 .. $minL) {
for my $i (0 .. $minL - $l) {
print "$i $l\n";
}
}
In the first iteration:
for (my $l = $minL; $l > 0; $l--) {
$l == $minL
for (my $i = 0; $i + $l < $minL; $i++) {
So this block won't run until $l is decremented:
print "$i $l\n";
}
Change your inner loop to:
for (my $i = 0; $i + $l <= $minL; $i++) {

Collatz Conjecture - Iteration rather than Recursion

I am working on something for learning purposes where I have tackled Collatz using recursion. If you see below I make use of #_ and $_ to keep the for alive.
#!/usr/bin/env perl
sub collatz {
my ($num, $count) = #_;
$count++;
if ($num == 1) {
return $count;
} elsif ($num % 2 == 0) {
return collatz($num/2, $count);
} else {
return collatz($num*3 + 1, $count);
}
}
my $max = 0;
my $saved = 0;
for (1..1000) {
my $length = collatz($_, 0);
print "Num: " . $_ . " Length: " . $length . "\n";
if ($length > $max) {
$max = $length;
$saved = $_;
}
}
print "The longest sequence starts with " . $saved . "\n";
I am trying to use iteration instead of recursion but I just can't think of how to tackle this. I am not after the code in the question, I just want some tips / hints on how to tackle this to get the same result.
I suspect I will need to use a while or an until field.
Any help would be appreciated, again I don't want the exact answer.
Update
Here is my second attempt, which is giving me an error of
Can't return outside a subroutine at answer2.pl line 38.
my $number = 0;
my $counter = 0;
while ($number != 1000) {
$counter++;
if ($number == 1) {
return $counter;
}
elsif ($number % 2 == 0) {
return ($number / 2, $counter);
}
else {
return ($number * 3 + 1, $counter);
}
$number++;
}
print "number" . $number . "counter" . $counter . "\n";
Basically you have tail recursion, which is nice and simple to eliminate.
Instead of collatz calling itself to generate the next step in the sequence, you simply change the variables in-place and loop back to the top.
In its crudest form this would be
sub collatz2 {
my ($num, $count) = #_;
NEXT:
$count++;
if ($num == 1) {
return $count;
}
elsif ($num % 2 == 0) {
$num = $num / 2;
}
else {
$num = $num * 3 + 1;
}
goto NEXT;
}
but it should be written much more nicely than that.
I ended up with this
sub collatz {
my ($num) = #_;
my $count = 1;
while ($num > 1) {
$num = $num % 2 ? $num * 3 + 1 : $num / 2;
++$count;
}
$count;
}
Consider adding the logic that returns when the condition is met in the while.
Spoiler:
my $iter = 0;
while($num != 1){ #do stuff; $iter++ }
Just use a for or while loop with the end condition that your number == 1.
Spoiler:
use strict;
use warnings;
my $max_num = 0;
my $max_steps = 0;
for my $num (1..1000) {
my $steps = 0;
for (my $i = $num; $i != 1; $steps++) {
$i = $i % 2 ? 3 * $i + 1 : $i / 2;
}
print "Num: " . $num . " Length: " . $steps . "\n";
if ($steps > $max_steps) {
$max_num = $num;
$max_steps = $steps;
}
}
print "The longest sequence starts with " . $max_num . "\n";