I have written the following code in PowerShell to display the permutation and combination for the given string but I am not able to achieve it by recursive functions.
function Swapping1 {
$a = "abc"
$b = $a.ToCharArray()
$c = $b.Length-1
$d = 0
GetPer($b, $d, $c)
}
function GetPer {
Param($list, $k, $m)
[char[]] $list1 = $list[0]
$k = $list[1]
$m = $list[2]
if ($k -eq $m) {
# Write-Host $list1
} else {
for ($i = $k; $i -le 1; $i++) {
$a = $list1[$k]
$b = $list1[$i]
$a, $b = $b, $a
$k = $k+1
Write-Host $list[0]
GetPer($list[0], $k, $m)
$a, $b = $b, $a
}
}
}
The same logic when I write it in C# it is working fine.
private static void Swap(ref char a, ref char b) {
if (a == b) return;
a ^= b;
b ^= a;
a ^= b;
}
private static void GetPermutation(char[] list, int k, int m) {
if (k == m) {
Console.Write(list);
Console.WriteLine();
} else
for (int i = k; i <= m; i++) {
Swap(ref list[k], ref list[i]);
GetPermutation(list, k + 1, m);
Swap(ref list[k], ref list[i]);
}
}
static void Main(string[] args) {
string str = "abc";
char[] arr = str.ToCharArray();
int x = arr.Length - 1;
GetPermutation(arr, 0, x);
//GetPer(arr);
Console.Read();
}
Below is the output when I executed the PowerShell script:
PS C:\WINDOWS\system32> C:\Dorababu\Power Shell\Swapping1.ps1
a b c
a b c
a b c
C# output:
Your C# and PowerShell code do different things. You output at a different place in PowerShell, the condition in the for loop is different ($i -le 1 vs i <= m), you increment $k in the PowerShell code ($k = $k+1) but not in the C# code, and your swapping as well as the parameter handling are completely wrong. A function call foo(a, b, c) passes an array a, b, c to the first parameter of foo() and nothing to the second and third parameter. The correct way to call foo() with three parameters a, b, and c in PowerShell would be foo a b c. And for swapping array elements simply use the array elements. Don't assign them to variables first.
If you actually implement the same logic the PowerShell code works as expected:
function Swapping1 {
$a = "abc"
$b = $a.ToCharArray()
$c = $b.Length-1
$d = 0
GetPer $b $d $c
}
function GetPer {
Param($list, $k, $m)
if ($k -eq $m) {
Write-Host $list
} else {
for ($i = $k; $i -le $m; $i++) {
$list[$k], $list[$i] = $list[$i], $list[$k]
GetPer $list ($k+1) $m
$list[$k], $list[$i] = $list[$i], $list[$k]
}
}
}
Swapping1
Related
I want to convert Roman Numbers into Decimal Numbers Like:
"MCMVII" = 1907;
"MMCDXLVII" = 2447;
"MMCMLXXXIV" = 2984;
"MXCVI" = 1096;
"MCMIV" = 1904;
"MMDII" = 2502;
"M" = 1000;
"MMDLXXIX" = 2579;
"MMMLXXXVIII" = 3088;
"MMDCCXCIX" = 2799;
"MMDVI" = 2506;
"MMMDCCLVII" = 3757;
"MMMCCLXXXIII" = 3283;
"MCDXL" = 1440;
"MMD" = 2500;
"DCLI" = 651;
Can someone help me with this? I am struggling from where to start??
There are good hints in the comments, but neither bluuf's helpful recipe nor the implementations pointed to Lee_Dailey amount to robust implementations.
A robust implementation that rules out syntactically invalid Roman numerals is surprisingly complex - find function ConvertFrom-RomanNumeral in the bottom section.
Applied to your sample values, you'll get the corresponding decimal numbers as shown in your question:
#(
"MCMVII"
"MMCDXLVII"
"MMCMLXXXIV"
"MXCVI"
"MCMIV"
"MMDII"
"M"
"MMDLXXIX"
"MMMLXXXVIII"
"MMDCCXCIX"
"MMDVI"
"MMMDCCLVII"
"MMMCCLXXXIII"
"MCDXL"
"MMD"
"DCLI"
) | ConvertFrom-RomanNumeral
A helpful online resource is the Roman Numerals Converter, which offers conversion both to and from Roman numerals.
ConvertFrom-RomanNumeral source code:
Any syntactically invalid Roman numeral results in a non-terminating error - do let us know if I missed any cases.
No limit is placed on the number of M digits (each representing 1000) in a row.
function ConvertFrom-RomanNumeral {
param(
[Parameter(Mandatory, ValueFromPipeline)]
[string] $RomanNumeral
)
begin {
function toValue {
param ([string] $RomanNumeral, [int] $i)
if ($i -ge $RomanNumeral.Length) { return $null }
$value = #{
[char] 'i' = 1
[char] 'v' = 5
[char] 'x' = 10
[char] 'l' = 50
[char] 'c' = 100
[char] 'd' = 500
[char] 'm' = 1000
}[[char]::ToLower($RomanNumeral[$i])]
if (-not $value) {
throw "Cannot convert '$RomanNumeral': not a Roman digit: '$($RomanNumeral[$i])'"
}
$value # output
}
}
process {
$num = 0; $maxDigitSoFar = 1001; $prevValue = 0
for ($i = 0; $i -lt $RomanNumeral.Length; ++$i) {
try {
$value = toValue $RomanNumeral $i
if ($isMultiDigitRun = $value -eq $prevValue) { # Check for too many digits in a row.
++$runCount
if ($value -ne 1000 -and $runCount -gt 3) { throw "Cannot convert '$RomanNumeral': no more than 3 digits other than M allowed in sequence." }
if ($value -in 5, 50, 500) { throw "Cannot convert '$RomanNumeral': V, L, and D cannot be repeated." }
} else {
$runCount = 1
}
if (($nextValue = toValue $RomanNumeral ($i + 1)) -gt $value) { # A subtraction, such as IV
$isValid = switch ($value) { # Verify that the next digit is valid; V, L, D cannot be used in subtractions.
1 { $nextValue -in 5, 10; break } # IV, IX
10 { $nextValue -in 50, 100; break } # XL, XC
100 { $nextValue -in 500, 1000; break } # CD, CM
}
if (-not $isValid) { throw "Cannot convert '$RomanNumeral': invalid subtraction sequence: '$($RomanNumeral[$i])$($RomanNumeral[$i+1])'" }
$isValid = $nextValue -le $maxDigitSoFar # Also check if the digit is too high.
++$i # Skip the next digit, given that we've just processed it.
$prevValue = 0 # Signal that the next digit is by definition not part of a run.
$maxDigitSoFar = $value # Signal that this digit must not be used again later, except in another subtraction.
$value = $nextValue - $value
}
else { # A stand-alone digit.
$isValid = $isMultiDigitRun -or $value -lt $maxDigitSoFar
$prevValue = $value
$maxDigitSoFar = $value
}
if (-not $isValid) { throw "Cannot convert '$RomanNumeral': digits not in expected order." }
$num += $value
}
catch {
Write-Error "$_"; return
}
}
$num # output
}
}
To complement the answer from #mklement0 and taking the complexity away by seeing each decimal number as a roman numeral pattern that represent the numbers 1 to 9. Note here that (as some other ancient number systems) roman numerals don't have/require zeros (M000 ➔ M equals 1000) as each roman number is unique to its own bound value:
function ConvertFrom-RomanNumeral {
param(
[Parameter(Mandatory, ValueFromPipeline)]
[string] $RomanNumeral
)
begin {
$1 = 'i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix'
$10 = 'x', 'xx', 'xxx', 'xl', 'l', 'lx', 'lxx', 'lxxx', 'xc'
$100 = 'c', 'cc', 'ccc', 'cd', 'd', 'dc', 'dcc', 'dccc', 'cm'
$Pattern = "^(m*)($($100 -Join '|'))?($($10 -Join '|'))?($($1 -Join '|'))?$"
}
process {
if ($_ -Match $Pattern) {
$Value = if ($Matches[1]) { 1000 * $Matches[1].Length }
if ($Matches[2]) { $Value += 100 * $100.IndexOf($Matches[2].ToLower()) + 100 }
if ($Matches[3]) { $Value += 10 * $10.IndexOf($Matches[3].ToLower()) + 10 }
if ($Matches[4]) { $Value += $1.IndexOf($Matches[4].ToLower()) + 1 }
$Value
} else { throw "Cannot convert $_" }
}
}
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
}
}
I have two arrays of string data type and i am comparing those using foreach loops and raising the counter when a match is found
my #array1 = ('India');
my #array2 = ('India', 'America');
foreach my $a (#array1) {
foreach my $b (#array2) {
my $count=0;
if($a eq $b) {
$count++;
}
}
}
Now I want to use this count variable outside of its scope
if ($count > 0) {
call_some_function();
}
Where am I going wrong?
$count is declared into the foreach loop, it doesn't exist outside this loop, if you want to use $count outside the loop, simply put my $count=0 before the first foreach and remove the one into the foreach
here's what you want:
my #array1=('India');
my #array2=('India','America');
my $count=0;
foreach my $country1(#array1)
{
foreach my $country2(#array2)
{
if($country1 eq $country2)
{
$count++;
}
}
}
Declare variable outside of the loops, you've also got a typo in $count:
my $count = 0;
foreach $a (#array1) {
foreach $b (#array2) {
if ( $a eq $b ) {
$count++;
}
}
}
When ever I run this bit of code. it doesn't display any output. Anyone see anything wrong?
I am trying to display this in the out put:
A
AA
AAA
AAAB
AAABA
AAABAA
AAABAAA
AAABAAAB
etc.
#!/usr/local/bin/perl
$A = 3;
$B = 1;
$i = 1;
$output = "";
$j = 1;
while ($i <= $ARGV[0]) {
while ($j <= $i) {
if ($A == 0 && $B == 0) {
$A = 3;
$B = 1;
}
if ($A > 0) {
$output.= "A";
$A--;
}
else {
$output.= "B";
$B--;
}
$j++;
}
print($output . "\n");
$i++;
}
It works for me when I run it with a numeric argument (number of lines).
An idea how to simplify the code:
#!/usr/bin/perl
use warnings;
use strict;
my $count = shift;
my $A = 3;
my $B = 1;
my $string = q();
$string .= ('A' x $A) . ('B' x $B) while $count > length $string;
print substr($string, 0, $_), "\n" for 1 .. $count;
It uses a different algorithm - it creates the longest possible string, and then outputs parts of it.
if there is no #ARGV, while ($i <= $ARGV[0]) never runs.
#ARGV is an array of the command line arguments provided when the script is executed. you did not provide any command line arguments. if you had use warnings in effect, you would be warned that $ARGV[0] is uninitialized.
As from ikegami comment. You cann't pass the input at when the program is compile. For example, consider your file name is algo.pl. Can you run your program with
perl algo.pl 10
Here 10 is the input value of the program. In program value is retrieve by the $ARGV[0]
so in your program looks like while ($i <= $ARGV[0]).
If you want pass the several values like perl filename.pl 12 data1 data2In your data retrieve by $ARGV[0] $ARGV[1] $ARGV[2] for more information see here.
If you want pass the input at the time of execution used STDIN
use warnings;
use strict;
my $A = 3;
my $B = 1;
my $i = 1;
my $output = "";
my $j = 1;
print "Enter the value: ";
chomp(my $value = <STDIN>);
while ($i <= $value) {
while ($j <= $i) {
if ($A == 0 && $B == 0) {
$A = 3;
$B = 1;
}
if ($A > 0) {
$output.= "A";
$A--;
}
else {
$output.= "B";
$B--;
}
$j++;
}
print($output . "\n");
$i++;
}
I have a 2d array in Perl. I passed the array to a subroutine and I want to modify all elements of the 2d array then return it and print the array. I have attached my code so far below. The problem I am having is actually changing each individual element and passing the array to a subroutine.
Original Matrix+Code
x y z
CG -3.74900 -4.89100 -3.45400
OD1 -6.45900 -6.29100 -6.08000
OD2 -1.31600 -1.83300 -0.17600
sub translateMatrixOperation
{
my (#translatematrix, $x, $y, $z) = #_;
print "PRINTING FIRST\n";
my $arrsize = scalar #translatematrix;
for(my $i = 0; $i <= $arrsize; $i++)
{
for(my $j = 0; $j <= $arrsize; $j++)
{
if ($j == 0)
{
print "[$i][$j]:$translatematrix[$i][$j]\n";
$_ = $_ - $x;
}
elsif ($j == 1)
{
print "[$i][$j]:$translatematrix[$i][$j]\n";
$_ = $_ - $y;
}
elsif ($j == 2)
{
print "[$i][$j]:$translatematrix[$i][$j]\n";
$_ = $_ - $z;
}
}
}
print "PRINTING\n";
for(my $i = 0; $i <= $arrsize; $i++)
{
for(my $j = 0; $j <= $arrsize; $j++)
{
print "$translatematrix[$i][$j] ";
}
print "\n";
}
# return (\#translatematrix);
}
I want to edit the whole array by adding a constant value to the x values, a constant value to the y values, and a constant to the z. Where did I go wrong?
my (#translatematrix, $x, $y, $z) = #_;
does not make sense as #translatematrix slurps all elements from #_, and should be:
my ($translatematrix, $x, $y, $z) = #_;
where $translatematrix is array reference.
$_ = $_ - $x;
should be more like
$translatematrix->[$i][$j] -= $x;
and also similar logic to $y and $z should be applied.