Đây là một niềm vui. Tôi thích câu hỏi này. Tôi đã viết các chức năng sau đây để thực hiện nhiệm vụ và nó thực hiện công việc.
palindromes() (
rev() while getopts : o "-$1" ||
! r="${2#"${2%%[1-9]*}"}"
do set -- "$1" "$OPTARG$2"
done
rand() { : & : "$(($1=$!))"; }
[ "$1" -gt 10 ] || exit
n=$1; set --
while OPTIND=1; rev "$n"
case "$#.$n.$r" in
(100.*) ! printf '%s\t%s\t%s\t%s\t%s\n' "$@" ;;
(*.$r.$n) set -- "$@" "$n"; rand n ;;
(*) n=$((${n#-}+${r%-})) ;;
esac; do :; done
)
Có một vài điều đáng chú ý về điều này. Ở nơi đầu tiên, getopts
được sử dụng để đảo ngược số. Chức năng chính của getopts
là phân tích các tùy chọn ngắn có thể hoặc không thể kết hợp với nhau - và do đó nó tạo ra một công cụ thuận tiện để lặp qua từng byte trong một chuỗi.
Tôi không thích $RAND
chức năng của bash
shell, nhưng có lẽ nó bảo thủ hơn rand()
chức năng của tôi , nó chỉ làm nền cho một nhiệm vụ không hoạt động và gán PID không còn tồn tại của nó cho bất kỳ varname nào được lưu trữ trong đối số đầu tiên của nó. Khá rẻ, tôi sẽ thừa nhận.
Cấu case
trúc có thể dễ dàng đánh giá tất cả các khía cạnh của bài tập của bạn trong một bài kiểm tra đơn giản. Tôi làm:
case "$#.$n.$r" in
(100*) all done; printf %s\\n "$@";;
(*$r.$n) palindrome; set -- "$@" "$n";;
(*) no luck; $n+$r; go again;;
esac
Tôi đã có rất nhiều khó khăn với điều này lúc đầu. Lúc đầu, tôi đang làm những việc như:
(*$r.$n) set -- ...; n=$((n+1))
Đó là một ý tưởng tồi . Việc bổ sung bỏ trốn ngay lập tức tăng số lượng lên kích thước mà chỉ số đếm chữ số là đủ để thổi bay mọi khả năng tìm thấy một bảng màu. Tôi đã loay hoay với date +%S
nhưng tôi đoán rằng dù sao tôi cũng sẽ chạy một quy trình khác, tôi cũng có thể sử dụng bộ vi xử lý của nó. Và quá trình đó, trong trường hợp đó, cũng có thể chỉ là một null-op. Dù sao, phạm vi PID là đủ nhỏ để trị vì yếu tố chạy trốn khá nhiều lần, dường như.
Ví dụ: tôi sẽ chạy cái này ngay bây giờ và dán vào kết quả:
palindromes 76
ĐẦU RA
484 29292 49294 69296 89298
215512 50605 90609 446644 886688
123321 52625 92629 468864 663787366
134431 54645 94649 881585188 7667585634365857667
145541 23432 43434 63436 83438
147741 24442 44444 64446 84448
158851 25452 45454 65456 85458
169961 13231 46464 66466 86468
49985258994 27472 47474 67476 87478
14355341 28482 48484 68486 88488
395593 29492 49494 69496 89498
219912 121121 11244211 441144 881188
125521 165561 15522551 463364 7365409856589045637
136631 211112 17858768886785871 485584 893974888888479398
147741 23632 43634 63636 83638
149941 24642 44644 64646 84648
523325 25652 45654 65656 85658
567765 13331 46664 66666 86668
2358532 27672 47674 67676 87678
2236322 28682 48684 68686 88688
Có lẽ có một số bản sao trong đó - nó xảy ra, rõ ràng. Không nhiều. Tôi không biết đó có phải là vấn đề với bạn hay không, nhưng đây chỉ là một ví dụ về cách nó có thể được thực hiện.
Một lưu ý cuối cùng - chạy cái này dash
nhanh hơn nhiều so với nó bash
; mặc dù sự khác biệt dường như chỉ là một giây hoặc lâu hơn. Trong mọi trường hợp, nếu bạn sử dụng, dash
bạn cần thay đổi rev()
set -- "$1"
dòng thànhset -- "${1#?}".
Tôi chỉ nhận ra có một yêu cầu gồm hai chữ số - mặc dù sự nghi ngờ của tôi là quy tắc cụ thể này là một nỗ lực để giữ cho bài tập không quá khó. Dù sao, chỉ nhận được một tập hợp con của một chuỗi là rất dễ thực hiện. Trong thực tế, đó là những gì tôi làm với r=
khi tôi:
r="${2#"${2%%[1-9]*}"}"
... luôn luôn chỉ định r
một giá trị không bắt đầu bằng 0.
Đây là phiên bản rand()
luôn gán một số có hai chữ số cho $1
:
rand() { : & set -- "$1" "$!" "$(($!%100))"
: "$(($1=($3>10?$3:${#2}$3)))"
}
Bạn có thể áp dụng cùng một logic để bash
's $RAND
tất nhiên. Các $((var=(value)?(assign if true):(assign if false)))"
nhà điều hành ternary sẽ làm việc với gần như bất kỳ bộ số nguyên. Ở đây tôi chỉ định nó là modulo 100 (về cơ bản là phần trăm) nếu giá trị đó lớn hơn mười, nếu không, tôi chỉ định đó là số thứ hai của hai chữ số trong đó số thứ nhất là số của các chữ số $!
.
Chạy theo cách đó và kết quả của nó là một chút ít thú vị:
333 66 484 1111 4884
77 88 99 121 121
363 484 77 4884 44044
88 99 121 121 363
484 1111 4884 88 8813200023188
99 121 121 363 484
1111 4884 44044 8813200023188 99
44 55 66 77 44
99 121 121 363 484
424 11 33 44 55
66 77 88 99 121
22 33 22 55 66
77 88 99 121 121
33 44 55 33 77
88 99 121 121 363
44 55 66 77 44
99 121 121 363 484
55 66 77 88 99
55 121 363 484 1111
66 77 88 99 121