This commit is contained in:
Ingy döt Net 2013-10-27 22:24:23 +00:00
parent 6f050a029e
commit 776bba907c
3887 changed files with 59894 additions and 7280 deletions

View file

@ -0,0 +1,61 @@
( ( vampire
= N len R fangsList
. !arg:@(?N:? [?len)
& 1/2*!len:~/:?len
& ( R
= len numpart left right allowed fangs rdigits
, tried digit untried head tail found
. !arg:(?len.?left.?numpart.?allowed)
& :?found
& ( !len:>0
& ( @( !numpart
: ?tried
( #%@?digit
& !allowed:?head !digit ?tail
& !head !tail:?allowed
)
( ?untried
& R
$ ( !len+-1
. 10*!left+!digit
. str$(!tried !untried)
. 0 1 2 3 4 5 6 7 8 9
)
: ?fangs
& !found !fangs:?found
& ~
)
)
| !found
)
| !N*!left^-1:~/?right:~<!left:?rdigits
& (!left*1/10:/|!right*1/10:/)
& ( @( !numpart
: ?
( #%@?digit ?
& @(!rdigits:?head !digit ?tail)
& str$(!head !tail):?rdigits
& ~
)
)
| !rdigits:&(!left,!right)
)
)
)
& R$(!len.0.!N.1 2 3 4 5 6 7 8 9)
: (
| ?fangsList
& out$(!N !fangsList)
& 1+!count:?count
)
)
& 0:?count
& 10:?i
& 16758243290880 24959017348650 14593825548650:?bignums
& whl
' ( ( vampire$!i&1+!i:?i
| !i*10:?i
)
& (!count:<25|!bignums:%?i ?bignums)
)
);

View file

@ -1,76 +1,19 @@
import std.stdio, std.algorithm, std.range, std.array;
import std.stdio, std.range, std.algorithm, std.typecons, std.conv;
immutable(long[2])[] vampireNumberFactors(in long n) {
static typeof(return) factorPairs(in long k) pure nothrow {
typeof(return) pairs;
foreach (immutable i; 2 .. cast(long)(k ^^ 0.5 + 1))
if (k % i == 0) {
immutable q = k / i;
if (q > i)
pairs ~= [i, q];
}
return pairs;
}
static long[] getDigits(in long k) pure nothrow {
typeof(return) digits;
long m = k;
while (m > 0) {
digits ~= (m % 10);
m /= 10;
}
digits.reverse();
return digits;
}
if (n < 2)
return null;
auto digits = getDigits(n);
if (digits.length % 2 != 0)
return null;
digits.sort();
typeof(return) result;
immutable half = digits.length / 2;
foreach (immutable pair; factorPairs(n)) {
/*immutable*/ auto f1 = getDigits(pair.front);
if (f1.length != half)
continue;
immutable f2 = getDigits(pair.back);
if (f2.length != half)
continue;
if (f1.back == 0 && f2.back == 0)
continue;
if (!(f1 ~ f2).sort().equal(digits))
continue;
result ~= pair;
}
return result;
auto fangs(in long n) {
auto pairs = iota(2, cast(int)(n ^^ 0.5)) // n.isqrt
.filter!(x => !(n % x)).map!(x => [x, n / x]);
enum dLen = (long x) => x.text.length;
immutable half = dLen(n) / 2;
enum halvesQ = (long[] p) => p.all!(u => dLen(u) == half);
enum digits = (long[] p) => dtext(p[0], p[1]).dup.sort();
const dn = n.to!(dchar[]).sort();
return tuple(n, pairs.filter!(p => halvesQ(p) && dn == digits(p)));
}
void main() {
for (long count = 0, n = 0; count < 25; n++) {
immutable factors = vampireNumberFactors(n);
if (!factors.empty) {
writefln("%s : %(%s %)", n, factors);
count++;
}
}
writeln;
foreach (immutable n; [16_758_243_290_880L,
24_959_017_348_650L,
14_593_825_548_650L]) {
immutable factors = vampireNumberFactors(n);
if (!factors.empty)
writefln("%s: %(%s %)", n, vampireNumberFactors(n));
}
foreach (v; int.max.iota.map!fangs.filter!q{ !a[1].empty }
.take(25).chain([16758243290880, 24959017348650,
14593825548650].map!fangs))
writefln("%d: (%(%(%s %)) (%))", v[]);
}

View file

@ -0,0 +1,26 @@
procedure main()
write("First 25 vampire numbers and their fangs:")
every fangs := vampire(n := seq())\25 do write(right(n,20),":",fangs)
write("\nOther numbers:")
every n := 16758243290880 | 24959017348650 | 14593825548650 do
write(right(n,20),": ",vampire(n)|"toothless")
end
procedure vampire(n)
ns := string(n)
if *ns % 2 = 1 then fail
every (fangs := "") ||:= " "||fangCheck(n, *ns/2, f1 := 2 to integer(sqrt(n)), n/f1)
if *fangs > 0 then return fangs
end
procedure fangCheck(n, n2, f1, f2)
if f1*f2 ~= n then fail
if n2 ~= *(f1|f2) then fail
if (f1|f2) % 10 ~= 0 then
if csort(f1||f2) == csort(n) then return "("||f1||","||f2||")"
end
procedure csort(s) # Adapted from csort(s) in Icon IPL
every (s1 := "", c := !cset(s)) do every find(c, s) do s1 ||:= c
return s1
end

View file

@ -0,0 +1,40 @@
Filter=: (#~`)(`:6)
odd =: 2&|
even =: -.@:odd
factors =: [: ([: /:~ [: */"1 ([: x: [) ^"1 [: > [: , [: { [: <@:i.@>: ])/ __ q: ]
digits =: 10&(#.inv)
tally =: # : [:
half =: -: : [:
even_number_of_digits =: even@:tally@:digits
same_digits =: digits@:[ -:&(/:~) ,&digits/@:]
assert 1 -: 1234 same_digits 23 14
assert 0 -: 1234 same_digits 23 140
half_the_digits =: (half@:tally@:digits@:[ = tally@:digits&>@:]) # ]
factors_with_half_the_digits =: half_the_digits factors
large =: (> <.@:%:)~ # ]
candidates =: large factors_with_half_the_digits
one_trailing_zero_permitted =: (0 < [: tally 0 -.~ 10&|)"1 Filter
pairs =: (% ,. ]) one_trailing_zero_permitted@:candidates
fangs =: (same_digits"0 1 # ]) pairs
A=:(0 2 -.@:-: $)&>Filter<@fangs"0]1000+i.1e4
B=:(0 2 -.@:-: $)&>Filter<@fangs"0]100000+i.25501
(,: */@:{.&.>)A,B
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┐
│21 60│15 93│35 41│30 51│21 87│27 81│80 86│201 510│260 401│210 501│204 516│150 705│135 801│158 701│152 761│161 725│167 701│141 840│201 600│231 534│281 443│152 824│231 543│246 510│251 500│
│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │204 615│ │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┼───────┤
│1260 │1395 │1435 │1530 │1827 │2187 │6880 │102510 │104260 │105210 │105264 │105750 │108135 │110758 │115672 │116725 │117067 │118440 │120600 │123354 │124483 │125248 │125433 │125460 │125500 │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┘
<@fangs"0[] 16758243290880 24959017348650 14593825548650
┌───────────────┬───────────────┬──┐
│2817360 5948208│4230765 5899410│ │
│2751840 6089832│4129587 6043950│ │
│2123856 7890480│4125870 6049395│ │
│1982736 8452080│2949705 8461530│ │
│ │2947050 8469153│ │
└───────────────┴───────────────┴──┘
fangs f. NB. <laugh>
((10&(#.^:_1)@:[ -:&(/:~) ,&(10&(#.^:_1))/@:])"0 1 # ]) ((% ,. ]) (#~ (0 < [: # :[: 0 -.~ 10&|)"1)@:(((> <.@:%:)~ # ]) (((-: :[:@:(# :[:)@:(10&(#.^:_1))@:[ = # :[:@:(10&(#.^:_1))&>@:]) # ]) ([: ([: /:~ [: */"1 ([: x: [) ^"1 [: > [: , [: { [: <@:i.@>: ])/ __ q: ]))))

View file

@ -0,0 +1,4 @@
fang(n)=my(v=digits(n),u=List());if(#v%2,return([]));fordiv(n,d,if(#Str(d)==#v/2 && #Str(n/d)==#v/2 && vecsort(v)==vecsort(concat(digits(d),digits(n/d))) && (d%10 || (n/d)%10), if(d^2>n,return(Vec(u))); listput(u, d))); Vec(u)
k=25;forstep(d=4,6,2,for(n=10^(d-1),10^d-1,f=fang(n); for(i=1,#f,print(n" "f[i]" "n/f[i]); if(i==#f && k--==0,return))))
print();v=[16758243290880, 24959017348650, 14593825548650];
for(i=1,#v,f=fang(v[i]); for(j=1,#f, print(v[i]" "f[j]" "v[i]/f[j])))

View file

@ -0,0 +1,33 @@
#!/usr/bin/perl
use warnings;
use strict;
use feature qw(say);
sub fangs {
my $vampire = shift;
my $length = length 0 + $vampire;
return if $length % 2;
my $fang_length = $length / 2;
my $from = '1' . '0' x ($fang_length - 1);
my $to = '9' x $fang_length;
my $sorted = join q(), sort split //, $vampire;
my @fangs;
for my $f1 ($from .. 1 + sqrt $vampire) {
next if $vampire % $f1;
my $f2 = $vampire / $f1;
next if $sorted ne join q(), sort split //, $f1 . $f2;
next if 2 == grep '0' eq substr($_, -1 , 1), $f1, $f2; # Needed for the 26th number.
push @fangs, [$f1, $f2];
}
return @fangs;
}
my $count = 0;
my $i = 9;
while ($count < 25) {
$i++;
my @f = fangs($i);
$count++, say join ' ', "$count. $i:", map "[@$_]", @f if @f;
}
say join ' ', $_, map "[@$_]", fangs($_) for 16758243290880, 24959017348650, 14593825548650;

View file

@ -0,0 +1,75 @@
import math
from operator import mul
from itertools import product
from functools import reduce
def fac(n):
'''\
return the prime factors for n
>>> fac(600)
[5, 5, 3, 2, 2, 2]
>>> fac(1000)
[5, 5, 5, 2, 2, 2]
>>>
'''
step = lambda x: 1 + x*4 - (x//2)*2
maxq = int(math.floor(math.sqrt(n)))
d = 1
q = n % 2 == 0 and 2 or 3
while q <= maxq and n % q != 0:
q = step(d)
d += 1
res = []
if q <= maxq:
res.extend(fac(n//q))
res.extend(fac(q))
else: res=[n]
return res
def fact(n):
'''\
return the prime factors and their multiplicities for n
>>> fact(600)
[(2, 3), (3, 1), (5, 2)]
>>> fact(1000)
[(2, 3), (5, 3)]
>>>
'''
res = fac(n)
return [(c, res.count(c)) for c in set(res)]
def divisors(n):
'Returns all the divisors of n'
factors = fact(n) # [(primefactor, multiplicity), ...]
primes, maxpowers = zip(*factors)
powerranges = (range(m+1) for m in maxpowers)
powers = product(*powerranges)
return (
reduce(mul,
(prime**power for prime, power in zip(primes, powergroup)),
1)
for powergroup in powers)
def vampire(n):
fangsets = set( frozenset([d, n//d])
for d in divisors(n)
if (len(str(d)) == len(str(n))/2
and sorted(str(d) + str(n//d)) == sorted(str(n))
and (str(d)[-1] == 0) + (str(n//d)[-1] == 0) <=1) )
return sorted(tuple(sorted(fangs)) for fangs in fangsets)
if __name__ == '__main__':
print('First 25 vampire numbers')
count = n = 0
while count <25:
n += 1
fangpairs = vampire(n)
if fangpairs:
count += 1
print('%i: %r' % (n, fangpairs))
print('\nSpecific checks for fangpairs')
for n in (16758243290880, 24959017348650, 14593825548650):
fangpairs = vampire(n)
print('%i: %r' % (n, fangpairs))

View file

@ -0,0 +1,23 @@
from math import sqrt
from itertools import imap, ifilter, islice, count
def factor_pairs(n):
return ((x, n // x) for x in xrange(2, int(sqrt(n))) if n % x == 0)
def fangs(n):
dlen = lambda x: len(str(x))
half = dlen(n) // 2
digits = lambda (x, y): sorted(str(x) + str(y))
halvesQ = lambda xs: all(y == half for y in imap(dlen, xs))
dn = sorted(str(n))
return [p for p in factor_pairs(n) if halvesQ(p) and dn==digits(p)]
def vampiricQ(n):
fn = fangs(n)
return (n, fn) if fn else None
for v in islice(ifilter(None, imap(vampiricQ, count())), 0, 25):
print v
for n in [16758243290880, 24959017348650, 14593825548650]:
print vampiricQ(n) or str(n) + " is not vampiric."

View file

@ -2,41 +2,44 @@
numeric digits 20 /*be able to handle large numbers*/
parse arg N .; if N=='' then N=25 /*No arg? Then use the default. */
#=0 /*number of vampire numbers found*/
if N>0 then do j=1000 until # >= N /*search until N vampire #s found*/
v=vampire(j)
if words(v)<=1 then iterate
parse var v v f
#=#+1
say 'vampire number' right(#,length(N)) "is: " v', fangs=' f
end /*j*/
if N<0 then do
parse value vampire(-N) with v f
if v=='' then say -N "isn't a vampire number."
else say -N "is a vampire number, fangs=" f
end
if N>0 then do j=1260 until # >= N /*search until N vampire #s found*/
if length(j)//2 then do; j=j*10-1; iterate; end /*adjust J*/
if n<11453481 then if right(j,1)==1 then iterate /*tenable?*/
f=vampire(j) /*get possible fangs for J. */
if f=='' then iterate /*Is 2nd fang null? Yes, not vamp*/
#=#+1 /*bump the vampire count, Vlad. */
say 'vampire number' right(#,length(N)) "is: " j', fangs=' f
end /*j*/
else do
f=vampire(-N) /*get possible fangs for abs(N).*/
if f=='' then say -N " isn't a vampire number."
else say -N " is a vampire number, fangs=" f
end /*j*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────VAMPIRE subroutine──────────────────*/
vampire: procedure expose !.; parse arg ? 1 z 1 $; L=length(?); W=L%2
if L//2 then return '' /*Odd length? Then not vampire. */
vampire: procedure; parse arg ?; L=length(?); W=L%2
if L//2 then return '' /*Odd length? Then not vampire.*/
$.= /*used to build BOT and TOP value*/
do k=1 for length(?); _=substr(?,k,1); $._=$._ || _; end /*k*/
bot=; do m=0 for 10; bot=bot || $.m; end /*m*/
fangs=; do k=1 for L; _=substr(?,k,1); $._=$._ || _; end /*k*/
bot=; do m=0 for 10; bot=bot || $.m; end /*m*/
top=left(reverse(bot),w); bot=left(bot,w) /*determine limits of search*/
do d=max(bot, 10**(w-1)) to min(top, 10**w-1)
if verify(d,?)\==0 then iterate
if ?//d\==0 then iterate
q=?%d; if d>q then iterate
if q*d//9\==(q+d)//9 then iterate /*modulo 9 congruence.*/
if verify(q,?)\==0 then iterate
if length(q)\==w then iterate
if right(q,1)==0 then if right(d,1)==0 then iterate
dq=d||q; t=z
do i=1 for L; _=substr(dq,i,1); p=pos(_,t)
if p==0 then iterate d
t=delstr(t,p,1)
end /*i*/
$=$ d','q
end /*d*/
return $
do d=max(bot, 10**(w-1)) to min(top, 10**w-1)
if ?//d\==0 then iterate
if verify(d,?)\==0 then iterate
if ?//d\==0 then iterate
if verify(d,?)\==0 then iterate
q=?%d; if d>q then iterate
if q*d//9\==(q+d)//9 then iterate /*modulo 9 congruence.*/
if length(q)\==w then iterate
if verify(q,?)\==0 then iterate
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*/
fangs=fangs d','q
end /*d*/
return fangs

View file

@ -1,12 +1,14 @@
def factor_pairs n
(2..n ** 0.5 + 1).map { |i| [i, n / i] if n % i == 0 }.compact
first = 10 ** ((n.to_s.size / 2) - 1)
(first .. n ** 0.5).map { |i| [i, n / i] if n % i == 0 }.compact
end
def vampire_factors n
return [] if n.to_s.size.odd?
half = n.to_s.size / 2
factor_pairs(n).select do |a, b|
a.to_s.size == half && b.to_s.size == half &&
[a, b].map { |x| x % 10 }.count(0) != 2 &&
[a, b].count {|x| x%10 == 0} != 2 &&
"#{a}#{b}".chars.sort == n.to_s.chars.sort
end
end
@ -15,11 +17,15 @@ i = vamps = 0
until vamps == 25
vf = vampire_factors(i += 1)
unless vf.empty?
puts "#{i}\t#{vf}"
puts "#{i}:\t#{vf}"
vamps += 1
end
end
[16758243290880, 24959017348650, 14593825548650].each do |n|
puts "#{n}\t#{vf}" unless (vf = vampire_factors n).empty?
if (vf = vampire_factors n).empty?
puts "#{n} is not a vampire number!"
else
puts "#{n}:\t#{vf}" unless (vf = vampire_factors n).empty?
end
end

View file

@ -0,0 +1,50 @@
import Stream._
import math._
import scala.collection.mutable.ListBuffer
object VampireNumbers extends App {
val elapsed: (=> Unit) => Long = f => {val s = System.currentTimeMillis; f; (System.currentTimeMillis - s)/1000}
val sexp = from(1, 2) // stream of integer: 1,3,5,7, ...
val rs: Stream[Int] => Stream[Pair[Long,Long]] = exps => Pair(pow(10,exps.head).toLong,(pow(10,exps.head)*10-1).toLong)#::rs(exps.tail)
val srs = rs(sexp) // stream of ranges: [10..99], [1000..9999], [100000..999999], ...
val cs: Stream[Pair[Long,Long]] => Stream[Long] = rs => (rs.head._1 to rs.head._2).toStream#:::cs(rs.tail)
val scs = cs(srs) // stream of candidates: 10,11,..,99,1000,1001,..,9999, ...
val it = scs.iterator
val checkVN: Long => Pair[Long,Seq[Pair[Long,Long]]] = n => {
val check: Pair[Long,Long] => Pair[Long,Long] = p => {
val len: Long => Int = n => n.toString.size
val (a,b) = p
if ((a%10==0)&&(b%10==0)) Pair(0,0) else
if (len(a) != len(b)) Pair(0,0) else
if (n.toString.toList.diff(a.toString.toList++b.toString.toList)!=Nil) Pair(0,0) else p
}
Pair(n,(pow(10,log10(sqrt(n).toLong).toLong).toLong+1 to sqrt(n).toLong).filter{i=>n%i==0}
.map {fac =>Pair(fac,n/fac)}.map {p => check(p)}.filter {p => p._1 != 0})
}
val et = elapsed {
val lb = new ListBuffer[Pair[Long,Seq[Pair[Long,Long]]]]
while ((lb.size<25)&&(it.hasNext)) {
checkVN(it.next) match {
case (n, Seq()) =>
case p => lb += p
}
}
lb.toList.zipWithIndex.foreach {p =>
println(p._2+1+": "+p._1._1+(p._1._2:\"")((x,y)=>" = "+x._1+" x "+x._2+y))
}
println
List(16758243290880L, 24959017348650L, 14593825548650L)
.map {checkVN(_)}
.foreach {
case (n, Seq()) => println(n+" is not vampiric")
case p => println(p._1+(p._2:\"")((x,y)=>" = "+x._1+" x "+x._2+y))
}
}
println("\n"+"elapsed time: "+et+" seconds")
}