September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,30 @@
(defun ludic-numbers (max &optional n)
(loop with numbers = (make-array (1+ max) :element-type 'boolean :initial-element t)
for i from 2 to max
until (and n (= num-results (1- n))) ; 1 will be added at the end
when (aref numbers i)
collect i into results
and count t into num-results
and do (loop for j from i to max
count (aref numbers j) into counter
when (= (mod counter i) 1)
do (setf (aref numbers j) nil))
finally (return (cons 1 results))))
(defun main ()
(format t "First 25 ludic numbers:~%")
(format t "~{~D~^ ~}~%" (ludic-numbers 100 25))
(terpri)
(format t "How many ludic numbers <= 1000?~%")
(format t "~D~%" (length (ludic-numbers 1000)))
(terpri)
(let ((numbers (ludic-numbers 30000 2005)))
(format t "~{#~D: ~D~%~}"
(mapcan #'list '(2000 2001 2002 2003 2004 2005) (nthcdr 1999 numbers))))
(terpri)
(loop with numbers = (ludic-numbers 250)
initially (format t "Triplets:~%")
for x in numbers
when (and (find (+ x 2) numbers)
(find (+ x 6) numbers))
do (format t "~3D ~3D ~3D~%" x (+ x 2) (+ x 6))))

View file

@ -1,12 +1,13 @@
import Data.List (unfoldr, genericSplitAt)
ludic :: [Integer]
ludic = 1 : unfoldr (\xs@(x:_) -> Just (x, dropEvery x xs)) [2..] where
dropEvery n = concat . map tail . unfoldr (Just . genericSplitAt n)
ludic = 1 : unfoldr (\xs@(x:_) -> Just (x, dropEvery x xs)) [2 ..]
where
dropEvery n = concatMap tail . unfoldr (Just . genericSplitAt n)
main :: IO ()
main = do
print $ take 25 $ ludic
print $ length $ takeWhile (<= 1000) $ ludic
print $ take 6 $ drop 1999 $ ludic
-- haven't done triplets task yet
print $ take 25 ludic
(print . length) $ takeWhile (<= 1000) ludic
print $ take 6 $ drop 1999 ludic
-- haven't done triplets task yet

View file

@ -0,0 +1,65 @@
/**
* Boilerplate to simply get an array filled between 2 numbers
* @param {!number} s Start here (inclusive)
* @param {!number} e End here (inclusive)
*/
const makeArr = (s, e) => new Array(e + 1 - s).fill(s).map((e, i) => e + i);
/**
* Remove every n-th element from the given array
* @param {!Array} arr
* @param {!number} n
* @return {!Array}
*/
const filterAtInc = (arr, n) => arr.filter((e, i) => (i + 1) % n);
/**
* Generate ludic numbers
* @param {!Array} arr
* @param {!Array} result
* @return {!Array}
*/
const makeLudic = (arr, result) => {
const iter = arr.shift();
result.push(iter);
return arr.length ? makeLudic(filterAtInc(arr, iter), result) : result;
};
/**
* Our Ludic numbers. This is a bit of a cheat, as we already know beforehand
* up to where our seed array needs to go in order to exactly get to the
* 2005th Ludic number.
* @type {!Array<!number>}
*/
const ludicResult = makeLudic(makeArr(2, 21512), [1]);
// Below is just logging out the results.
/**
* Given a number, return a function that takes an array, and return the
* count of all elements smaller than the given
* @param {!number} n
* @return {!Function}
*/
const smallerThanN = n => arr => {
return arr.reduce((p,c) => {
return c <= n ? p + 1 : p
}, 0)
};
const smallerThan1K = smallerThanN(1000);
console.log('\nFirst 25 Ludic Numbers:');
console.log(ludicResult.filter((e, i) => i < 25).join(', '));
console.log('\nTotal Ludic numbers smaller than 1000:');
console.log(smallerThan1K(ludicResult));
console.log('\nThe 2000th to 2005th ludic numbers:');
console.log(ludicResult.filter((e, i) => i > 1998).join(', '));
console.log('\nTriplets smaller than 250:');
ludicResult.forEach(e => {
if (e + 6 < 250 && ludicResult.indexOf(e + 2) > 0 && ludicResult.indexOf(e + 6) > 0) {
console.log([e, e + 2, e + 6].join(', '));
}
});

View file

@ -0,0 +1,83 @@
// version 1.0.6
/* Rather than remove elements from a MutableList which would be a relatively expensive operation
we instead use two arrays:
1. An array of the Ludic numbers to be returned.
2. A 'working' array of a suitable size whose elements are set to 0 to denote removal. */
fun ludic(n: Int): IntArray {
if (n < 1) return IntArray(0)
val lu = IntArray(n) // array of Ludic numbers required
lu[0] = 1
if (n == 1) return lu
var count = 1
var count2: Int
var j: Int
var k = 1
var ub = n * 11 // big enough to deal with up to 2005 ludic numbers
val a = IntArray(ub) { it } // working array
while (true) {
k += 1
for (i in k until ub) {
if (a[i] > 0) {
count +=1
lu[count - 1] = a[i]
if (n == count) return lu
a[i] = 0
k = i
break
}
}
count2 = 0
j = k + 1
while (j < ub) {
if (a[j] > 0) {
count2 +=1
if (count2 == k) {
a[j] = 0
count2 = 0
}
}
j += 1
}
}
}
fun main(args: Array<String>) {
val lu: IntArray = ludic(2005)
println("The first 25 Ludic numbers are :")
for (i in 0 .. 24) print("%4d".format(lu[i]))
val count = lu.count { it <= 1000 }
println("\n\nThere are $count Ludic numbers <= 1000" )
println("\nThe 2000th to 2005th Ludics are :")
for (i in 1999 .. 2004) print("${lu[i]} ")
println("\n\nThe Ludic triplets below 250 are : ")
var k: Int = 0
var ldc: Int
var b: Boolean
for (i in 0 .. 247) {
ldc = lu[i]
if (ldc >= 244) break
b = false
for (j in i + 1 .. 248) {
if (lu[j] == ldc + 2) {
b = true
k = j
break
}
else if (lu[j] > ldc + 2) break
}
if (!b) continue
for (j in k + 1 .. 249) {
if (lu[j] == ldc + 6) {
println("($ldc, ${ldc + 2}, ${ldc + 6})")
break
}
else if (lu[j] > ldc + 6) break
}
}
}

View file

@ -0,0 +1,44 @@
constant LUMAX = 25000
sequence ludic = repeat(1,LUMAX)
integer n
for i=2 to LUMAX/2 do
if ludic[i] then
n = 0
for j=i+1 to LUMAX do
n += ludic[j]
if n=i then
ludic[j] = 0
n = 0
end if
end for
end if
end for
sequence s = {}
for i=1 to LUMAX do
if ludic[i] then
s &= i
if length(s)=25 then exit end if
end if
end for
printf(1,"First 25 Ludic numbers: %s\n",{sprint(s)})
printf(1,"Ludic numbers below 1000: %d\n",{sum(ludic[1..1000])})
s = {}
n = 0
for i=1 to LUMAX do
if ludic[i] then
n += 1
if n>=2000 then
s &= i
if n=2005 then exit end if
end if
end if
end for
printf(1,"Ludic numbers 2000 to 2005: %s\n",{sprint(s)})
s = {}
for i=1 to 243 do
if ludic[i] and ludic[i+2] and ludic[i+6] then
s = append(s,{i,i+2,i+6})
end if
end for
printf(1,"There are %d Ludic triplets below 250: %s\n",{length(s),sprint(s)})

View file

@ -5,36 +5,31 @@ if count=='' | count=="," then count=1000 /* " " " " "
if bot=='' | bot=="," then bot=2000 /* " " " " " " */
if top=='' | top=="," then top=2005 /* " " " " " " */
if triples=='' | triples=="," then triples=250-1 /* " " " " " " */
say 'The first ' N " ludic numbers: " ludic(n) /*display title for what's coming next.*/
$=ludic( max(N, count, bot, top, triples) ) /*generate enough ludic nums.*/
say 'The first ' N " ludic numbers: " subword($,1,25) /*display 1st N ludic nums.*/
do j=1 until word($, j) > count; end /*process up to a specific #.*/
say
say "There are " words(ludic(-count)) ' ludic numbers from 1'count " (inclusive)."
say "There are " j-1 ' ludic numbers that are ' count
say
say "The " bot ' to ' top " ludic numbers are: " ludic(bot,top)
$=ludic(-triples) 0 0; #=0; @=
say
do j=1 for words($); _=word($,j) /*it is known that ludic _ exists. */
say "The " bot '' top ' (inclusive) ludic numbers are: ' subword($, bot)
#=0
@=; do j=1 for words($); _=word($,j) /*it is known that ludic _ exists. */
if _>=triples then leave /*only process up to a specific number.*/
if wordpos(_+2, $)==0 | wordpos(_+6, $)==0 then iterate /*Not triple? Skip it.*/
#=#+1; @=@ ''_ _+2 _+6"" /*bump the triple counter, and ··· */
#=#+1; @=@ ''_ _+2 _+6"" /*bump the triple counter, and ··· */
end /*j*/ /* [↑] append the found triple ──► @ */
say
if @=='' then say 'From 1'triples", no triples found."
else say 'From 1'triples", " # ' triples found:' @
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
ludic: procedure; parse arg m,h; am=abs(m); if h\=='' then am=h; $=1 2; yes=m>0 | h\==''
@= /*$≡ludic numbers superset; @≡sequence*/
do j=3 by 2 to am*max(1, 15*yes) /*construct an initial list of numbers.*/
@=@ j /* [↓] construct a ludic sequence. */
end /*j*/ /* [↑] high limit: approx or exact. */
@=@' ' /*append a blank to the number sequence*/
do while words(@)\==0; f=word(@,1) /* [↓] examine the first word. */
$=$ f /*append this first word to the list. */
do d=1 by f while d<=words(@) /*use 1st number, elide all occurrences*/
y=word(@,d) /*obtain the Yth word of @ string.*/
@=changestr(' 'y" ", @, ' . ') /*delete the number in the sequence. */
end /*d*/ /* [↑] done eliding the "1st" number. */
@=translate(@, , .) /*translate periods (dots) to blanks. */
ludic: procedure; parse arg m,,@; $=1 2 /*$≡ludic numbers superset; @≡sequence*/
do j=3 by 2 to m*15; @=@ j; end /*construct an initial list of numbers.*/
@=@' '; n=words(@) /*append a blank to the number sequence*/
do while n\==0; f=word(@,1); $=$ f /*examine the first word in @; add to $*/
do d=1 by f while d<=n; n=n-1 /*use 1st number, elide all occurrences*/
@=changestr(' 'word(@, d)" ", @, ' . ') /*crossout a number in @ */
end /*d*/ /* [↑] done eliding the "1st" number. */
@=translate(@, , .) /*change dots to blanks; count numbers.*/
end /*while*/ /* [↑] done eliding ludic numbers. */
if h=='' then return subword($, 1, am) /*return a range of ludic numbers. */
return subword($, am, h-m+1) /*return a section of a range. */
return subword($, 1, m) /*return a range of ludic numbers. */

View file

@ -0,0 +1,26 @@
import <Utilities/Set.sl>;
ludic(v(1), result(1)) :=
let
n := head(v);
filtered[i] := v[i] when (i-1) mod n /= 0;
in
result when size(v) < 1 else
ludic(filtered, result ++ [n]);
count : int(1) * int * int -> int;
count(v(1), top, index) :=
index-1 when v[index] > top else
count(v, top, index + 1);
main() :=
let
ludics := ludic(2...100000, [1]);
ludics250 := ludics[1 ... count(ludics, 250, 1)];
triplets[i] := [i, i+2, i+6] when elementOf(i+2, ludics250) and elementOf(i+6, ludics250)
foreach i within ludics250;
in
"First 25:\n" ++ toString(ludics[1...25]) ++
"\n\nLudics below 1000:\n" ++ toString(count(ludics, 1000, 1)) ++
"\n\nLudic 2000 to 2005:\n" ++ toString(ludics[2000...2005]) ++
"\n\nTriples below 250:\n" ++ toString(triplets) ;

View file

@ -0,0 +1,9 @@
fcn dropNth(n,seq){
seq.tweak(fcn(n,skipper,idx){ if(0==idx.inc()%skipper) Void.Skip else n }
.fp1(n,Ref(1))) // skip every nth number of previous sequence
}
fcn ludic{ //-->Walker
Walker(fcn(rw){ w:=rw.value; n:=w.next(); rw.set(dropNth(n,w)); n }
.fp(Ref([3..*,2]))) // odd numbers starting at 3
.push(1,2); // first two Ludic numbers
}

View file

@ -0,0 +1,6 @@
ludic().walk(25).toString(*).println();
ludic().reduce(fcn(sum,n){ if(n<1000) return(sum+1); return(Void.Stop,sum); },0).println();
ludic().drop(1999).walk(6).println(); // Ludic's between 2000 & 2005
ls:=ludic().filter(fcn(n){ (n<250) and True or Void.Stop }); // Ludic's < 250
ls.filter('wrap(n){ ls.holds(n+2) and ls.holds(n+6) }).apply(fcn(n){ T(n,n+2,n+6) }).println();