September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -3,7 +3,7 @@ import Control.Arrow ((&&&))
-- VAMPIRE NUMBERS ------------------------------------------------------------
vampires :: [Int]
vampires = filter ((0 <) . length . fangs) [1 ..]
vampires = filter (not . null . fangs) [1 ..]
fangs :: Int -> [(Int, Int)]
fangs n

View file

@ -1,19 +1,20 @@
sub is_vampire (Int $num) {
my $digits = $num.comb.sort;
my @fangs;
for vfactors($num) -> $this {
(10**$num.sqrt.log(10).floor .. $num.sqrt.ceiling).map: -> $this {
next if $num % $this;
my $that = $num div $this;
@fangs.push("$this x $that") if
!($this %% 10 && $that %% 10) and
($this ~ $that).comb.sort eq $digits;
next if $this %% 10 && $that %% 10;
@fangs.push("$this x $that") if ($this ~ $that).comb.sort eq $digits;
}
return @fangs;
@fangs
}
constant @vampires = gather for 1 .. * -> $n {
next if $n.log(10).floor %% 2;
my @fangs = is_vampire($n);
take "$n: { @fangs.join(', ') }" if @fangs.elems;
constant @vampires = flat (3..*).map: -> $s, $e {
(10**$s .. 10**$e).hyper.map: -> $n {
next unless my @fangs = is_vampire($n);
"$n: { @fangs.join(', ') }"
}
}
say "\nFirst 25 Vampire Numbers:\n";
@ -22,16 +23,6 @@ say "\nFirst 25 Vampire Numbers:\n";
say "\nIndividual tests:\n";
for 16758243290880, 24959017348650, 14593825548650 {
print "$_: ";
my @fangs = is_vampire($_);
if @fangs.elems {
say @fangs.join(', ');
} else {
say 'is not a vampire number.';
}
}
sub vfactors (Int $n) {
map { $_ if $n %% $_ }, 10**$n.sqrt.log(10).floor .. $n.sqrt.ceiling;
.say for (16758243290880, 24959017348650, 14593825548650).hyper(:1batch).map: {
"$_: " ~ (is_vampire($_).join(', ') || 'is not a vampire number.')
}

View file

@ -0,0 +1,45 @@
function vampire(atom v)
sequence res = {}
if v>=0 then
string vs = sprintf("%d",v)
if mod(length(vs),2)=0 then -- even length
vs = sort(vs)
for i=power(10,length(vs)/2-1) to floor(sqrt(v)) do
if remainder(v,i)=0 then
integer i2 = v/i
string si = sprintf("%d",i),
s2 = sprintf("%d",i2)
if (si[$]!='0' or s2[$]!='0')
and sort(si&s2)=vs then
res = append(res,{i,i2})
end if
end if
end for
end if
end if
return res
end function
integer found = 0
atom i = 0
sequence res
puts(1,"The first 26 vampire numbers and their fangs:\n")
while found<26 do
res = vampire(i)
if length(res) then
found += 1
printf(1,"%d: %d: %s\n",{found,i,sprint(res)})
end if
i += 1
end while
puts(1,"\n")
constant tests = {16758243290880,
24959017348650,
14593825548650}
for t=1 to length(tests) do
i = tests[t]
res = vampire(i)
printf(1,"%d: %s\n",{i,iff(res={}?"not a vampire number":sprint(res))})
end for

View file

@ -1,40 +1,51 @@
/*REXX program displays N vampire numbers, or verifies if a number is vampiric. */
numeric digits 20 /*be able to handle gihugic numbers. */
parse arg N .; if N=='' | N=="," then N=25 /*Not specified? Then use the default.*/
!.0=1260; !.1=11453481; !.2=115672; !.3=124483; !.4=105264 /*lowest #, dig.*/
!.5=1395; !.6=126846; !.7=1827; !.8=110758; !.9=156289 /* " " " */
#=0 /*num. of vampire numbers found, so far*/
parse arg N . /*obtain optional argument from the CL.*/
if N=='' | N=="," then N= 25 /*Not specified? Then use the default.*/
!.0= 1260; !.1= 11453481; !.2= 115672; !.3= 124483; !.4= 105264 /*lowest #, dig*/
!.5= 1395; !.6= 126846; !.7= 1827; !.8= 110758; !.9= 156289 /* " " " */
#= 0; L= length(N); aN= abs(N) /*num. of vampire numbers found, so far*/
numeric digits max(9, length(aN) ) /*be able to handle ginormus numbers. */
@vamp= right('vampire number', 20) /*literal used when showing a vampire #*/
if N>0 then do j=1260 until # >= N /*search until N vampire numbers found.*/
if length(j) // 2 then do; j=j*10 - 1; iterate; end /*adjust J*/
_=right(j,1); if j<!._ then iterate /*is number tenable based on last dig? */
f=vampire(j); if f=='' then iterate /*Are fangs null? Yes, not vampire. */
#=# + 1 /*bump the vampire count, Vlad. */
say 'vampire number' right(#,length(N)) "is: " j', fangs=' f
if length(j) // 2 then do; j= j*10 - 1; iterate /*bump J to even length*/
end /* [↑] check if odd. */
parse var j '' -1 _ /*obtain the last decimal digit of J. */
if j<!._ then iterate /*is number tenable based on last dig? */
f= vampire(j) /*obtain the fangs of J. */
if f=='' then iterate /*Are fangs null? Yes, not vampire. */
#= # + 1 /*bump the vampire count, Vlad. */
say @vamp right(#, L) "is: " right(j, 9)', fangs=' f
end /*j*/ /* [↑] process a range of numbers. */
else do; N=abs(N); f=vampire(N) /* [↓] process a number; obtain fangs.*/
if f=='' then say N " isn't a vampire number."
else say N " is a vampire number, fangs=" f
else do; f= vampire(aN) /* [↓] process a number; obtain fangs.*/
if f=='' then say aN " isn't a vampire number."
else say aN " is a vampire number, fangs=" f
end
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
vampire: procedure; parse arg ?,, $. a bot; L=length(?); w=L % 2
if L//2 then return '' /*Is L an odd length? Then ¬vampire.*/
do k=1 for L; _=substr(?,k,1); $._=$._ || _; end /*k*/
do m=0 for 10; bot=bot || $.m; end /*m*/
top=left( reverse(bot), w); bot=left(bot, w) /*determine limits of search*/
inc=?//2 + 1 /*? is odd? INC=2. No? INC=1*/
beg=max(bot, 10**(w-1)); if inc=2 then if beg//2==0 then beg=beg + 1
vampire: procedure; parse arg x,, $. a bot; L= length(x) /*get arg; compute len of X*/
if L//2 then return '' /*is L odd? Then ¬vampire.*/
do k=1 for L; _= substr(x, k, 1); $._= $._ || _
end /*k*/
w= L % 2 /*%: is REXX's integer ÷ */
do m=0 for 10; bot= bot || $.m
end /*m*/
top= left( reverse(bot), w)
bot= left(bot, w) /*determine limits of search*/
inc= x // 2 + 1 /*X is odd? INC=2. No? INC=1*/
beg= max(bot, 10**(w-1) ) /*calculate where to start.*/
if inc==2 then if beg//2==0 then beg= beg + 1 /*possibly adjust the start.*/
/* [↑] odd BEG if odd INC*/
do d=beg to min(top, 10**w - 1) by inc
if ? // d \==0 then iterate /*? not ÷ by D? Then skip,*/
q=? % d; if d>q then iterate /*is D > Q Then skip.*/
if q*d//9 \== (q+d)//9 then iterate /*modulo 9 congruence test. */
if length(q) \==w then iterate /*Len of Q ^= W? Then skip.*/
if right(q, 1) ==0 then if right(d, 1) ==0 then iterate
dq=d || q
t=?; do i=1 for L; p=pos( substr(dq, i, 1), t)
if p==0 then iterate d; t=delstr(t, p, 1)
end /*i*/
a=a '['d""q']'
end /*d*/
return a
do d=beg to min(top, 10**w - 1) by inc /*use smart start, end, inc.*/
if x // d \==0 then iterate /*X not ÷ by D? Then skip,*/
q= x % d; if d>q then iterate /*is D > Q Then skip.*/
if q*d//9 \== (q+d)//9 then iterate /*modulo 9 congruence test. */
if length(q) \==w then iterate /*Len of Q ¬= W? Then skip.*/
parse var q '' -1 _ /*get last decimal dig. of Q*/
if _==0 then if right(d, 1) ==0 then iterate
dq= d || q
t= x; do i=1 for L; p= pos( substr(dq, i, 1), t)
if p==0 then iterate d; t= delstr(t, p, 1)
end /*i*/
a=a '['d""q'] ' /*construct formatted fangs.*/
end /*d*/ /* [↑] ∙ is a round bullet*/
return a /*return formatted fangs.*/

View file

@ -0,0 +1,54 @@
import Foundation
func vampire<T>(n: T) -> [(T, T)] where T: BinaryInteger, T.Stride: SignedInteger {
let strN = String(n).sorted()
let fangLength = strN.count / 2
let start = T(pow(10, Double(fangLength - 1)))
let end = T(Double(n).squareRoot())
var fangs = [(T, T)]()
for i in start...end where n % i == 0 {
let quot = n / i
guard i % 10 != 0 || quot % 10 != 0 else {
continue
}
if "\(i)\(quot)".sorted() == strN {
fangs.append((i, quot))
}
}
return fangs
}
var count = 0
var i = 1.0
while count < 25 {
let start = Int(pow(10, i))
let end = start * 10
for num in start...end {
let fangs = vampire(n: num)
guard !fangs.isEmpty else { continue }
count += 1
print("\(num) is a vampire number with fangs: \(fangs)")
guard count != 25 else { break }
}
i += 2
}
for (vamp, fangs) in [16758243290880, 24959017348650, 14593825548650].lazy.map({ ($0, vampire(n: $0)) }) {
if fangs.isEmpty {
print("\(vamp) is not a vampire number")
} else {
print("\(vamp) is a vampire number with fangs: \(fangs)")
}
}