shell:自定义数基算术
shell: arithmetic with custom number bases
我必须编写一个命令行,在两个不同的自定义基础中输入两个数字,并在第三个基础中输出。
自定义基础,我的意思是我有这样的东西:
- 输入基数1:"!?\
- 输入基数 2:ajedpoi
- 输出:rAfeB oiX
所以从那开始我猜 bc
没有帮助,对吧?
是否有这样的命令,或者我应该编写一些自定义脚本吗?你能给我一些线索吗?我完全迷路了。
编辑:练习的确切说明是:
Write a command line that takes numbers from variables FT_NBR1, in
’"?! base, and FT_NBR2, in mrdoc base, and displays the sum of both
in gtaio luSnemf base.
以具有以下值的方式:
FT_NBR1=\'?"\"'\
FT_NBR2=rcrdmddd
我会得到以下输出:
Salut
如何将字符串 789
转换为数字?
嗯,789等于
7×102+8×101+9×100
但是我们正在编写一个程序,我们希望利用循环。
( ( 7 ) × 10 + 8 ) × 10 + 9
更好的是,
( ( ( 0 ) × 10 + 7 ) × 10 + 8 ) × 10 + 9
我们不以数字 7
、8
和 9
开头,而是以它们的字符串表示形式开头。
(
(
(
0
) × 10 + [ offset of "7" in "0123456789" ]
) × 10 + [ offset of "8" in "0123456789" ]
) × 10 + [ offset of "9" in "0123456789" ]
最后,让我们消除对基数 10 的最后一点依赖。
(
(
(
0
) × [ number of symbols in "0123456789" ] + [ offset of "7" in "0123456789" ]
) × [ number of symbols in "0123456789" ] + [ offset of "8" in "0123456789" ]
) × [ number of symbols in "0123456789" ] + [ offset of "9" in "0123456789" ]
所以代码看起来像这样:
- 将
n
设置为 0。
- 设置
base
为基数中的符号数。
- 对于每个数字,
- 设置
n
为n
和base
相乘的结果。
- 获取组成基数的符号数组中数字的偏移量。
- 设置
n
为n
和偏移量相加的结果。
示例 Perl 实现:
my @syms = split //, "01234567890";
my %sym_offset = map { $syms[$_] => $_ } 0 .. $#syms;
my $s = "...";
my $n = 0;
for my $sym ( split //, $s ) {
my $offset = $sym_offset{ $sym };
$n = $n * @syms + $offset;
}
$s = $syms[ 0 ] if !length( $s );
say $n;
这个过程的反面可以取一个数字并将其转换为基数。不是重复乘法,而是重复除法,使用余数作为构成基数的符号列表的索引。
- 设置
base
为基数中的符号数。
- 将
s
设置为空字符串。
- 虽然
n
大于零,
- 求
n
除以 base
的余数。
- 获取在偏移量等于余数的符号。
- 将符号添加到
s
。
- 设置
n
为n
减去余数的结果。
- 将
n
设为n
除以base
的结果。
- 如果
s
是一个空字符串,
- 将
s
设置为第一个符号。
示例 Perl 实现:
my @syms = split //, "01234567890";
my %sym_offset = map { $syms[$_] => $_ } 0 .. $#syms;
my $n = ...;
my $s = "";
while ( $n ) {
my $offset = $n % @syms;
$s = $syms[ $offset ] . $s;
$n = ( $n - $offset ) / @syms;
}
say $n;
好吧,我还不够聪明。我可以只用 tr
和 bc
我使用 tr
将奇怪的“基数”和 bc
与正常数字相互转换。
这是我所做的:
#!/bin/sh
NUM1=$(echo "$FT_NBR1" | tr \'\\\"\?\! '01234')
NUM2=$(echo "$FT_NBR2" | tr mrdoc '01234')
RES=$(echo "obase=13; ibase=5; $NUM1 + $NUM2" | bc)
echo $RES | tr '0123456789abc' 'gtaio luSnemf'
我必须编写一个命令行,在两个不同的自定义基础中输入两个数字,并在第三个基础中输出。
自定义基础,我的意思是我有这样的东西:
- 输入基数1:"!?\
- 输入基数 2:ajedpoi
- 输出:rAfeB oiX
所以从那开始我猜 bc
没有帮助,对吧?
是否有这样的命令,或者我应该编写一些自定义脚本吗?你能给我一些线索吗?我完全迷路了。
编辑:练习的确切说明是:
Write a command line that takes numbers from variables FT_NBR1, in ’"?! base, and FT_NBR2, in mrdoc base, and displays the sum of both in gtaio luSnemf base.
以具有以下值的方式:
FT_NBR1=\'?"\"'\
FT_NBR2=rcrdmddd
我会得到以下输出:
Salut
如何将字符串 789
转换为数字?
嗯,789等于
7×102+8×101+9×100
但是我们正在编写一个程序,我们希望利用循环。
( ( 7 ) × 10 + 8 ) × 10 + 9
更好的是,
( ( ( 0 ) × 10 + 7 ) × 10 + 8 ) × 10 + 9
我们不以数字 7
、8
和 9
开头,而是以它们的字符串表示形式开头。
(
(
(
0
) × 10 + [ offset of "7" in "0123456789" ]
) × 10 + [ offset of "8" in "0123456789" ]
) × 10 + [ offset of "9" in "0123456789" ]
最后,让我们消除对基数 10 的最后一点依赖。
(
(
(
0
) × [ number of symbols in "0123456789" ] + [ offset of "7" in "0123456789" ]
) × [ number of symbols in "0123456789" ] + [ offset of "8" in "0123456789" ]
) × [ number of symbols in "0123456789" ] + [ offset of "9" in "0123456789" ]
所以代码看起来像这样:
- 将
n
设置为 0。 - 设置
base
为基数中的符号数。 - 对于每个数字,
- 设置
n
为n
和base
相乘的结果。 - 获取组成基数的符号数组中数字的偏移量。
- 设置
n
为n
和偏移量相加的结果。
- 设置
示例 Perl 实现:
my @syms = split //, "01234567890";
my %sym_offset = map { $syms[$_] => $_ } 0 .. $#syms;
my $s = "...";
my $n = 0;
for my $sym ( split //, $s ) {
my $offset = $sym_offset{ $sym };
$n = $n * @syms + $offset;
}
$s = $syms[ 0 ] if !length( $s );
say $n;
这个过程的反面可以取一个数字并将其转换为基数。不是重复乘法,而是重复除法,使用余数作为构成基数的符号列表的索引。
- 设置
base
为基数中的符号数。 - 将
s
设置为空字符串。 - 虽然
n
大于零,- 求
n
除以base
的余数。 - 获取在偏移量等于余数的符号。
- 将符号添加到
s
。 - 设置
n
为n
减去余数的结果。 - 将
n
设为n
除以base
的结果。
- 求
- 如果
s
是一个空字符串,- 将
s
设置为第一个符号。
- 将
示例 Perl 实现:
my @syms = split //, "01234567890";
my %sym_offset = map { $syms[$_] => $_ } 0 .. $#syms;
my $n = ...;
my $s = "";
while ( $n ) {
my $offset = $n % @syms;
$s = $syms[ $offset ] . $s;
$n = ( $n - $offset ) / @syms;
}
say $n;
好吧,我还不够聪明。我可以只用 tr
和 bc
我使用 tr
将奇怪的“基数”和 bc
与正常数字相互转换。
这是我所做的:
#!/bin/sh
NUM1=$(echo "$FT_NBR1" | tr \'\\\"\?\! '01234')
NUM2=$(echo "$FT_NBR2" | tr mrdoc '01234')
RES=$(echo "obase=13; ibase=5; $NUM1 + $NUM2" | bc)
echo $RES | tr '0123456789abc' 'gtaio luSnemf'