I need to do a script for bash to solve the word game for 8 directions. I have managed to make some code, but the last thing I am stuck on, is how to rotate the table to find the words in all directions. 90° is not a problem, but 45°... I think awk could help but I am not really good at it. Thanks.
我需要为bash做一个脚本来解决8个方向的文字游戏。我已经设法制作了一些代码,但最后我坚持的是如何旋转表格来查找所有方向的单词。 90°不是问题,但45°......我觉得awk可以提供帮助,但我并不擅长它。谢谢。
Example:
abcd efgh ijkl
=>
a eb ifc jgd kh l
Example 2:
abcde fghij klmno
=>
a fb kgc lhd mie nj o
Example 3:
abc defg hi
=>
a db hec if g
3 个解决方案
#1
$ cat tst.awk
BEGIN { FS="" }
{
for (i=1;i<=NF;i++) {
a[NR,i]=$i
}
numCols = (NF>numCols?NF:numCols)
numRows = NR
}
END {
rowNr=1
for (colNr=1;colNr<=numCols;colNr++) {
for (;rowNr<=numRows;rowNr++) {
printf "%*s", colNr-1, ""
for (delta=0;delta<rowNr;delta++) {
printf "%s%s", a[rowNr-delta,colNr+delta], (delta<(rowNr-1)?FS:RS)
}
}
rowNr=numRows
}
}
.
$ awk -f tst.awk file1
a
eb
ifc
jgd
kh
l
$
$ awk -f tst.awk file2
a
fb
kgc
lhd
mie
nj
o
$
$ awk -f tst.awk file3
a
db
hec
if
g
wrt the comments below from @JoseRicardoBustosM. suggesting that the above does not produce the desired output from one of his sample inputs, here's the suggested input4
:
以下来自@JoseRicardoBustosM的评论。建议上面没有从他的一个样本输入产生所需的输出,这是建议的输入4:
$ cat input4
Jose
y
Ricardo
y
Gloriset
and the above script run on it:
以上脚本在其上运行:
$ awk -f tst.awk input4
J
yo
Rs
yie
Gc
la
or
rd
io
s
e
t
and here's a modified script to inject blank chars when none exist IF that was the desired behavior which I think is extremely unlikely:
这里是一个修改过的脚本,当不存在时会注入空白字符如果这是我认为极不可能的所需行为:
$ cat tst2.awk
BEGIN { FS="" }
{
for (i=1;i<=NF;i++) {
a[NR,i]=$i
}
numCols = (NF>numCols?NF:numCols)
numRows = NR
}
END {
rowNr=1
for (colNr=1;colNr<=numCols;colNr++) {
for (;rowNr<=numRows;rowNr++) {
printf "%*s", colNr-1, ""
for (delta=0;delta<rowNr;delta++) {
printf "%s%s", ((rowNr-delta,colNr+delta) in a ? a[rowNr-delta,colNr+delta] : " "), (delta<(rowNr-1)?FS:RS)
}
}
rowNr=numRows
}
}
$ awk -f tst2.awk input4
J
yo
R s
yi e
G c
l a
o r
r d
i o
s
e
t
#2
I would suggest using perl
instead of awk
. Perl
is very powerful in processing texts, and the syntax is quite C
-like.
我建议使用perl而不是awk。 Perl在处理文本方面非常强大,而且语法非常像C语言。
As far as I understand what 'rotating a text by 45°' means, the following script performs such a rotation:
据我所知,“将文本旋转45°”意味着,以下脚本执行这样的旋转:
rotate_text_45.pl
:
#!/usr/bin/perl
use strict;
use warnings;
my @input = <>;
my $lines_count = scalar @input;
my $global_max_diag = 0;
for my $i (0 .. scalar @input - 1){
chomp $input[$i];
$input[$i] = [split //, $input[$i]];
my $max_diag = $i + scalar(@{$input[$i]}) - 1;
$global_max_diag = $max_diag if $max_diag > $global_max_diag;
}
for my $diag (0 .. $global_max_diag){
for my $i (0 .. $diag){
next if $diag - $i >= $lines_count;
$input[$diag - $i][$i] = ' ' unless defined $input[$diag - $i][$i];
print $input[$diag - $i][$i];
}
print "\n";
}
Assuming the input file is as follows:
假设输入文件如下:
$ cat in.txt
iftkn
iarwp
cooop
froas
blmaz
the script produces this result:
该脚本产生以下结果:
$ ./rotate_text_45.pl in.txt
i
if
cat
fork
brown
loop
map
as
z
To perform rotation by 135° or 225° I suggest rotation by 90° (180°) and then rotation by 45°.
要进行135°或225°的旋转,我建议旋转90°(180°)然后旋转45°。
#3
awk '
BEGIN{
sum = 0;
}
{
words[NR] = $0;
sum += length($0);
}
END{
cant_words = length(words);
for(i=1; i<=cant_words; i++){
flag[i] = 2-i;
}
cont_letter = 0;
row = 1;
while(cont_letter<sum){
out = "";
for(i=0; i<row-cant_words; i++){
out = out" ";
}
cont_space = 0;
for(i=cant_words; i>=1; i--){
if(flag[i] >= 1 && flag[i] <= length(words[i])){
for(j=0; j<cont_space; j++){
out=out" "
}
cont_space = 0;
out=out""substr(words[i],flag[i],1);
cont_letter = cont_letter + 1;
}else{
if(flag[i] > length(words[i])){
cont_space = cont_space + 1;
}
}
flag[i] = flag[i]+1;
}
print out;
row = row + 1;
}
}
' input
input1:
abcd efgh ijkl
output1:
a eb ifc jgd kh l
input2
abc defg hi
output2
a db hec if g
input3
abc defg hi jklm
output3
a db hec jif k g l m
input4
Jose y Ricardo y Gloriset
output4
J yo R s yi e G c l a o r r d i o s e t
#1
$ cat tst.awk
BEGIN { FS="" }
{
for (i=1;i<=NF;i++) {
a[NR,i]=$i
}
numCols = (NF>numCols?NF:numCols)
numRows = NR
}
END {
rowNr=1
for (colNr=1;colNr<=numCols;colNr++) {
for (;rowNr<=numRows;rowNr++) {
printf "%*s", colNr-1, ""
for (delta=0;delta<rowNr;delta++) {
printf "%s%s", a[rowNr-delta,colNr+delta], (delta<(rowNr-1)?FS:RS)
}
}
rowNr=numRows
}
}
.
$ awk -f tst.awk file1
a
eb
ifc
jgd
kh
l
$
$ awk -f tst.awk file2
a
fb
kgc
lhd
mie
nj
o
$
$ awk -f tst.awk file3
a
db
hec
if
g
wrt the comments below from @JoseRicardoBustosM. suggesting that the above does not produce the desired output from one of his sample inputs, here's the suggested input4
:
以下来自@JoseRicardoBustosM的评论。建议上面没有从他的一个样本输入产生所需的输出,这是建议的输入4:
$ cat input4
Jose
y
Ricardo
y
Gloriset
and the above script run on it:
以上脚本在其上运行:
$ awk -f tst.awk input4
J
yo
Rs
yie
Gc
la
or
rd
io
s
e
t
and here's a modified script to inject blank chars when none exist IF that was the desired behavior which I think is extremely unlikely:
这里是一个修改过的脚本,当不存在时会注入空白字符如果这是我认为极不可能的所需行为:
$ cat tst2.awk
BEGIN { FS="" }
{
for (i=1;i<=NF;i++) {
a[NR,i]=$i
}
numCols = (NF>numCols?NF:numCols)
numRows = NR
}
END {
rowNr=1
for (colNr=1;colNr<=numCols;colNr++) {
for (;rowNr<=numRows;rowNr++) {
printf "%*s", colNr-1, ""
for (delta=0;delta<rowNr;delta++) {
printf "%s%s", ((rowNr-delta,colNr+delta) in a ? a[rowNr-delta,colNr+delta] : " "), (delta<(rowNr-1)?FS:RS)
}
}
rowNr=numRows
}
}
$ awk -f tst2.awk input4
J
yo
R s
yi e
G c
l a
o r
r d
i o
s
e
t
#2
I would suggest using perl
instead of awk
. Perl
is very powerful in processing texts, and the syntax is quite C
-like.
我建议使用perl而不是awk。 Perl在处理文本方面非常强大,而且语法非常像C语言。
As far as I understand what 'rotating a text by 45°' means, the following script performs such a rotation:
据我所知,“将文本旋转45°”意味着,以下脚本执行这样的旋转:
rotate_text_45.pl
:
#!/usr/bin/perl
use strict;
use warnings;
my @input = <>;
my $lines_count = scalar @input;
my $global_max_diag = 0;
for my $i (0 .. scalar @input - 1){
chomp $input[$i];
$input[$i] = [split //, $input[$i]];
my $max_diag = $i + scalar(@{$input[$i]}) - 1;
$global_max_diag = $max_diag if $max_diag > $global_max_diag;
}
for my $diag (0 .. $global_max_diag){
for my $i (0 .. $diag){
next if $diag - $i >= $lines_count;
$input[$diag - $i][$i] = ' ' unless defined $input[$diag - $i][$i];
print $input[$diag - $i][$i];
}
print "\n";
}
Assuming the input file is as follows:
假设输入文件如下:
$ cat in.txt
iftkn
iarwp
cooop
froas
blmaz
the script produces this result:
该脚本产生以下结果:
$ ./rotate_text_45.pl in.txt
i
if
cat
fork
brown
loop
map
as
z
To perform rotation by 135° or 225° I suggest rotation by 90° (180°) and then rotation by 45°.
要进行135°或225°的旋转,我建议旋转90°(180°)然后旋转45°。
#3
awk '
BEGIN{
sum = 0;
}
{
words[NR] = $0;
sum += length($0);
}
END{
cant_words = length(words);
for(i=1; i<=cant_words; i++){
flag[i] = 2-i;
}
cont_letter = 0;
row = 1;
while(cont_letter<sum){
out = "";
for(i=0; i<row-cant_words; i++){
out = out" ";
}
cont_space = 0;
for(i=cant_words; i>=1; i--){
if(flag[i] >= 1 && flag[i] <= length(words[i])){
for(j=0; j<cont_space; j++){
out=out" "
}
cont_space = 0;
out=out""substr(words[i],flag[i],1);
cont_letter = cont_letter + 1;
}else{
if(flag[i] > length(words[i])){
cont_space = cont_space + 1;
}
}
flag[i] = flag[i]+1;
}
print out;
row = row + 1;
}
}
' input
input1:
abcd efgh ijkl
output1:
a eb ifc jgd kh l
input2
abc defg hi
output2
a db hec if g
input3
abc defg hi jklm
output3
a db hec jif k g l m
input4
Jose y Ricardo y Gloriset
output4
J yo R s yi e G c l a o r r d i o s e t