Đến nội dung


Hình ảnh
* * * * - 7 Bình chọn

[Hỏi]Đố vui với LISP


  • Please log in to reply
391 replies to this topic

#161 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5449 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 19 October 2011 - 02:19 PM

Cái lợi của while bạn DOAN VAN HA đã nói đúng nhưng với bài toán đề ra thì dùng repeat đúng hơn vì nhanh hơn đó là lý do vì sao repeat vẫn tồn tại song song với while.
phần code của bạn nếu thêm (exit) khi ok =0 thì sao?
theo lý thuyết là thế nhưng chưa test với lisp. bạn nào đã test thì cho xin cái đáp án.
Thanks!

1). Có trường hợp không thể dùng while được nên nó mới tồn tại // 2 thằng (hay chính xác là dùng while không tiện bằng repeat).
2). Trong bài toán: nếu thêm exit khi ok với repeat thì nó lỗi ngay, còn khi thêm đ/k (while (or (...) (/= ok 0)) thì nó dừng lại êm đềm khi ok=0.
3). Dùng while nhanh hơn repeat ở bài toán tổng quát chứ (lặp 1 vòng và lặp 999 vòng mà).
  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#162 gia_bach

gia_bach

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 1436 Bài viết
Điểm đánh giá: 1426 (rất tốt)

Đã gửi 19 October 2011 - 02:23 PM

Cái lợi của while bạn DOAN VAN HA đã nói đúng nhưng với bài toán đề ra thì dùng repeat đúng hơn vì nhanh hơn đó là lý do vì sao repeat vẫn tồn tại song song với while.
phần code của bạn nếu thêm (exit) khi ok =0 thì sao?
theo lý thuyết là thế nhưng chưa test với lisp. bạn nào đã test thì cho xin cái đáp án.
Thanks!

theo lý thuyết là thế nhưng ...
Có thể tôi chưa biết hết các hàm Lisp nhưng LISP không có hàm cho phép exit trong vòng lặp Repeat.
Hàm Exit hay Quit của Lisp thoát luôn khỏi ứng dụng.
(Các ngôn ngữ khác thì có vd : Break, Continue, Goto, Exit ... để thoát khỏi vòng lặp)
(defun c:test()
(setq i 0)
(repeat 5
(setq i (1+ i))
;(if (= i 2) (exit)) ;(quit))
)
(princ i) (princ ))

  • 1

#163 npham

npham

    biết lệnh rotate

  • Members
  • PipPipPip
  • 136 Bài viết
Điểm đánh giá: 75 (tàm tạm)

Đã gửi 19 October 2011 - 04:45 PM

Muốn thoát khoải vòng lặp rẻpeat thì dùng mẹo thôi

(defun c:test()
(setq i 0)
(repeat 5
(setq i (1+ i))
(if (= i 2)(setq i 5))
)
(princ i)
(princ )
)
  • 1

#164 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6009 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 19 October 2011 - 04:51 PM


Trời !!! Sao hay vậy ta. Két chỉ giáo thêm về cái giải thuật này đuwocj không, lạ quá, đọc hoài không hiểu Hình đã gửi

Hề hề hề,
Sau khi gặm cái món "độc hơn thịt chuột" này của bác ketxu, với cái trình độ học mót của mình thì vỡ ra được mấy thứ như sau, đúng sai mong các bác tận tình chỉ dạy thêm hè:
1/- Cái hàm (cons 'list lst) của Ketxu trả về một list là (LIST (1 2 3 4) (A B C D) (5 6 7 8))
2/- Vậy nên khi dùng hàm (apply 'mapcar (cons 'list lst)) nghĩa là áp dụng cái hàm mapcar cho cái list (LIST (1 2 3 4) (A B C D) (5 6 7 8))
Vấn đề độc ở dây chính là cái cách dùng thằng mapcar này vì theo cú pháp thì hàm mapcar phải sử dụng một function cho các list đi kèm nhưng ở đây chả thấy cái function nào cả.
Hề hề hề,
Nếu dùng (mapcar 'list '(1 2 3 4) '(a b c d) '(5 6 7 8)) tức là sử sụng hàm list cho các danh sách '(1 2 3 4), '(a b c d), '(5 6 7 8) thì nó sẽ trả về cái list mà bác Npham mong muốn.
Từ đó mình luận theo kiểu củ chuối rằng khi áp dụng cái hàm mapcar với cái list (LIST (1 2 3 4) (A B C D) (5 6 7 8)) có nghĩa rằng sẽ áp dụng cái hàm list với các danh sách '(1 2 3 4), '(a b c d), '(5 6 7 8) như đã nói ở trên.

Để thẩm định lại cái hiểu của mình, mình đã thay '(a b c d) bằng '(2 3 4 5) và dùng hàm + thay cho hàm list thì thấy kết quả như sau:
(mapcar '+ '(1 2 3 4) '(2 3 4 5) '(5 6 7 8)) trả về list (8 11 14 17)

(apply 'mapcar (cons '+ (list '(1 2 3 4) '(2 3 4 5) '(5 6 7 8)))) củng trả về list (8 11 14 17)
Từ đó mình rút ra cái kết luận tù mù rằng: cái độc của bác ketxu ở đây chính là nhét cái function của hàm mapcar vào bên trong cái list của hàm apply nhờ hàm cons.

Độc thiệt , độc thiệt, chả biết món thuốc mình vừa tìm có giải được cái độc đó không hè?????
Kính mong các bác rộng ..... miệng chỉ bảo thêm.
Hề hề hề,....
  • 1
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#165 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6009 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 19 October 2011 - 04:58 PM

Muốn thoát khoải vòng lặp rẻpeat thì dùng mẹo thôi

(defun c:test()
(setq i 0)
(repeat 5
(setq i (1+ i))
(if (= i 2)(setq i 5))
)
(princ i)
(princ )
)

Hề hề hề,
Mặc kệ cái mẹo của bác nhưng đã dùng repeat thì nó cứ phải lặp đủ 5 phát bác ạ. Không tín bác thử xem nhé. Sau khi test cái thằng i của bác nó là 8 chứ có dừng ở 5 đâu ạ.
Hề hề hề,....
Giá mà bác dùng while thì ắt nó sẽ dừng đúng chỗ bác cấn.....
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#166 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 19 October 2011 - 05:58 PM

nhét cái function của hàm mapcar vào bên trong cái list của hàm apply nhờ hàm cons.

Bác Bình quả thật tinh ý ^^
Apply 'function '('a 'b 'c ..) => (function 'a 'b 'c ..)
Function ở đây là mapcar, phần tử đầu là 'list (mà ta append vào nhờ cons), ta lại được :
(mapcar 'list 'c 'b ..) => ra kết quả như bác đã phân tích :

Nếu dùng (mapcar 'list '(1 2 3 4) '(a b c d) '(5 6 7 8)) tức là sử sụng hàm list cho các danh sách '(1 2 3 4), '(a b c d), '(5 6 7 8) thì nó sẽ trả về cái list mà bác Npham mong muốn.


  • 0

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#167 Detailing

Detailing

    biết lệnh imageclip

  • Members
  • PipPipPipPipPipPipPip
  • 667 Bài viết
Điểm đánh giá: 278 (khá)

Đã gửi 19 October 2011 - 09:32 PM

theo lý thuyết là thế nhưng ...
Có thể tôi chưa biết hết các hàm Lisp nhưng LISP không có hàm cho phép exit trong vòng lặp Repeat.
Hàm Exit hay Quit của Lisp thoát luôn khỏi ứng dụng.
(Các ngôn ngữ khác thì có vd : Break, Continue, Goto, Exit ... để thoát khỏi vòng lặp)

(defun c:test()
(setq i 0)
(repeat 5
(setq i (1+ i))
;(if (= i 2) (exit)) ;(quit))
)
(princ i) (princ ))

Cám ơn bạn Gia_bach đã có giải thích về hàm (exit) của lisp. Mình ko rành cái món này nên chỉ góp ý theo phần hiểu biết ít ỏi thôi.


1). Có trường hợp không thể dùng while được nên nó mới tồn tại // 2 thằng.
2). Trong bài toán: nếu thêm exit khi ok với repeat thì nó lỗi ngay, còn khi thêm đ/k (while (or (...) (/= ok 0)) thì nó dừng lại êm đềm khi ok=0.
3). Dùng while nhanh hơn repeat ở bài toán tổng quát chứ (lặp 1 vòng và lặp 999 vòng mà).


1. Bạn Doan Van Ha có thể cho mình 1 ví dụ về việc ko dùng repeat dc ko?
2. Nếu bị lỗi bạn đã tìm hiểu lỗi do đâu chưa?
3. while chạy 1 vòng chậm hơn repeat ở chỗ phải kiểm tra điều kiện lặp. biến kiểm tra là biến ngoài thân hàm -> truy xuất lâu hơn, v.v..

Thanks all!
  • 0

Ideas don't matter, execution does!

1908412_308002392716743_8165279281236341


#168 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5449 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 19 October 2011 - 10:01 PM

Cám ơn bạn Gia_bach đã có giải thích về hàm (exit) của lisp. Mình ko rành cái món này nên chỉ góp ý theo phần hiểu biết ít ỏi thôi.




1. Bạn Doan Van Ha có thể cho mình 1 ví dụ về việc ko dùng repeat dc ko?
2. Nếu bị lỗi bạn đã tìm hiểu lỗi do đâu chưa?
3. while chạy 1 vòng chậm hơn repeat ở chỗ phải kiểm tra điều kiện lặp. biến kiểm tra là biến ngoài thân hàm -> truy xuất lâu hơn, v.v..

Thanks all!

Tôi có thể trả lời được 2 câu hỏi đầu của bạn. Còn câu 3, tôi nói rằng riêng trong bài toán đố vui này thì dùng while tốt hơn, và đã ví dụ 1 với 999. Tôi không thích tranh cãi kiểu thách đố, mong bạn hiểu, nhất là khi chúng ta cùng góp tay xây dựng CV. Còn bạn nếu muốn, đồng thời không ai ý kiến gì thì lúc đó lại là chuyện khác.
Thân thương!
  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#169 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 19 October 2011 - 10:27 PM

Cám ơn bạn Gia_bach đã có giải thích về hàm (exit) của lisp. Mình ko rành cái món này nên chỉ góp ý theo phần hiểu biết ít ỏi thôi.




1. Bạn Doan Van Ha có thể cho mình 1 ví dụ về việc ko dùng repeat dc ko?
2. Nếu bị lỗi bạn đã tìm hiểu lỗi do đâu chưa?
3. while chạy 1 vòng chậm hơn repeat ở chỗ phải kiểm tra điều kiện lặp. biến kiểm tra là biến ngoài thân hàm -> truy xuất lâu hơn, v.v..

Thanks all!

1. Ta thường dùng repeat trong trường hợp biết trước số vòng lặp :) còn while thì thường khi chưa biết số lượng lặp và ta phải xử lý luôn kết quả sau mỗi bước lặp
Ví dụ đơn giản để princ số a đến khi người dùng không nhập nữa

(while (setq a (getint)) (princ a))

Ta sẽ không biết người dùng sẽ nhập bao nhiêu số a. Nó khác với việc nhập hết tất cả các số a rồi sau đó dùng hàm repeat
2. Trong ngôn ngữ lisp, khi repeat, số lần lặp chỉ được tính 1 lần duy nhất vào vòng lặp đầu tiên.
Ví dụ :

(defun c:test()
(setq i 5 j 0)
(repeat (1- i)
(setq j (1+ j))
(if (= j 2)(setq i 1))
(princ j)
)
(princ )
)

3. Repeat cũng phải thực hiện 2 phép tính mặc định sau mỗi vòng lặp : 1 là tăng biến đếm (1+ ), 2 là kiểm tra kết quả này với giới hạn số vòng lặp. Trong 1 số trường hợp, dù thực hiện vùng số vòng lặp tương đương, nếu điều kiện kiểm tra của While đơn giản hơn 2 phép tính trên thì while sẽ nhanh hơn
  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#170 Detailing

Detailing

    biết lệnh imageclip

  • Members
  • PipPipPipPipPipPipPip
  • 667 Bài viết
Điểm đánh giá: 278 (khá)

Đã gửi 19 October 2011 - 10:59 PM

Tôi có thể trả lời được 2 câu hỏi đầu của bạn. Còn câu 3, tôi nói rằng riêng trong bài toán đố vui này thì dùng while tốt hơn, và đã ví dụ 1 với 999. Tôi không thích tranh cãi kiểu thách đố, mong bạn hiểu, nhất là khi chúng ta cùng góp tay xây dựng CV. Còn bạn nếu muốn, đồng thời không ai ý kiến gì thì lúc đó lại là chuyện khác.
Thân thương!

Sorry nếu làm phật lòng bạn, thật sự mình ko có ý thách đố hay gì cả, chỉ muốn hiểu rõ hơn vấn đề thôi.
Sau một hồi tìm hiểu thì cái error đó là do bản thân trình biên dịch lisp gây ra do cách load của lisp ("List Processing") và đó cũng chính là nguyên nhân ko có hàm nào để thoát khỏi while hay repeat.

@Ket: Do đặc thù của lisp (đã nói ở trên) nên Ket ko nhận thấy sự khác biệt của repeat và while nhưng nếu ket có ý định nghiên cứu các ngôn ngữ khác thì nó có khác biệt "chút chút" đấy.
ngoài ra còn vài thứ như
if () else <> cond (select case/switch case/..) về memory
array <> list (static array <> dynamic array) về memory + speed
và nhiều thứ nữa.
Mọi ý kiến của mình chỉ mong các bạn chỉ cho những chỗ sai ko hề có ý thách đố mong các bạn hiểu cho.

p/s: em thấy có hàm (vl-exit-with-value) nhưng ko biết cách dùng, bác nào có nhã ý giúp thì em xin trong topic khác kẻo làm loãng topic này.
Thân!
  • 1

Ideas don't matter, execution does!

1908412_308002392716743_8165279281236341


#171 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 19 October 2011 - 11:12 PM

@detailing : :) While thì phải có thoát chứ :) Hì hì. Ketxu cũng chưa hiểu sau bài phân tích ngắn sự khác nhau giữa repeat Detail nói
Do đặc thù của lisp (đã nói ở trên) nên Ket ko nhận thấy sự khác biệt của repeat và while nghĩa mần răng ^^

So với các ngôn ngữ khác thì Ketxu thấy lisp khá lỏng lẻo, tuy nhiên, cũng từ cái lỏng lẻo này mà ta luôn luôn có những mẹo và khám phá rất mới ^^ Ngoài ra, với đặc thù luôn trả về giá trị trong 1 cặp biểu thức, ta có thể lạm dụng để rút ngắn rất nhiều thứ. Nếu lisp mà hỗ trợ phần dialog như các ngôn ngữ NET thì...
Ketxu cũng muốn học Net quá, mà thấy ngại nhất khoản máy mình chạy máy người không chạy, các bản Ref dll khác nhau, nên mặc dù thấy ham mà cứ chần chừ mãi tháng này qua tháng khác
  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#172 Detailing

Detailing

    biết lệnh imageclip

  • Members
  • PipPipPipPipPipPipPip
  • 667 Bài viết
Điểm đánh giá: 278 (khá)

Đã gửi 19 October 2011 - 11:24 PM

@detailing : :) While thì phải có thoát chứ :) Hì hì. Ketxu cũng chưa hiểu sau bài phân tích ngắn sự khác nhau giữa repeat Detail nói
Do đặc thù của lisp (đã nói ở trên) nên Ket ko nhận thấy sự khác biệt của repeat và while nghĩa mần răng ^^

So với các ngôn ngữ khác thì Ketxu thấy lisp khá lỏng lẻo, tuy nhiên, cũng từ cái lỏng lẻo này mà ta luôn luôn có những mẹo và khám phá rất mới ^^ Ngoài ra, với đặc thù luôn trả về giá trị trong 1 cặp biểu thức, ta có thể lạm dụng để rút ngắn rất nhiều thứ. Nếu lisp mà hỗ trợ phần dialog như các ngôn ngữ NET thì...
Ketxu cũng muốn học Net quá, mà thấy ngại nhất khoản máy mình chạy máy người không chạy, các bản Ref dll khác nhau, nên mặc dù thấy ham mà cứ chần chừ mãi tháng này qua tháng khác

lisp (list processing) nghĩa là load hết vào sau đó thực hiện các lệnh theo trình tự từ đầu đến cuối nếu có sự cố giữa đường sẽ sinh ra *error*
file acdbmgd của AutoCAD ko thay đổi theo từng phiên bản như mọi người nghĩ nó bao gồm 2000, 2004, 2007, 2010 tuy nhiên các phiên bản CAD ver sau các dạng chuẩn sẽ có bổ sung thêm các hàm mới nếu muốn dùng dc với phiên bản thấp hơn thì nên tránh dùng các hàm mới đó mà nên tự tạo ra. Cá biệt có phiên bản mới thay hàm trong phiên bản cũ thì developer nên chú ý để kiểm tra ver trước rồi mới quyết định cách xử lý.

p/s: chú ý với các bạn nào viết API cho revit (using .NET only) thì API nó thay đổi xoành xoạch mỗi lần update gần như làm lại từ đầu hehe (em hơi lạc đề)
  • 1

Ideas don't matter, execution does!

1908412_308002392716743_8165279281236341


#173 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5449 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 19 October 2011 - 11:49 PM

@ Detailing: OK với những gì bạn đang tâm sự.
@ Ketxu: chia sẻ với những gì Ket đang âu tư.
Thực ra, lisp có rất nhiều hạn chế so với các ngôn ngữ khác, mà chán nhất là cái DCL, quá nghèo nàn và quá nhiêu khê.
Bàn "chuyên môn" chút:
Theo thiển ý của tôi, nói chung, repeat nhanh hơn while nếu cùng số lần lặp vì while thường còn phải xét thêm điều kiện đi theo nó. Nhưng nói riêng thì chưa kiểm tra được, ví dụ ta cho (repeat 10^10 và ta cho (while 1 rồi ngắt khi nó thực hiện đúng 10^10 vòng chẳng hạn. Hơi khó để kiểm tra nhỉ?
  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#174 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 20 October 2011 - 12:55 AM

Thì cũng tùy lúc thôi ^^ Nói chung e thường dùng while hơn :)
1 Ví dụ thường thấy nhất trong lisp với 1 hàm phổ biến : ss -> ent :

(defun dorepeat (ss / n l i)
(setq n (sslength ss) i -1)
(repeat n
(setq l (cons (ssname ss (setq i (1+ i))) l))
)
)
(defun dowhile (ss / n l e)
(setq n (sslength ss))
(while (setq e (ssname ss (setq n (1- n))))
(setq l (cons e l))
)
)

  • 0

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#175 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5449 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 20 October 2011 - 11:21 AM

Gởi bạn Detailing!
Hôm qua chúng ta có bàn đến chuyện nhanh/chậm của repeat/while, và tôi đã có vài nhận định về chúng. Đêm nằm nghĩ lại thì ngộ ra điều này:
1). Ket nói dùng while trong bài đố đó là nhanh hơn repeat (vì nếu while duyệt qua mà đạt y/c thì dừng lặp còn repeat lặp đến hết), tôi đồng ý và đưa ra ví dụ "1 lặp và 999 lặp". Hoá ra điều này quá phiêu lưu, vì ngộ nhỡ cặp sublst đó nó nằm cuối cùng thì số vòng lặp là như nhau, mà có lẽ là mỗi repeat nhanh hơn mỗi while (có ai kiểm tra giùm???) nên lúc này dùng repeat nhanh hơn. Vậy kết luận: nhanh/chậm là hên/xui chăng?
2). Câu đại ý "có khi không dùng while được mà bắt buộc phải dùng repeat" là câu tương đối thôi nhé Detailing! Ý tôi nói là trong trường hợp này dùng repeat chắc chắn nhanh hơn while chứ không phải không thể dùng while, vì với mỗi repeat thì hình như đều có thể dùng while để thay thế được. VD: "(repeat 10" thì có thể thay bằng "(setq x 0) (while (< x 10) (setq x (1+ x))" được.
Bạn nào hiểu rõ hơn thì xin chỉ giáo, đa tạ. Có loãng topic tí, mong thông cảm.
  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#176 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 20 October 2011 - 11:48 AM

Bác ĐVH test lại 2 ví dụ ketxu đưa ra bên trên xem kết quả thế nào :)
  • 0

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#177 codered8x

codered8x

    biết lệnh copy

  • Members
  • PipPipPip
  • 119 Bài viết
Điểm đánh giá: 18 (tàm tạm)

Đã gửi 20 October 2011 - 01:05 PM

Đọc mấy post trên có nói 2 hàm, hàm vl-every với vl-some khác nhau thế nào nhỉ ?
  • 0

#178 Detailing

Detailing

    biết lệnh imageclip

  • Members
  • PipPipPipPipPipPipPip
  • 667 Bài viết
Điểm đánh giá: 278 (khá)

Đã gửi 20 October 2011 - 01:14 PM

Gởi bạn Detailing!
Hôm qua chúng ta có bàn đến chuyện nhanh/chậm của repeat/while, và tôi đã có vài nhận định về chúng. Đêm nằm nghĩ lại thì ngộ ra điều này:
1). Ket nói dùng while trong bài đố đó là nhanh hơn repeat (vì nếu while duyệt qua mà đạt y/c thì dừng lặp còn repeat lặp đến hết), tôi đồng ý và đưa ra ví dụ "1 lặp và 999 lặp". Hoá ra điều này quá phiêu lưu, vì ngộ nhỡ cặp sublst đó nó nằm cuối cùng thì số vòng lặp là như nhau, mà có lẽ là mỗi repeat nhanh hơn mỗi while (có ai kiểm tra giùm???) nên lúc này dùng repeat nhanh hơn. Vậy kết luận: nhanh/chậm là hên/xui chăng?
2). Câu đại ý "có khi không dùng while được mà bắt buộc phải dùng repeat" là câu tương đối thôi nhé Detailing! Ý tôi nói là trong trường hợp này dùng repeat chắc chắn nhanh hơn while chứ không phải không thể dùng while, vì với mỗi repeat thì hình như đều có thể dùng while để thay thế được. VD: "(repeat 10" thì có thể thay bằng "(setq x 0) (while (< x 10) (setq x (1+ x))" được.
Bạn nào hiểu rõ hơn thì xin chỉ giáo, đa tạ. Có loãng topic tí, mong thông cảm.

Chào bạn,
thật nhọc công bạn quá.
Vì lisp ko cho thoát khỏi hàm khi đã dc nạp (lý do mình đã giải thích ở trên) nên while hay repeat nhanh chậm mình xin thua. Nhưng với các ngôn ngữ khác mình chắc chắn vòng lặp theo số lần nhất định và thoát (break, exit for, exit do, ...) sẽ nhanh hơn hoặc bằng cái while.
while hoàn toàn có thể thay cho repeat dc. Ngoài ra trong VB còn có dạng Do..Loop Until cũng tương tự như while.
Thân!
  • 0

Ideas don't matter, execution does!

1908412_308002392716743_8165279281236341


#179 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5449 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 27 October 2011 - 03:29 PM

Mời (và nhờ) các bạn cùng tìm lỗi của bài toán sau đây:
Trong bản vẽ đính kèm có 1 cặp Spline màu đỏ và 1 cặp Line màu trắng. Với cặp màu đỏ thì chưa phát hiện ra lỗi, nhưng với cặp màu trắng thì có lỗi. Bài toán này xuất phát từ thực tế công việc, mà tôi cũng không hiểu tại sao.
Lisp y/c nhập số điểm chia, chọn đường 1 và chọn đường 2. Kết quả lisp sẽ vẽ 2 Line.
Nhưng khi nhập n=100 và n=500 thì không lỗi, còn nhập n=300 thì lỗi.
http://www.cadviet.c...do_vui_ha_1.dwg

;Doan Van Ha CADViet.com
(defun C:HA ( / obj1 obj2 num lst1 lst2 p1 p2 q1 q2)
(setq num (getint "\nNhap so diem chia: "))
(setq obj1 (vlax-ename->vla-object (car (entsel "\nChon duong thu 1: "))) lst1 (LISTP_CURVE obj1 num)
obj2 (vlax-ename->vla-object (car (entsel "\nChon duong thu 2: "))) lst2 (LISTP_CURVE obj2 num)
p1 (car lst1) q1 (last lst2) p2 (car lst2) q2 (last lst1))
(entmake (list '(0 . "LINE") (cons 62 3) (cons 10 p1) (cons 11 q1)))
(entmake (list '(0 . "LINE") (cons 62 4) (cons 10 p2) (cons 11 q2))))
(defun LISTP_CURVE (obj num / step dis lst) ;T&#185;o list points of Curve.
(setq step (/ (vlax-curve-getDistAtPoint obj (vlax-curve-getEndPoint obj)) (1- num)) dis 0)
(repeat num
(setq lst (cons (vlax-curve-getPointAtDist Obj dis) lst) dis (+ step dis)))
lst)

  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#180 gia_bach

gia_bach

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 1436 Bài viết
Điểm đánh giá: 1426 (rất tốt)

Đã gửi 27 October 2011 - 04:13 PM

Mời (và nhờ) các bạn cùng tìm lỗi của bài toán sau đây:
Trong bản vẽ đính kèm có 1 cặp Spline màu đỏ và 1 cặp Line màu trắng. Với cặp màu đỏ thì chưa phát hiện ra lỗi, nhưng với cặp màu trắng thì có lỗi. Bài toán này xuất phát từ thực tế công việc, mà tôi cũng không hiểu tại sao.
Lisp y/c nhập số điểm chia, chọn đường 1 và chọn đường 2. Kết quả lisp sẽ vẽ 2 Line.
Nhưng khi nhập n=100 và n=500 thì không lỗi, còn nhập n=300 thì lỗi.
http://www.cadviet.c...do_vui_ha_1.dwg


;Doan Van Ha CADViet.com
(defun C:HA ( / obj1 obj2 num lst1 lst2 p1 p2 q1 q2)
(setq num (getint "\nNhap so diem chia: "))
(setq obj1 (vlax-ename->vla-object (car (entsel "\nChon duong thu 1: "))) lst1 (LISTP_CURVE obj1 num)
obj2 (vlax-ename->vla-object (car (entsel "\nChon duong thu 2: "))) lst2 (LISTP_CURVE obj2 num)
p1 (car lst1) q1 (last lst2) p2 (car lst2) q2 (last lst1))
(entmake (list '(0 . "LINE") (cons 62 3) (cons 10 p1) (cons 11 q1)))
(entmake (list '(0 . "LINE") (cons 62 4) (cons 10 p2) (cons 11 q2))))
(defun LISTP_CURVE (obj num / step dis lst) ;T&#185;o list points of Curve.
(setq step (/ (vlax-curve-getDistAtPoint obj (vlax-curve-getEndPoint obj)) (1- num)) dis 0)
(repeat num
(setq lst (cons (vlax-curve-getPointAtDist Obj dis) lst) dis (+ step dis)))
lst)

Lỗi này phát sinh khi cộng dồn : dis (+ step dis) trong hàm LISTP_CURVE.
Về lí thuyết thì sau khi lặp num lần thì dis phải bằng chiều dài của Curve, nhưng ... thực tế thì có lúc bằng lúc không bằng như bạn đã gặp với t/hợp 300.
khi dis lớn hơn chiều dài của Curve (mặc dù sai số rất nhỏ) hàm (vlax-curve-getPointAtDist Obj dis) -> nil
và đây là nguyên nhân gây ra lỗi sau đó. (bạn có thể k/tra trong k/quả trả về của hàm LISTP_CURVE)

Cách khắc phục : lặp num -1 lần , sau đó lấy EndPoint của Curve thêm vào danh sách.

(defun LISTP_CURVE (obj num / step dis lst)
(setq step (/ (vlax-curve-getDistAtPoint obj (vlax-curve-getEndPoint obj)) (1- num )) dis 0)
(repeat (1- num)
(setq lst (cons (vlax-curve-getPointAtDist Obj dis) lst)
dis (+ step dis)))
(setq lst (cons (vlax-curve-getEndPoint Obj) lst))
lst)

  • 2