all tasks

This commit is contained in:
Ingy döt Net 2013-04-11 01:07:29 -07:00
parent b83f433714
commit 68f8f3e56b
14735 changed files with 178959 additions and 0 deletions

View file

@ -0,0 +1,13 @@
A [[wp:Vampire_number|vampire number]] is a natural number with an even number of digits, that can be factored into two integers. These two factors are called the ''fangs'', and must have the following properties:
* they each contain half the number of the digits of the original number
* together they consist of exactly the same digits as the original number
* at most one of them has a trailing zero
An example of a Vampire number and its fangs: <code>1260 : (21, 60)</code>
;<nowiki>Task description:</nowiki>
# Print the first 25 Vampire numbers and their fangs.
# Check if the following numbers are Vampire numbers and, if so, print them and their fangs: <code>16758243290880, 24959017348650, 14593825548650</code>
Note that a Vampire number can have more than 1 pair of fangs.
;<nowiki>See also:</nowiki>
* [http://www.numberphile.com/videos/vampire_numbers.html numberphile.com].
* [http://users.cybercity.dk/~dsl522332/math/vampires/ Vampire search algorithm]
* [[oeis:A014575|Vampire numbers on OEIS]]

View file

@ -0,0 +1,2 @@
---
note: Mathematics

View file

@ -0,0 +1,75 @@
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <cmath>
bool isVampireNumber( long number, std::vector<std::pair<long, long> > & solution ) {
std::ostringstream numberstream ;
numberstream << number ;
std::string numberstring( numberstream.str( ) ) ;
std::sort ( numberstring.begin( ) , numberstring.end( ) ) ;
int fanglength = numberstring.length( ) / 2 ;
long start = static_cast<long>( std::pow( 10 , fanglength - 1 ) ) ;
long end = start * 10 ;
for ( long i = start ; i < ( end - start ) / 2 ; i++ ) {
if ( number % i == 0 ) {
long quotient = number / i ;
if ( ( i % 10 == 0 ) && ( quotient % 10 == 0 ) )
return false ;
numberstream.str( "" ) ; //clear the number stream
numberstream << i << quotient ;
std::string divisorstring ( numberstream.str( ) ) ;
std::sort ( divisorstring.begin( ) , divisorstring.end( ) ) ;
if ( divisorstring == numberstring ) {
std::pair<long , long> divisors = std::make_pair( i, quotient ) ;
solution.push_back( divisors ) ;
}
}
}
return !solution.empty( ) ;
}
void printOut( const std::pair<long, long> & solution ) {
std::cout << "[ " << solution.first << " , " << solution.second << " ]" ;
}
int main( ) {
int vampireNumbersFound = 0 ;
std::vector<std::pair<long , long> > solutions ;
double i = 1.0 ;
while ( vampireNumbersFound < 25 ) {
long start = static_cast<long>( std::pow( 10 , i ) ) ;
long end = start * 10 ;
for ( long num = start ; num < end ; num++ ) {
if ( isVampireNumber( num , solutions ) ) {
std::cout << vampireNumbersFound << " :" << num << " is a vampire number! These are the fangs:\n" ;
std::for_each( solutions.begin( ) , solutions.end( ) , printOut ) ;
std::cout << "\n_______________" << std::endl ;
solutions.clear( ) ;
vampireNumbersFound++ ;
if ( vampireNumbersFound == 25 )
break ;
}
}
i += 2.0 ;
}
std::vector<long> testnumbers ;
testnumbers.push_back( 16758243290880 ) ;
testnumbers.push_back( 2495901734865 ) ;
testnumbers.push_back( 14593825548650 ) ;
for ( std::vector<long>::const_iterator svl = testnumbers.begin( ) ;
svl != testnumbers.end( ) ; svl++ ) {
if ( isVampireNumber( *svl , solutions ) ) {
std::cout << *svl << " is a vampire number! The fangs:\n" ;
std::for_each( solutions.begin( ) , solutions.end( ) , printOut ) ;
std::cout << std::endl ;
solutions.clear( ) ;
} else {
std::cout << *svl << " is not a vampire number!" << std::endl ;
}
}
return 0 ;
}

View file

@ -0,0 +1,82 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
typedef uint64_t xint;
typedef unsigned long long ull;
xint tens[20];
inline xint max(xint a, xint b) { return a > b ? a : b; }
inline xint min(xint a, xint b) { return a < b ? a : b; }
inline int ndigits(xint x)
{
int n = 0;
while (x) n++, x /= 10;
return n;
}
inline xint dtally(xint x)
{
xint t = 0;
while (x) t += 1<<((x%10) * 6), x /= 10;
return t;
}
int fangs(xint x, xint *f)
{
int n = 0;
int nd = ndigits(x);
if (nd & 1) return 0;
nd /= 2;
xint lo, hi;
lo = max(tens[nd-1], (x + tens[nd] - 2)/ (tens[nd] - 1));
hi = min(x / lo, sqrt(x));
xint a, b, t = dtally(x);
for (a = lo; a <= hi; a++) {
b = x / a;
if (a * b == x && ((a%10) || (b%10)) && t == dtally(a) + dtally(b))
f[n++] = a;
}
return n;
}
void show_fangs(xint x, xint *f, xint cnt)
{
printf("%llu", (ull)x);
int i;
for (i = 0; i < cnt; i++)
printf(" = %llu x %llu", (ull)f[i], (ull)(x / f[i]));
putchar('\n');
}
int main(void)
{
int i, j, n;
xint x, f[16], bigs[] = {16758243290880ULL, 24959017348650ULL, 14593825548650ULL, 0};
tens[0] = 1;
for (i = 1; i < 20; i++)
tens[i] = tens[i-1] * 10;
for (x = 1, n = 0; n < 25; x++) {
if (!(j = fangs(x, f))) continue;
printf("%2d: ", ++n);
show_fangs(x, f, j);
}
putchar('\n');
for (i = 0; bigs[i]; i++) {
if ((j = fangs(bigs[i], f)))
show_fangs(bigs[i], f, j);
else
printf("%llu is not vampiric\n", (ull)bigs[i]);
}
return 0;
}

View file

@ -0,0 +1,23 @@
(defn factor-pairs [n]
(for [x (range 2 (Math/sqrt n))
:when (zero? (mod n x))]
[x (quot n x)]))
(defn fangs [n]
(let [dlen (comp count str)
half (/ (dlen n) 2)
halves? #(apply = (cons half (map dlen %)))
digits #(sort (apply str %))]
(filter #(and (halves? %)
(= (sort (str n)) (digits %)))
(factor-pairs n))))
(defn vampiric? [n]
(let [fangs (fangs n)]
(if (empty? fangs) nil [n fangs])))
(doseq [n (take 25 (keep vampiric? (range)))]
(prn n))
(doseq [n [16758243290880, 24959017348650, 14593825548650]]
(println (or (vampiric? n) (str n " is not vampiric."))))

View file

@ -0,0 +1,76 @@
import std.stdio, std.algorithm, std.range, std.array;
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]; // Heap-allocated pair.
}
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;
}
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));
}
}

View file

@ -0,0 +1,92 @@
import std.stdio, std.math, std.algorithm, std.array, std.traits;
T[N] pows(T, size_t N)() {
typeof(return) result;
result[0] = 1;
foreach (i, ref r; result[1 .. $])
r = result[i] * 10;
return result;
}
__gshared immutable tenPowsU = pows!(uint, 10);
__gshared immutable tenPowsUL = pows!(ulong, 20);
size_t nDigits(T)(in T x) pure nothrow {
Unqual!T y = x;
size_t n = 0;
while (y) {
n++;
y /= 10;
}
return n;
}
T dTally(T)(in T x) pure nothrow {
Unqual!T y = x;
T t = 0;
while (y) {
t += 1 << ((y % 10) * 6);
y /= 10;
}
return t;
}
T[] fangs(T)(in T x, T[] f)
pure nothrow if (is(T == uint) || is(T == ulong)) {
alias tenPows = Select!(is(T == ulong), tenPowsUL, tenPowsU);
immutable nd0 = nDigits(x);
if (nd0 & 1)
return null;
immutable nd = nd0 / 2;
immutable lo = max(tenPows[nd - 1],
(x + tenPows[nd] - 2) / (tenPows[nd] - 1));
immutable hi = min(x / lo, cast(T)sqrt(cast(real)x));
immutable t = x.dTally;
size_t n = 0;
foreach (immutable a; lo .. hi + 1) {
immutable b = x / a;
if (a * b == x
&& (a % 10 || b % 10)
&& t == (a.dTally + b.dTally)) {
f[n] = a;
n++;
}
}
return f[0 .. n];
}
void showFangs(T)(in T x, in T[] fs) {
x.write;
foreach (immutable fi; fs)
writef(" = %d x %d", fi, x / fi);
writeln;
}
void main() {
uint[16] fu;
for (uint x = 1, n = 0; n < 25; x++) {
const fs = fangs(x, fu);
if (fs.empty)
continue;
n++;
writef("%2d: ", n);
showFangs(x, fs);
}
writeln;
__gshared static immutable ulong[3] bigs = [16_758_243_290_880UL,
24_959_017_348_650UL,
14_593_825_548_650UL];
ulong[fu.length] ful;
foreach (immutable bi; bigs) {
const fs = fangs(bi, ful);
if (fs.empty)
writeln(bi, " is not vampiric");
else
showFangs(bi, fs);
}
}

View file

@ -0,0 +1,41 @@
import Data.List (sort)
primes = 2:filter isPrime [3,5..] where
isPrime n = f n primes where
f n (p:ps)
| p*p > n = True
| n`mod`p == 0 = False
| otherwise = f n ps
primeFactors n = f n primes where
f n (p:ps)
| p*p > n = if n == 1 then [] else [(n,1)]
| n`mod`p == 0 = (p,e):f res ps
| otherwise = f n ps
where (e,res) = ppower (n`div`p) p 1
ppower n p e
| n`mod`p /= 0 = (e,n)
| otherwise = ppower (n`div`p) p (e+1)
factors n = comb (primeFactors n) where
comb [] = [1]
comb ((p,e):others) = [a*b | b<-map (p^) [0 .. e], a<-comb others]
ndigit 0 = 0
ndigit n = 1 + ndigit (n`div`10)
fangs n
| odd w = []
| otherwise = map (\x->(x,n`div`x)) $ filter isfang (factors n) where
isfang x = x > xmin && x < y && y < ymax && -- same length
((x`div`10)/=0 || (y`div`10)/=0) && -- not zero-ended
sort (show n) == sort ((show x) ++ (show y)) -- same digits
where y = n`div`x
w = ndigit n
xmin = 10^(w`div`2-1)
ymax = 10^(w`div`2)
vampires = filter ((0<).length.fangs) [1..]
main = mapM (\n->print (n,fangs n)) $
((take 25 vampires) ++ [16758243290880, 24959017348650, 14593825548650])

View file

@ -0,0 +1,48 @@
import java.util.Arrays;
import java.util.HashSet;
public class VampireNumbers{
private static int numDigits(long num){
return Long.toString(Math.abs(num)).length();
}
private static boolean fangCheck(long orig, long fang1, long fang2){
if(Long.toString(fang1).endsWith("0") && Long.toString(fang2).endsWith("0")) return false;
int origLen = numDigits(orig);
if(numDigits(fang1) != origLen / 2 || numDigits(fang2) != origLen / 2) return false;
byte[] origBytes = Long.toString(orig).getBytes();
byte[] fangBytes = (Long.toString(fang1) + Long.toString(fang2)).getBytes();
Arrays.sort(origBytes);
Arrays.sort(fangBytes);
return Arrays.equals(origBytes, fangBytes);
}
public static void main(String[] args){
HashSet<Long> vamps = new HashSet<Long>();
for(long i = 10; vamps.size() <= 25; i++ ){
if((numDigits(i) % 2) != 0) {i = i * 10 - 1; continue;}
for(long fang1 = 2; fang1 <= Math.sqrt(i) + 1; fang1++){
if(i % fang1 == 0){
long fang2 = i / fang1;
if(fangCheck(i, fang1, fang2) && fang1 <= fang2){
vamps.add(i);
System.out.println(i + ": [" + fang1 + ", " + fang2 +"]");
}
}
}
}
Long[] nums = {16758243290880L, 24959017348650L, 14593825548650L};
for(Long i : nums){
for(long fang1 = 2; fang1 <= Math.sqrt(i) + 1; fang1++){
if(i % fang1 == 0){
long fang2 = i / fang1;
if(fangCheck(i, fang1, fang2) && fang1 <= fang2){
System.out.println(i + ": [" + fang1 + ", " + fang2 +"]");
}
}
}
}
}
}

View file

@ -0,0 +1,38 @@
my @vampires := gather for 1 .. * -> $start, $end {
map {
my @fangs = is_vampire($_);
take "$_: { @fangs.join(', ') }" if @fangs.elems
}, 10 ** $start .. 10 ** $end
}
say "\nFirst 25 Vampire Numbers:\n";
.say for @vampires[^25];
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 is_vampire (Int $num) {
my $digits = $num.comb.sort;
my @fangs;
for vfactors($num) -> $this {
my $that = $num div $this;
@fangs.push("$this x $that") if
!($this %% 10 && $that %% 10) and
($this ~ $that).comb.sort eq $digits;
}
return @fangs;
}
sub vfactors (Int $n) {
map { $_ if $n %% $_ }, 10**$n.sqrt.log(10).floor .. $n.sqrt.ceiling;
}

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,42 @@
/*REXX pgm displays X vampire numbers, or verifies if a # is vampiric.*/
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
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. */
$.= /*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*/
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 $

View file

@ -0,0 +1,34 @@
#lang racket
;; chock full of fun... including divisors
(require math/number-theory)
;; predicate to tell if n is a vampire number
(define (sub-vampire?-and-fangs n)
(define digit-count-n (add1 (order-of-magnitude n)))
(define (string-sort-characters s) (sort (string->list s) char<?))
(define digits-in-order-n (string-sort-characters (number->string n)))
(define (fangs-of-n? d e)
(and (<= d e) ; avoid duplication
(= (add1 (order-of-magnitude d)) (add1 (order-of-magnitude e)) (/ digit-count-n 2))
(not (= 0 (modulo d 10) (modulo e 10)))
(equal? digits-in-order-n
(string-sort-characters (string-append (number->string d) (number->string e))))))
(let* ((fangses (for*/list ((d (in-list (divisors n))) #:when (fangs-of-n? d (/ n d)))
(list d (/ n d)))))
(and (not (null? fangses)) (cons n fangses))))
(define (vampire?-and-fangs n)
(and (odd? (order-of-magnitude n)) ; even number of digits - else not even worth looking!
(sub-vampire?-and-fangs n)))
(displayln "First 25 vampire numbers:")
(for ((vmp (sequence-filter identity (sequence-map vampire?-and-fangs (in-naturals 1))))
(cnt (in-range 1 (add1 25))))
(printf "#~a ~a~%" cnt vmp))
(displayln "Test the big numbers:")
(displayln (vampire?-and-fangs 16758243290880))
(displayln (vampire?-and-fangs 24959017348650))
(displayln (vampire?-and-fangs 14593825548650))

View file

@ -0,0 +1,25 @@
def factor_pairs n
(2..n ** 0.5 + 1).map { |i| [i, n / i] if n % i == 0 }.compact
end
def vampire_factors n
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}".chars.sort == n.to_s.chars.sort
end
end
i = vamps = 0
until vamps == 25
vf = vampire_factors(i += 1)
unless vf.empty?
puts "#{i}\t#{vf}"
vamps += 1
end
end
[16758243290880, 24959017348650, 14593825548650].each do |n|
puts "#{n}\t#{vf}" unless (vf = vampire_factors n).empty?
end

View file

@ -0,0 +1,24 @@
proc factorPairs {n {from 2}} {
set result [list 1 $n]
if {$from<=1} {set from 2}
for {set i $from} {$i<=sqrt($n)} {incr i} {
if {$n%$i} {} {lappend result $i [expr {$n/$i}]}
}
return $result
}
proc vampireFactors {n} {
if {[string length $n]%2} return
set half [expr {[string length $n]/2}]
set digits [lsort [split $n ""]]
set result {}
foreach {a b} [factorPairs $n [expr {10**$half/10}]] {
if {
[string length $a]==$half && [string length $b]==$half &&
($a%10 || $b%10) && $digits eq [lsort [split $a$b ""]]
} then {
lappend result [list $a $b]
}
}
return $result
}

View file

@ -0,0 +1,25 @@
# A nicer way to print the evidence of vampire-ness
proc printVampire {n pairs} {
set out "${n}:"
foreach p $pairs {
append out " \[[join $p {, }]\]"
}
puts $out
}
set n 0
for {set i 0} {$i < 25} {incr i} {
while 1 {
if {[llength [set vamps [vampireFactors [incr n]]]]} {
printVampire $n $vamps
break
}
}
}
puts ""
foreach n {16758243290880 24959017348650 14593825548650} {
if {[llength [set vamps [vampireFactors $n]]]} {
printVampire $n $vamps
} else {
puts "$n is not a vampire number"
}
}