[Edited] Ugly but performs reasonably, gnerally better as the size of the list increases (some code lifted, some code new) ...
(defun FirstN_MP ( n lst / len foo boo bar )
(defun foo ( n lst / result )
(repeat n
(setq
result (cons (car lst) result)
lst (cdr lst)
)
)
(reverse result)
)
(defun boo ( n k lst func )
(repeat (/ (- (length lst) n) k)
(setq lst (func lst))
)
lst
)
(defun bar ( n lst / result )
(setq result (reverse lst))
(foreach pair '((4 cddddr)(3 cdddr)(2 cddr)(1 cdr))
(setq result (boo n (car pair) result (eval (cadr pair))))
)
(reverse result)
)
(if (< (setq n (min n (setq len (length lst)))) (/ len 5))
(foo n lst)
(bar n lst)
)
)
Test results for n samples of 10, 33, 50, 66 and 90 % of the list lengths, for list lengths of 100, 1000 and 10000.
List length = 100, n = 10
(FIRSTN_STD N LST).....1373 / 1.13 <fastest>
(FIRSTN_LM N LST)......1389 / 1.11
(FIRSTN_ALE N LST).....1404 / 1.10
(FIRSTN_MP N LST)......1545 / 1.00 <slowest>
List length = 100, n = 33
(FIRSTN_ALE N LST).....1045 / 1.10 <fastest>
(FIRSTN_STD N LST).....1045 / 1.10
(FIRSTN_LM N LST)......1045 / 1.10
(FIRSTN_MP N LST)......1154 / 1.00 <slowest>
List length = 100, n = 50
(FIRSTN_LM N LST)......1061 / 1.24 <fastest>
(FIRSTN_MP N LST)......1138 / 1.15
(FIRSTN_ALE N LST).....1310 / 1.00
(FIRSTN_STD N LST).....1311 / 1.00 <slowest>
List length = 100, n = 66
(FIRSTN_LM N LST)......1856 / 1.67 <fastest>
(FIRSTN_MP N LST)......2246 / 1.38
(FIRSTN_STD N LST).....3089 / 1.00
(FIRSTN_ALE N LST).....3104 / 1.00 <slowest>
List length = 100, n = 90
(FIRSTN_LM N LST)......1436 / 2.68 <fastest>
(FIRSTN_MP N LST)......2153 / 1.79
(FIRSTN_STD N LST).....3853 / 1.00
(FIRSTN_ALE N LST).....3854 / 1.00 <slowest>
List length = 1000, n = 100
(FIRSTN_ALE N LST).....1077 / 1.04 <fastest>
(FIRSTN_STD N LST).....1077 / 1.04
(FIRSTN_LM N LST)......1092 / 1.03
(FIRSTN_MP N LST)......1124 / 1.00 <slowest>
List length = 1000, n = 330
(FIRSTN_MP N LST)......1061 / 1.43 <fastest>
(FIRSTN_LM N LST)......1497 / 1.01
(FIRSTN_ALE N LST).....1513 / 1.00
(FIRSTN_STD N LST).....1513 / 1.00 <slowest>
List length = 1000, n = 500
(FIRSTN_MP N LST)......1014 / 2.22 <fastest>
(FIRSTN_LM N LST)......1701 / 1.32
(FIRSTN_STD N LST).....2231 / 1.01
(FIRSTN_ALE N LST).....2247 / 1.00 <slowest>
List length = 1000, n = 660
(FIRSTN_MP N LST)......1981 / 2.95 <fastest>
(FIRSTN_ALE N LST).....2044 / 2.86
(FIRSTN_LM N LST)......2824 / 2.07
(FIRSTN_STD N LST).....5850 / 1.00 <slowest>
List length = 1000, n = 900
(FIRSTN_ALE N LST).....1669 / 4.72 <fastest>
(FIRSTN_LM N LST)......1856 / 4.24
(FIRSTN_MP N LST)......1872 / 4.21
(FIRSTN_STD N LST).....7878 / 1.00 <slowest>
List length = 10000, n = 1000
(FIRSTN_LM N LST)......1154 / 5.12 <fastest>
(FIRSTN_STD N LST).....1155 / 5.12
(FIRSTN_MP N LST)......1170 / 5.05
(FIRSTN_ALE N LST).....5912 / 1.00 <slowest>
List length = 10000, n = 3300
(FIRSTN_MP N LST)......1155 / 2.31 <fastest>
(FIRSTN_STD N LST).....1825 / 1.46
(FIRSTN_LM N LST)......1826 / 1.46
(FIRSTN_ALE N LST).....2668 / 1.00 <slowest>
List length = 10000, n = 5000
(FIRSTN_MP N LST)......1139 / 2.40 <fastest>
(FIRSTN_LM N LST)......2153 / 1.27
(FIRSTN_ALE N LST).....2371 / 1.15
(FIRSTN_STD N LST).....2730 / 1.00 <slowest>
List length = 10000, n = 6600
(FIRSTN_MP N LST)......1108 / 3.30 <fastest>
(FIRSTN_LM N LST)......1732 / 2.11
(FIRSTN_ALE N LST).....1981 / 1.84
(FIRSTN_STD N LST).....3651 / 1.00 <slowest>
List length = 10000, n = 9000
(FIRSTN_MP N LST)......1061 / 4.69 <fastest>
(FIRSTN_LM N LST)......1170 / 4.25
(FIRSTN_ALE N LST).....1295 / 3.84
(FIRSTN_STD N LST).....4976 / 1.00 <slowest>