Data update

This commit is contained in:
Ingy döt Net 2026-04-30 12:34:36 -04:00
parent 4bb20c9b71
commit cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions

View file

@ -0,0 +1,105 @@
program vampire_numbers
implicit none
integer :: count, i, n_digits
integer(kind=8) :: num, test_nums(3)
! logical :: is_vampire
! Initialize test numbers
test_nums = [16758243290880_8, 24959017348650_8, 14593825548650_8]
! Print first 25 vampire numbers
print *, 'First 25 vampire numbers and their fangs:'
count = 0
num = 1000
do while (count < 25)
if (is_vampire(num)) then
count = count + 1
end if
num = num + 1
end do
! Check specific test numbers
print *, ''
print *, 'Checking specific numbers:'
do i = 1, 3
if (is_vampire(test_nums(i))) then
continue ! Output handled in is_vampire
else
print *, test_nums(i), ' is not a vampire number.'
end if
end do
contains
logical function is_vampire(num)
integer(kind=8), intent(in) :: num
integer(kind=8) :: a, b, start_a, end_a
integer :: num_digits, half_digits
character(len=20) :: num_str, a_str, b_str
! Get number of digits
num_digits = floor(log10(real(num))) + 1
if (mod(num_digits, 2) /= 0) then
is_vampire = .false.
return
end if
half_digits = num_digits / 2
! Calculate range for factor a
start_a = max(10**(half_digits-1), num / (10**half_digits))
end_a = min(num / 10**(half_digits-1), floor(sqrt(real(num))))
is_vampire = .false.
do a = start_a, end_a
if (mod(num, a) /= 0) cycle
b = num / a
! Check if b has correct number of digits
if (b < 10**(half_digits-1) .or. b >= 10**half_digits) cycle
! Check trailing zeros
if (mod(a, 10_8) == 0 .and. mod(b, 10_8) == 0) cycle
! Check if digits match
write(num_str, '(I0)') num
write(a_str, '(I0)') a
write(b_str, '(I0)') b
if (len_trim(a_str) == half_digits .and. len_trim(b_str) == half_digits) then
if (same_digits(num_str, a_str, b_str)) then
is_vampire = .true.
print '(I0, " : (", I0, ", ", I0, ")")', num, a, b
end if
end if
end do
end function is_vampire
logical function same_digits(num_str, a_str, b_str)
character(len=*), intent(in) :: num_str, a_str, b_str
integer :: digits_num(0:9), digits_ab(0:9), i
character(len=1) :: c
digits_num = 0
digits_ab = 0
! Count digits in num
do i = 1, len_trim(num_str)
read(num_str(i:i), '(A)') c
digits_num(ichar(c) - ichar('0')) = digits_num(ichar(c) - ichar('0')) + 1
end do
! Count digits in a
do i = 1, len_trim(a_str)
read(a_str(i:i), '(A)') c
digits_ab(ichar(c) - ichar('0')) = digits_ab(ichar(c) - ichar('0')) + 1
end do
! Count digits in b
do i = 1, len_trim(b_str)
read(b_str(i:i), '(A)') c
digits_ab(ichar(c) - ichar('0')) = digits_ab(ichar(c) - ichar('0')) + 1
end do
same_digits = all(digits_num == digits_ab)
end function same_digits
end program vampire_numbers

View file

@ -0,0 +1,69 @@
const TENS = [UInt(10)^i for i in 0:19]
function dtally(x::UInt)
t = UInt(0)
while x > 0
t += UInt(1) << ((x % 10) * 6)
x ÷= 10
end
return t
end
function fangs(x::UInt)
f = UInt[]
nd = ndigits(x)
nd & 1 != 0 && return f
nd ÷= 2
lo = max(TENS[nd], (x + TENS[nd+1] - 2) ÷ (TENS[nd+1] - 1))
hi = min(x ÷ lo, floor(UInt, sqrt(x)))
t = dtally(x)
for a in lo:hi
b = x ÷ a
if a * b == x && ((a % 10) != 0 || (b % 10) != 0) && t == dtally(a) + dtally(b)
push!(f, a)
end
end
return f
end
function show_fangs(x::UInt, f::Vector{UInt})
print(x)
for fang in f
print(" = ", fang, " x ", x ÷ fang)
end
println()
end
function testfangs()
bigs = UInt[16758243290880, 24959017348650, 14593825548650]
# Find first 25 vampire numbers
x = UInt(1)
n = 0
while n < 25
f = fangs(x)
if !isempty(f)
n += 1
print(lpad(n, 2), ": ")
show_fangs(x, f)
end
x += 1
end
println()
# Check big numbers
for b in bigs
f = fangs(b)
if !isempty(f)
show_fangs(b, f)
else
println(b, " is not vampiric")
end
end
end
testfangs()

View file

@ -0,0 +1,75 @@
local fmt = require "fmt"
require "table2"
local function ndigits(x)
local n = 0
while x > 0 do
n += 1
x //= 10
end
return n
end
local function dtally(x)
local t = 0
while x > 0 do
t += 2 ** ((x % 10) * 6)
x //= 10
end
return t
end
local tens = table.rep(15, 0)
local function init()
tens[1] = 1
for i = 2, 15 do tens[i] = tens[i - 1] * 10 end
end
local function fangs(x)
local f = {}
local nd = ndigits(x)
if nd & 1 == 1 then return f end
nd //= 2
local lo = math.max(tens[nd], (x + tens[nd + 1] - 2) // (tens[nd + 1] - 1))
local hi = math.min(x // lo, math.floor(math.sqrt(x)))
local t = dtally(x)
local a = lo
while a <= hi do
local b = x // a
local t2 = dtally(a) + dtally(b)
if a * b == x and ((a % 10) > 0 or (b % 10) > 0) and t == t2 then
f:insert(a)
end
a += 1
end
return f
end
local function showfangs(x, f)
fmt.write("%6d", x)
if #f > 1 then print() end
for f as a do fmt.print(" = %3d x %3d", a, x // a) end
end
init()
local x = 1
local n = 0
while n < 25 do
local f = fangs(x)
if #f > 0 then
n += 1
fmt.write("%2d: ", n)
showfangs(x, f)
end
x += 1
end
print()
for {16758243290880, 24959017348650, 14593825548650} as y do
local f = fangs(y)
if #f > 0 then
showfangs(y, f)
else
fmt.print("%d is not vampiric", y)
end
end

View file

@ -0,0 +1,85 @@
(
// Usage: ~extract_fangs.(n), where n is a positive integer
//
// Return a list made of all the fangs of n. If n isn't a vampire,
// then an empty list is returned.
// n can be a floating point number as long as its fractional part
// is equal to 0.
~extract_fangs = {
arg n; var out = List[], f, is_fang, f1, f2, i = 0,
nd = [], nr, n_cp = n, k;
// Convert n to an array made of its digits
// > fast method used when n is a 32-bit int or float
nr = n_cp % 1e9;
nd = nr.asInteger.asDigits ++ nd;
n_cp = n_cp - nr;
// > slower method used when n is a 64-bit float
if(n_cp > 0){
n_cp = n; nd = [];
while{n_cp - (10**(i + 1)) > 0}{i = i + 1};
for(0, i){
arg j; k = i - j;
nr = floor(n_cp / (10**k));
nd = nd ++ [nr];
n_cp = n_cp - (nr * (10**k));
};
};
// Even number of digits
if(nd.size % 2 == 1){}{
for(1, floor(sqrt(n))){
arg i; is_fang = true; f = [];
if(n % i == 0){
f = [i, n/i];
}{is_fang = false};
if(is_fang){
f1 = f[0].asInteger.asDigits;
f2 = f[1].asInteger.asDigits;
// Each fang has the same number of digits
if((f1.size != (nd.size/2)) ||
(f2.size != (nd.size/2))){is_fang = false}{
// At most one has a trailing zero
if((f1[f1.size - 1] == 0) &&
(f2[f2.size - 1] == 0)){is_fang = false}{
if((f1 ++ f2).sort != nd.sort)
{is_fang = false}{};
};
};
if(is_fang){out.add(f)}{};
}{};
};
};
out
};
~goal = 25; ~i = 0; ~f;
"25 first vampire numbers
-------------------------------".postln;
while{~goal > 0}{
if((~f = ~extract_fangs.(~i = ~i + 1)) == List[]){}{
~goal = ~goal - 1;
("" ++ (25 - ~goal).asString ++ " is " ++
~i.asString ++ "; fangs: ").post;
~f.postln;
};
};
"\nIndividual tests
-------------------------------".postln;
[16758243290880.0, 24959017348650.0, 14593825548650.0].do{
arg n; n.asString.post;
if((~f = ~extract_fangs.(n)) == List[])
{" isn't a vampire number.".postln;}
{" is a vampire number; fangs: ".post; ~f.postln;};
};
)