Eban numbers
You are encouraged to solve this task according to the task description, using any language you may know.
- Definition
An eban number is a number that has no letter e in it when the number is spelled in English.
Or more literally, spelled numbers that contain the letter e are banned.
The American version of spelling numbers will be used here (as opposed to the British).
2,000,000,000 is two billion, not two milliard.
Only numbers less than one sextillion (1021) will be considered in/for this task.
This will allow optimizations to be used.
- Task
-
- show all eban numbers ≤ 1,000 (in a horizontal format), and a count
- show all eban numbers between 1,000 and 4,000 (inclusive), and a count
- show a count of all eban numbers up and including 10,000
- show a count of all eban numbers up and including 100,000
- show a count of all eban numbers up and including 1,000,000
- show a count of all eban numbers up and including 10,000,000
- show all output here.
- See also
-
- The MathWorld entry: eban numbers.
- The OEIS entry: A6933, eban numbers.
- Number names.
11l
F iseban(n)
I n == 0
R 0B
V (b, r) = divmod(n, 1'000'000'000)
(V m, r) = divmod(r, 1'000'000)
(V t, r) = divmod(r, 1'000)
m = I m C 30..66 {m % 10} E m
t = I t C 30..66 {t % 10} E t
r = I r C 30..66 {r % 10} E r
R Set([b, m, t, r]) <= Set([0, 2, 4, 6])
print(‘eban numbers up to and including 1000:’)
L(i) 0..100
I iseban(i)
print(i, end' ‘ ’)
print("\n\neban numbers between 1000 and 4000 (inclusive):")
L(i) 1000..4000
I iseban(i)
print(i, end' ‘ ’)
print()
L(maxn) (10'000, 100'000, 1'000'000, 10'000'000)
V count = 0
L(i) 0..maxn
I iseban(i)
count++
print("\nNumber of eban numbers up to and including #8: #4".format(maxn, count))
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 Number of eban numbers up to and including 10000: 79 Number of eban numbers up to and including 100000: 399 Number of eban numbers up to and including 1000000: 399 Number of eban numbers up to and including 10000000: 1599
Ada
-- Rosetta Code Task written in Ada
-- Eban numbers
-- https://rosettacode.org/wiki/Eban_numbers
-- Inspired (mostly) by the Nim and Go solutions
-- August 2024, R. B. E.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Eban_Numbers is
function Is_Eban (Candidate : Natural) return Boolean is
N : Natural := Candidate;
B, R, M, T : Natural;
begin
if (N = 0) then
return False;
end if;
B := N / 1_000_000_000;
R := N mod 1_000_000_000;
M := R / 1_000_000;
R := R mod 1_000_000;
T := R / 1_000;
R := R mod 1_000;
case M is
when 30..66 => M := M mod 10;
when others => null;
end case;
case T is
when 30..66 => T := T mod 10;
when others => null;
end case;
case R is
when 30..66 => R := R mod 10;
when others => null;
end case;
if ((B = 0) or (B = 2) or (B = 4) or (B = 6)) then
if ((M = 0) or (M = 2) or (M = 4) or (M = 6)) then
if ((T = 0) or (T = 2) or (T = 4) or (T = 6)) then
if ((R = 0) or (R = 2) or (R = 4) or (R = 6)) then
return True;
else
return False;
end if;
else
return False;
end if;
else
return False;
end if;
else
return False;
end if;
end Is_Eban;
Group_Total : Natural;
Loop_Starts_At, Loop_Stops_At : Natural;
begin
Loop_Starts_At := 0;
Loop_Stops_At := 1_000;
Put ("eban numbers up to and including: ");
Put (Loop_Stops_At, 3);
New_Line;
for I in Loop_Starts_At .. Loop_Stops_At loop
if Is_Eban (I) then
Put (I, 0);
Put (" ");
end if;
end loop;
New_Line (2);
Loop_Starts_At := 1_000;
Loop_Stops_At := 4_000;
Put ("eban numbers between ");
Put (Loop_Starts_At, 3);
Put (" and ");
Put (Loop_Stops_At, 3);
Put_Line (" (inclusive):");
for I in Loop_Starts_At .. Loop_Stops_At loop
if Is_Eban (I) then
Put (I, 0);
Put (" ");
end if;
end loop;
New_Line (2);
Group_Total := 0;
Loop_Starts_At := 0;
Loop_Stops_At := 10_000;
for I in Loop_Starts_At .. Loop_Stops_At loop
if Is_Eban (I) then
Group_Total := Group_Total + 1;
end if;
end loop;
Put ("Number of eban numbers up to and including ");
Put (Loop_Stops_At, 3);
Put (": ");
Put (Group_Total, 4);
New_Line (2);
Group_Total := 0;
Loop_Starts_At := 0;
Loop_Stops_At := 100_000;
for I in Loop_Starts_At .. Loop_Stops_At loop
if Is_Eban (I) then
Group_Total := Group_Total + 1;
end if;
end loop;
Put ("Number of eban numbers up to and including ");
Put (Loop_Stops_At, 3);
Put (": ");
Put (Group_Total, 4);
New_Line (2);
Group_Total := 0;
Loop_Starts_At := 0;
Loop_Stops_At := 1_000_000;
for I in Loop_Starts_At .. Loop_Stops_At loop
if Is_Eban (I) then
Group_Total := Group_Total + 1;
end if;
end loop;
Put ("Number of eban numbers up to and including ");
Put (Loop_Stops_At, 3);
Put (": ");
Put (Group_Total, 4);
New_Line (2);
Group_Total := 0;
Loop_Starts_At := 0;
Loop_Stops_At := 10_000_000;
for I in Loop_Starts_At .. Loop_Stops_At loop
if Is_Eban (I) then
Group_Total := Group_Total + 1;
end if;
end loop;
Put ("Number of eban numbers up to and including ");
Put (Loop_Stops_At, 3);
Put (": ");
Put (Group_Total, 4);
New_Line (2);
Group_Total := 0;
Loop_Starts_At := 0;
Loop_Stops_At := 100_000_000;
for I in Loop_Starts_At .. Loop_Stops_At loop
if Is_Eban (I) then
Group_Total := Group_Total + 1;
end if;
end loop;
Put ("Number of eban numbers up to and including ");
Put (Loop_Stops_At, 3);
Put (": ");
Put (Group_Total, 4);
New_Line (2);
Group_Total := 0;
Loop_Starts_At := 0;
Loop_Stops_At := 1_000_000_000;
for I in Loop_Starts_At .. Loop_Stops_At loop
if Is_Eban (I) then
Group_Total := Group_Total + 1;
end if;
end loop;
Put ("Number of eban numbers up to and including ");
Put (Loop_Stops_At, 3);
Put (": ");
Put (Group_Total, 4);
New_Line (2);
end Eban_Numbers;
- Output:
eban numbers up to and including: 1000 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 Number of eban numbers up to and including 10000: 79 Number of eban numbers up to and including 100000: 399 Number of eban numbers up to and including 1000000: 399 Number of eban numbers up to and including 10000000: 1599 Number of eban numbers up to and including 100000000: 7999 Number of eban numbers up to and including 1000000000: 7999
ALGOL 68
BEGIN # Eban numbers - translated from the Lua and Phix samples #
MODE INTERVAL = STRUCT( INT start, end, BOOL print );
[]INTERVAL intervals = ( ( 2, 1000, TRUE )
, ( 1000, 4000, TRUE )
, ( 2, 10000, FALSE )
, ( 2, 1000000, FALSE )
, ( 2, 10000000, FALSE )
, ( 2, 100000000, FALSE )
, ( 2, 1000000000, FALSE )
);
FOR intp FROM LWB intervals TO UPB intervals DO
INTERVAL intv = intervals[ intp ];
IF start OF intv = 2 THEN
print( ( "eban numbers up to and including ", whole( end OF intv, 0 ), ":" ) )
ELSE
print( ( "eban numbers between ", whole( start OF intv, 0 )
, " and ", whole( end OF intv, 0 ), " (inclusive)"
)
)
FI;
print( ( newline ) );
IF NOT print OF intv THEN
# calculate the count, as in the Phix sample #
# end OF intv must be a power of 10 #
INT p10 := 0;
INT v := end OF intv;
WHILE v > p10 DO
p10 +:= 1;
v OVERAB 10
OD;
INT n = p10 - ( p10 OVER 3 );
INT p5 = n OVER 2;
INT p4 = ( n + 1 ) OVER 2;
print( ( "count = ", whole( ( ( 5 ^ p5 ) * ( 4 ^ p4 ) ) - 1, 0 ), newline ) )
ELSE
# enumerate the eban numbers, as in the Lua and other samples #
INT count := 0;
FOR i FROM start OF intv BY 2 TO end OF intv DO
INT b = i OVER 1 000 000 000;
INT r := i MOD 1 000 000 000;
INT m := r OVER 1 000 000;
r := i MOD 1 000 000;
INT t := r OVER 1 000;
r := r MOD 1 000;
IF m >= 30 AND m <= 66 THEN m MODAB 10 FI;
IF t >= 30 AND t <= 66 THEN t MODAB 10 FI;
IF r >= 30 AND r <= 66 THEN r MODAB 10 FI;
IF b = 0 OR b = 2 OR b = 4 OR b = 6 THEN
IF m = 0 OR m = 2 OR m = 4 OR m = 6 THEN
IF t = 0 OR t = 2 OR t = 4 OR t = 6 THEN
IF r = 0 OR r = 2 OR r = 4 OR r = 6 THEN
print( ( whole( i, 0 ), " " ) );
count +:= 1
FI
FI
FI
FI
OD;
print( ( newline, "count = ", whole( count, 0 ), newline ) )
FI;
print( ( newline ) )
OD
END
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive) 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 eban numbers up to and including 1000000000: count = 7999
AppleScript
(*
Quickly generate all the (positive) eban numbers up to and including the
specified end number, then lose those before the start number.
0 is taken as "zero" rather than as "nought" or "nil".
WARNING: The getEbans() handler returns a potentially very long list of numbers.
Don't let such a list get assigned to a persistent variable or be the end result displayed in an editor!
*)
on getEbans(startNumber, endNumber)
script o
property output : {}
property listCollector : missing value
property temp : missing value
end script
if (startNumber > endNumber) then set {startNumber, endNumber} to {endNumber, startNumber}
-- The range is limited to between 0 and 10^15 to keep within AppleScript's current number precision.
-- Even so, some of the numbers may not /look/ right when displayed in a editor.
set limit to 10 ^ 15 - 1
if (endNumber > limit) then set endNumber to limit
if (startNumber > limit) then set startNumber to limit
-- Initialise the output list with 0 and the sub-1000 ebans, stopping if the end number's reached.
-- The 0's needed for rest of the process, but is removed at the end.
repeat with tens in {0, 30, 40, 50, 60}
repeat with units in {0, 2, 4, 6}
set thisEban to tens + units
if (thisEban ≤ endNumber) then set end of o's output to thisEban
end repeat
end repeat
-- Repeatedly sweep the output list, adding new ebans formed from the addition of those found previously
-- to a suitable power of 1000 times each one. Stop when the end number's reached or exceeded.
-- The output list may become very long and appending items to it individually take forever, so results are
-- collected in short, 1000-item lists, which are concatenated to the output at the end of each sweep.
set sweepLength to (count o's output)
set multiplier to 1000
repeat while (thisEban < endNumber) -- Per sweep.
set o's temp to {}
set o's listCollector to {o's temp}
repeat with i from 2 to sweepLength -- Per eban found already. (Not the 0.)
set baseAmount to (item i of o's output) * multiplier
repeat with j from 1 to sweepLength by 1000 -- Per 1000-item list.
set z to j + 999
if (z > sweepLength) then set z to sweepLength
repeat with k from j to z -- Per new eban.
set thisEban to baseAmount + (item k of o's output)
if (thisEban ≤ endNumber) then set end of o's temp to thisEban
if (thisEban ≥ endNumber) then exit repeat
end repeat
if (thisEban ≥ endNumber) then exit repeat
set o's temp to {}
set end of o's listCollector to o's temp
end repeat
if (thisEban ≥ endNumber) then exit repeat
end repeat
-- Concatentate this sweep's new lists together
set listCount to (count o's listCollector)
repeat until (listCount is 1)
set o's temp to {}
repeat with i from 2 to listCount by 2
set end of o's temp to (item (i - 1) of o's listCollector) & (item i of o's listCollector)
end repeat
if (listCount mod 2 is 1) then set item -1 of o's temp to (end of o's temp) & (end of o's listCollector)
set o's listCollector to o's temp
set o's temp to {}
set listCount to (count o's listCollector)
end repeat
-- Concatenate the result to the output list and prepare to go round again.
set o's output to o's output & (beginning of o's listCollector)
set sweepLength to sweepLength * sweepLength
set multiplier to multiplier * multiplier
end repeat
-- Lose the initial 0 and any ebans before the specified start number.
set resultCount to (count o's output)
if (resultCount is 1) then
set o's output to {}
else
repeat with i from 2 to resultCount
if (item i of o's output ≥ startNumber) then exit repeat
end repeat
set o's output to items i thru resultCount of o's output
end if
if (endNumber = limit) then set end of o's output to "(Limit of AppleScript's number precision.)"
return o's output
end getEbans
-- Task code:
on runTask()
set output to {}
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ", "
set ebans to getEbans(0, 1000)
set end of output to ((count ebans) as text) & " eban numbers between 0 and 1,000:" & (linefeed & " " & ebans)
set ebans to getEbans(1000, 4000)
set end of output to ((count ebans) as text) & " between 1,000 and 4,000:" & (linefeed & " " & ebans)
set end of output to ((count getEbans(0, 10000)) as text) & " up to and including 10,000"
set end of output to ((count getEbans(0, 100000)) as text) & " up to and including 100,000"
set end of output to ((count getEbans(0, 1000000)) as text) & " up to and including 1,000,000"
set end of output to ((count getEbans(0, 10000000)) as text) & " up to and including 10,000,000"
set ebans to getEbans(6.606606602E+10, 1.0E+12)
set end of output to ((count ebans) as text) & " between 66,066,066,020 and 1,000,000,000,000:" & (linefeed & " " & ebans)
set AppleScript's text item delimiters to linefeed
set output to output as text
set AppleScript's text item delimiters to astid
return output
end runTask
runTask()
- Output:
"19 eban numbers between 0 and 1,000:
2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56, 60, 62, 64, 66
21 between 1,000 and 4,000:
2000, 2002, 2004, 2006, 2030, 2032, 2034, 2036, 2040, 2042, 2044, 2046, 2050, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 4000
79 up to and including 10,000
399 up to and including 100,000
399 up to and including 1,000,000
1599 up to and including 10,000,000
16 between 66,066,066,020 and 1,000,000,000,000:
6.606606603E+10, 6.6066066032E+10, 6.6066066034E+10, 6.6066066036E+10, 6.606606604E+10, 6.6066066042E+10, 6.6066066044E+10, 6.6066066046E+10, 6.606606605E+10, 6.6066066052E+10, 6.6066066054E+10, 6.6066066056E+10, 6.606606606E+10, 6.6066066062E+10, 6.6066066064E+10, 6.6066066066E+10"
AutoHotkey
eban_numbers(min, max, show:=0){
counter := 0, output := ""
i := min
while ((i+=2) <= max)
{
b := floor(i / 1000000000)
r := Mod(i, 1000000000)
m := floor(r / 1000000)
r := Mod(i, 1000000)
t := floor(r / 1000)
r := Mod(r, 1000)
if (m >= 30 && m <= 66)
m := Mod(m, 10)
if (t >= 30 && t <= 66)
t := Mod(t, 10)
if (r >= 30 && r <= 66)
r := Mod(r, 10)
if (b = 0 || b = 2 || b = 4 || b = 6)
&& (m = 0 || m = 2 || m = 4 || m = 6)
&& (t = 0 || t = 2 || t = 4 || t = 6)
&& (r = 0 || r = 2 || r = 4 || r = 6)
counter++, (show ? output .= i " " : "")
}
return min "-" max " : " output " Count = " counter
}
Examples:
MsgBox, 262144, , % eban_numbers(0, 1000, 1)
MsgBox, 262144, , % eban_numbers(1000, 4000, 1)
MsgBox, 262144, , % eban_numbers(0, 10000)
MsgBox, 262144, , % eban_numbers(0, 100000)
MsgBox, 262144, , % eban_numbers(0, 1000000)
MsgBox, 262144, , % eban_numbers(0, 100000000)
- Output:
2-1000 : 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 Count = 19 1000-4000 : 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 Count = 21 2-10000 : Count = 79 2-100000 : Count = 399 2-1000000 : Count = 399 2-10000000 : Count = 1599 2-100000000 : Count = 7999
AWK
# syntax: GAWK -f EBAN_NUMBERS.AWK
# converted from FreeBASIC
BEGIN {
main(2,1000,1)
main(1000,4000,1)
main(2,10000,0)
main(2,100000,0)
main(2,1000000,0)
main(2,10000000,0)
main(2,100000000,0)
exit(0)
}
function main(start,stop,printable, b,count,i,m,r,t) {
printf("%d-%d:",start,stop)
for (i=start; i<=stop; i+=2) {
b = int(i / 1000000000)
r = i % 1000000000
m = int(r / 1000000)
r = i % 1000000
t = int(r / 1000)
r = r % 1000
if (m >= 30 && m <= 66) { m %= 10 }
if (t >= 30 && t <= 66) { t %= 10 }
if (r >= 30 && r <= 66) { r %= 10 }
if (x(b) && x(m) && x(t) && x(r)) {
count++
if (printable) {
printf(" %d",i)
}
}
}
printf(" (count=%d)\n",count)
}
function x(n) {
return(n == 0 || n == 2 || n == 4 || n == 6)
}
- Output:
2-1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 (count=19) 1000-4000: 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 (count=21) 2-10000: (count=79) 2-100000: (count=399) 2-1000000: (count=399) 2-10000000: (count=1599) 2-100000000: (count=7999)
BASIC
BASIC256
call eban (2, 1000, 1)
call eban (1000, 4000, 1)
call eban (2, 10000, 0)
call eban (2, 100000, 0)
call eban (2, 1000000, 0)
call eban (2, 10000000, 0)
call eban (2, 100000000, 0)
print "Run time: " + (Msec/1000) + " seconds."
end
subroutine eban (start, ended, printable)
contar = 0
if start = 2 then
print "eban numbers up to and including "; ended; ":"
else
print "eban numbers between "; start; " and "; ended; " (inclusive):"
end if
for i = start to ended step 2
b = int(i / 1000000000)
r = (i % 1000000000)
m = int(r / 1000000)
r = (i % 1000000)
t = int(r / 1000)
r = (r % 1000)
if m >= 30 and m <= 66 then m = (m % 10)
if t >= 30 and t <= 66 then t = (t % 10)
if r >= 30 and r <= 66 then r = (r % 10)
if b = 0 or b = 2 or b = 4 or b = 6 then
if m = 0 or m = 2 or m = 4 or m = 6 then
if t = 0 or t = 2 or t = 4 or t = 6 then
if r = 0 or r = 2 or r = 4 or r = 6 then
if printable then print i + " ";
contar += 1
end if
end if
end if
end if
next i
if printable then print
print "count = "; contar & chr(10)
end subroutine
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 Run time: 565.135 seconds.
Chipmunk Basic
100 cls
110 t0 = timer
120 eban(2,1000,1)
130 eban(1000,4000,1)
140 eban(2,10000,0)
150 eban(2,100000,0)
160 eban(2,1000000,0)
170 eban(2,10000000,0)
180 eban(2,100000000,0)
190 print "Run time: ";(timer-t0);"seconds."
200 end
210 sub eban(start,ended,printable)
220 contar = 0
230 if start = 2 then
240 print "eban numbers up to and including ";ended;":"
250 else
260 print "eban numbers between ";start;"and ";ended;"(inclusive):"
270 endif
280 for i = start to ended step 2
290 b = int(i/1000000000)
300 r = (i mod 1000000000)
310 m = int(r/1000000)
320 r = (i mod 1000000)
330 t = int(r/1000)
340 r = (r mod 1000)
350 if m >= 30 and m <= 66 then m = (m mod 10)
360 if t >= 30 and t <= 66 then t = (t mod 10)
370 if r >= 30 and r <= 66 then r = (r mod 10)
380 if b = 0 or b = 2 or b = 4 or b = 6 then
390 if m = 0 or m = 2 or m = 4 or m = 6 then
400 if t = 0 or t = 2 or t = 4 or t = 6 then
410 if r = 0 or r = 2 or r = 4 or r = 6 then
420 if printable then print i;
430 contar = contar+1
440 endif
450 endif
460 endif
470 endif
480 next i
490 if printable then print
500 print "count = ";contar;chr$(10)
510 end sub
Gambas
Public Sub Main()
Dim tiempo As Float = Timer
eban(2, 1000, 1)
eban(1000, 4000, 1)
eban(2, 10000, 0)
eban(2, 100000, 0)
eban(2, 1000000, 0)
eban(2, 10000000, 0)
eban(2, 100000000, 0)
tiempo = Timer - tiempo
Print "Run time: " & (tiempo) & " seconds."
End
Public Sub eban(start As Integer, ended As Integer, printable As Integer)
Dim count As Integer
Dim i As Long, b As Long, r As Long, m As Long, t As Long
If start = 2 Then
Print "eban numbers up to and including "; ended; ":"
Else
Print "eban numbers between "; start; " and "; ended; " (inclusive):"
End If
count = 0
For i = start To ended Step 2
b = Int(i / 1000000000)
r = (i Mod 1000000000)
m = Int(r / 1000000)
r = (i Mod 1000000)
t = Int(r / 1000)
r = (r Mod 1000)
If m >= 30 And m <= 66 Then m = (m Mod 10)
If t >= 30 And t <= 66 Then t = (t Mod 10)
If r >= 30 And r <= 66 Then r = (r Mod 10)
If b = 0 Or b = 2 Or b = 4 Or b = 6 Then
If m = 0 Or m = 2 Or m = 4 Or m = 6 Then
If t = 0 Or t = 2 Or t = 4 Or t = 6 Then
If r = 0 Or r = 2 Or r = 4 Or r = 6 Then
If printable Then Print i; " ";
count += 1
End If
End If
End If
End If
Next
If printable Then Print
Print "count = "; count & Chr(10)
End
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 Run time: 31.7356444 seconds.
C
#include "stdio.h"
#include "stdbool.h"
#define ARRAY_LEN(a,T) (sizeof(a) / sizeof(T))
struct Interval {
int start, end;
bool print;
};
int main() {
struct Interval intervals[] = {
{2, 1000, true},
{1000, 4000, true},
{2, 10000, false},
{2, 100000, false},
{2, 1000000, false},
{2, 10000000, false},
{2, 100000000, false},
{2, 1000000000, false},
};
int idx;
for (idx = 0; idx < ARRAY_LEN(intervals, struct Interval); ++idx) {
struct Interval intv = intervals[idx];
int count = 0, i;
if (intv.start == 2) {
printf("eban numbers up to and including %d:\n", intv.end);
} else {
printf("eban numbers between %d and %d (inclusive:)", intv.start, intv.end);
}
for (i = intv.start; i <= intv.end; i += 2) {
int b = i / 1000000000;
int r = i % 1000000000;
int m = r / 1000000;
int t;
r = i % 1000000;
t = r / 1000;
r %= 1000;
if (m >= 30 && m <= 66) m %= 10;
if (t >= 30 && t <= 66) t %= 10;
if (r >= 30 && r <= 66) r %= 10;
if (b == 0 || b == 2 || b == 4 || b == 6) {
if (m == 0 || m == 2 || m == 4 || m == 6) {
if (t == 0 || t == 2 || t == 4 || t == 6) {
if (r == 0 || r == 2 || r == 4 || r == 6) {
if (intv.print) printf("%d ", i);
count++;
}
}
}
}
}
if (intv.print) {
printf("\n");
}
printf("count = %d\n\n", count);
}
return 0;
}
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive:)2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 eban numbers up to and including 1000000000: count = 7999
C#
using System;
namespace EbanNumbers {
struct Interval {
public int start, end;
public bool print;
public Interval(int start, int end, bool print) {
this.start = start;
this.end = end;
this.print = print;
}
}
class Program {
static void Main() {
Interval[] intervals = {
new Interval(2, 1_000, true),
new Interval(1_000, 4_000, true),
new Interval(2, 10_000, false),
new Interval(2, 100_000, false),
new Interval(2, 1_000_000, false),
new Interval(2, 10_000_000, false),
new Interval(2, 100_000_000, false),
new Interval(2, 1_000_000_000, false),
};
foreach (var intv in intervals) {
if (intv.start == 2) {
Console.WriteLine("eban numbers up to and including {0}:", intv.end);
} else {
Console.WriteLine("eban numbers between {0} and {1} (inclusive):", intv.start, intv.end);
}
int count = 0;
for (int i = intv.start; i <= intv.end; i += 2) {
int b = i / 1_000_000_000;
int r = i % 1_000_000_000;
int m = r / 1_000_000;
r = i % 1_000_000;
int t = r / 1_000;
r %= 1_000;
if (m >= 30 && m <= 66) m %= 10;
if (t >= 30 && t <= 66) t %= 10;
if (r >= 30 && r <= 66) r %= 10;
if (b == 0 || b == 2 || b == 4 || b == 6) {
if (m == 0 || m == 2 || m == 4 || m == 6) {
if (t == 0 || t == 2 || t == 4 || t == 6) {
if (r == 0 || r == 2 || r == 4 || r == 6) {
if (intv.print) Console.Write("{0} ", i);
count++;
}
}
}
}
}
if (intv.print) {
Console.WriteLine();
}
Console.WriteLine("count = {0}\n", count);
}
}
}
}
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 eban numbers up to and including 1000000000: count = 7999
C++
#include <iostream>
struct Interval {
int start, end;
bool print;
};
int main() {
Interval intervals[] = {
{2, 1000, true},
{1000, 4000, true},
{2, 10000, false},
{2, 100000, false},
{2, 1000000, false},
{2, 10000000, false},
{2, 100000000, false},
{2, 1000000000, false},
};
for (auto intv : intervals) {
if (intv.start == 2) {
std::cout << "eban numbers up to and including " << intv.end << ":\n";
} else {
std::cout << "eban numbers bwteen " << intv.start << " and " << intv.end << " (inclusive):\n";
}
int count = 0;
for (int i = intv.start; i <= intv.end; i += 2) {
int b = i / 1000000000;
int r = i % 1000000000;
int m = r / 1000000;
r = i % 1000000;
int t = r / 1000;
r %= 1000;
if (m >= 30 && m <= 66) m %= 10;
if (t >= 30 && t <= 66) t %= 10;
if (r >= 30 && r <= 66) r %= 10;
if (b == 0 || b == 2 || b == 4 || b == 6) {
if (m == 0 || m == 2 || m == 4 || m == 6) {
if (t == 0 || t == 2 || t == 4 || t == 6) {
if (r == 0 || r == 2 || r == 4 || r == 6) {
if (intv.print) std::cout << i << ' ';
count++;
}
}
}
}
}
if (intv.print) {
std::cout << '\n';
}
std::cout << "count = " << count << "\n\n";
}
return 0;
}
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers bwteen 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 eban numbers up to and including 1000000000: count = 7999
CLU
eban = cluster is numbers
rep = null
% Next valid E-ban number in the range [0..999]
next = proc (n: int) returns (int) signals (no_more)
if n>=66 then signal no_more end
if n<0 then return(0) end
% advance low digit (two four six)
if (n//10=0) then n := (n/10)*10 + 2
elseif (n//10=2) then n := (n/10)*10 + 4
elseif (n//10=4) then n := (n/10)*10 + 6
elseif (n//10=6) then n := (n/10)*10 + 10
end
% this might put us into tEn, twEnty which are invalid
if (n//100/10 = 1) then n := n + 20 % ten + 20 = 30
elseif (n//100/10 = 2) then n := n + 10 % twEnty + 10 = 30
end
return(n)
end next
% Yield all valid E_ban numbers
% (sextillion and upwards aren't handled)
numbers = iter () yields (int)
parts: array[int] := array[int]$[0: 2]
while true do
num: int := 0
for m: int in array[int]$indexes(parts) do
num := num + parts[m] * 1000 ** m
end
yield(num)
for m: int in array[int]$indexes(parts) do
begin
parts[m] := next(parts[m])
break
end except when no_more:
parts[m] := 0
end
end
if array[int]$top(parts) = 0 then
array[int]$addh(parts,2)
end
end
end numbers
end eban
start_up = proc ()
maxmagn = 1000000000000
po: stream := stream$primary_output()
count: int := 0
upto_1k: int := 0
between_1k_4k: int := 0
disp_1k: bool := false
disp_4k: bool := false
nextmagn: int := 10000
for i: int in eban$numbers() do
while i>nextmagn do
stream$putl(po, int$unparse(count)
|| " eban numbers <= "
|| int$unparse(nextmagn))
nextmagn := nextmagn * 10
end
count := count + 1
if i<1000 then upto_1k := upto_1k + 1
elseif i<=4000 then between_1k_4k := between_1k_4k + 1
end
if i>1000 & ~disp_1k then
disp_1k := true
stream$putl(po, "\n" || int$unparse(upto_1k)
|| " eban numbers <= 1000\n")
end
if i<=4000 then stream$putright(po, int$unparse(i), 5) end
if i>4000 & ~disp_4k then
disp_4k := true
stream$putl(po, "\n" || int$unparse(between_1k_4k)
|| " eban numbers 1000 <= x <= 4000\n")
end
if nextmagn>maxmagn then break end
end
end start_up
- Output:
2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 19 eban numbers <= 1000 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 21 eban numbers 1000 <= x <= 4000 79 eban numbers <= 10000 399 eban numbers <= 100000 399 eban numbers <= 1000000 1599 eban numbers <= 10000000 7999 eban numbers <= 100000000 7999 eban numbers <= 1000000000 31999 eban numbers <= 10000000000 159999 eban numbers <= 100000000000 159999 eban numbers <= 1000000000000
D
import std.stdio;
struct Interval {
int start, end;
bool print;
}
void main() {
Interval[] intervals = [
{2, 1_000, true},
{1_000, 4_000, true},
{2, 10_000, false},
{2, 100_000, false},
{2, 1_000_000, false},
{2, 10_000_000, false},
{2, 100_000_000, false},
{2, 1_000_000_000, false},
];
foreach (intv; intervals) {
if (intv.start == 2) {
writeln("eban numbers up to an including ", intv.end, ':');
} else {
writeln("eban numbers between ", intv.start ," and ", intv.end, " (inclusive):");
}
int count;
for (int i = intv.start; i <= intv.end; i = i + 2) {
int b = i / 1_000_000_000;
int r = i % 1_000_000_000;
int m = r / 1_000_000;
r = i % 1_000_000;
int t = r / 1_000;
r %= 1_000;
if (m >= 30 && m <= 66) m %= 10;
if (t >= 30 && t <= 66) t %= 10;
if (r >= 30 && r <= 66) r %= 10;
if (b == 0 || b == 2 || b == 4 || b == 6) {
if (m == 0 || m == 2 || m == 4 || m == 6) {
if (t == 0 || t == 2 || t == 4 || t == 6) {
if (r == 0 || r == 2 || r == 4 || r == 6) {
if (intv.print) write(i, ' ');
count++;
}
}
}
}
}
if (intv.print) {
writeln();
}
writeln("count = ", count);
writeln;
}
}
- Output:
eban numbers up to an including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to an including 10000: count = 79 eban numbers up to an including 100000: count = 399 eban numbers up to an including 1000000: count = 399 eban numbers up to an including 10000000: count = 1599 eban numbers up to an including 100000000: count = 7999 eban numbers up to an including 1000000000: count = 7999
EasyLang
func x n .
if n = 0 or n = 2 or n = 4 or n = 6
return 1
.
.
proc go start stop printable . .
write start & " - " & stop & ":"
for i = start step 2 to stop
b = i div 1000000000
r = i mod 1000000000
m = r div 1000000
r = i mod 1000000
t = r div 1000
r = r mod 1000
if m >= 30 and m <= 66
m = m mod 10
.
if t >= 30 and t <= 66
t = t mod 10
.
if r >= 30 and r <= 66
r = r mod 10
.
if x b = 1 and x m = 1 and x t = 1 and x r = 1
count += 1
if printable = 1
write " " & i
.
.
.
print " (count=" & count & ")"
.
go 2 1000 1
go 1000 4000 1
go 2 10000 0
go 2 100000 0
go 2 1000000 0
go 2 10000000 0
go 2 100000000 0
Factor
USING: arrays formatting fry io kernel math math.functions
math.order math.ranges prettyprint sequences ;
: eban? ( n -- ? )
1000000000 /mod 1000000 /mod 1000 /mod
[ dup 30 66 between? [ 10 mod ] when ] tri@ 4array
[ { 0 2 4 6 } member? ] all? ;
: .eban ( m n -- ) "eban numbers in [%d, %d]: " printf ;
: eban ( m n q -- o ) '[ 2dup .eban [a,b] [ eban? ] @ ] call ; inline
: .eban-range ( m n -- ) [ filter ] eban "%[%d, %]\n" printf ;
: .eban-count ( m n -- ) "count of " write [ count ] eban . ;
1 1000 1000 4000 [ .eban-range ] 2bi@
4 9 [a,b] [ [ 1 10 ] dip ^ .eban-count ] each
- Output:
eban numbers in [1, 1000]: { 2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56, 60, 62, 64, 66 } eban numbers in [1000, 4000]: { 2000, 2002, 2004, 2006, 2030, 2032, 2034, 2036, 2040, 2042, 2044, 2046, 2050, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 4000 } count of eban numbers in [1, 10000]: 79 count of eban numbers in [1, 100000]: 399 count of eban numbers in [1, 1000000]: 399 count of eban numbers in [1, 10000000]: 1599 count of eban numbers in [1, 100000000]: 7999 count of eban numbers in [1, 1000000000]: 7999
FreeBASIC
' Eban_numbers
' Un número eban es un número que no tiene la letra e cuando el número está escrito en inglés.
' O más literalmente, los números escritos que contienen la letra e están prohibidos.
'
' Usaremos la versión americana de los números de ortografía (a diferencia de los británicos).
' 2000000000 son dos billones, no dos millardos (mil millones).
'
Data 2, 1000, 1
Data 1000, 4000, 1
Data 2, 10000, 0
Data 2, 100000, 0
Data 2, 1000000, 0
Data 2, 10000000, 0
Data 2, 100000000, 0
Data 0, 0, 0
Dim As Double tiempo = Timer
Dim As Integer start, ended, printable, count
Dim As Long i, b, r, m, t
Do
Read start, ended, printable
If start = 0 Then Exit Do
If start = 2 Then
Print "eban numbers up to and including"; ended; ":"
Else
Print "eban numbers between "; start; " and "; ended; " (inclusive):"
End If
count = 0
For i = start To ended Step 2
b = Int(i / 1000000000)
r = (i Mod 1000000000)
m = Int(r / 1000000)
r = (i Mod 1000000)
t = Int(r / 1000)
r = (r Mod 1000)
If m >= 30 And m <= 66 Then m = (m Mod 10)
If t >= 30 And t <= 66 Then t = (t Mod 10)
If r >= 30 And r <= 66 Then r = (r Mod 10)
If b = 0 Or b = 2 Or b = 4 Or b = 6 Then
If m = 0 Or m = 2 Or m = 4 Or m = 6 Then
If t = 0 Or t = 2 Or t = 4 Or t = 6 Then
If r = 0 Or r = 2 Or r = 4 Or r = 6 Then
If printable Then Print i;
count += 1
End If
End If
End If
End If
Next i
If printable Then Print
Print "count = "; count & Chr(10)
Loop
tiempo = Timer - tiempo
Print "Run time: " & (tiempo) & " seconds."
End
- Output:
eban numbers up to and including 100: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 Run time: 1.848286400010693 seconds.
Fōrmulæ
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.
Programs in Fōrmulæ are created/edited online in its website.
In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.
Go
package main
import "fmt"
type Range struct {
start, end uint64
print bool
}
func main() {
rgs := []Range{
{2, 1000, true},
{1000, 4000, true},
{2, 1e4, false},
{2, 1e5, false},
{2, 1e6, false},
{2, 1e7, false},
{2, 1e8, false},
{2, 1e9, false},
}
for _, rg := range rgs {
if rg.start == 2 {
fmt.Printf("eban numbers up to and including %d:\n", rg.end)
} else {
fmt.Printf("eban numbers between %d and %d (inclusive):\n", rg.start, rg.end)
}
count := 0
for i := rg.start; i <= rg.end; i += 2 {
b := i / 1000000000
r := i % 1000000000
m := r / 1000000
r = i % 1000000
t := r / 1000
r %= 1000
if m >= 30 && m <= 66 {
m %= 10
}
if t >= 30 && t <= 66 {
t %= 10
}
if r >= 30 && r <= 66 {
r %= 10
}
if b == 0 || b == 2 || b == 4 || b == 6 {
if m == 0 || m == 2 || m == 4 || m == 6 {
if t == 0 || t == 2 || t == 4 || t == 6 {
if r == 0 || r == 2 || r == 4 || r == 6 {
if rg.print {
fmt.Printf("%d ", i)
}
count++
}
}
}
}
}
if rg.print {
fmt.Println()
}
fmt.Println("count =", count, "\n")
}
}
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 eban numbers up to and including 1000000000: count = 7999
Groovy
class Main {
private static class Range {
int start
int end
boolean print
Range(int s, int e, boolean p) {
start = s
end = e
print = p
}
}
static void main(String[] args) {
List<Range> rgs = Arrays.asList(
new Range(2, 1000, true),
new Range(1000, 4000, true),
new Range(2, 10_000, false),
new Range(2, 100_000, false),
new Range(2, 1_000_000, false),
new Range(2, 10_000_000, false),
new Range(2, 100_000_000, false),
new Range(2, 1_000_000_000, false)
)
for (Range rg : rgs) {
if (rg.start == 2) {
println("eban numbers up to and including $rg.end")
} else {
println("eban numbers between $rg.start and $rg.end")
}
int count = 0
for (int i = rg.start; i <= rg.end; ++i) {
int b = (int) (i / 1_000_000_000)
int r = i % 1_000_000_000
int m = (int) (r / 1_000_000)
r = i % 1_000_000
int t = (int) (r / 1_000)
r %= 1_000
if (m >= 30 && m <= 66) m %= 10
if (t >= 30 && t <= 66) t %= 10
if (r >= 30 && r <= 66) r %= 10
if (b == 0 || b == 2 || b == 4 || b == 6) {
if (m == 0 || m == 2 || m == 4 || m == 6) {
if (t == 0 || t == 2 || t == 4 || t == 6) {
if (r == 0 || r == 2 || r == 4 || r == 6) {
if (rg.print) {
print("$i ")
}
count++
}
}
}
}
}
if (rg.print) {
println()
}
println("count = $count")
println()
}
}
}
- Output:
Same as the Java entry
Haskell
{-# LANGUAGE NumericUnderscores #-}
import Data.List (intercalate)
import Text.Printf (printf)
import Data.List.Split (chunksOf)
isEban :: Int -> Bool
isEban n = all (`elem` [0, 2, 4, 6]) z
where
(b, r1) = n `quotRem` (10 ^ 9)
(m, r2) = r1 `quotRem` (10 ^ 6)
(t, r3) = r2 `quotRem` (10 ^ 3)
z = b : map (\x -> if x >= 30 && x <= 66 then x `mod` 10 else x) [m, t, r3]
ebans = map f
where
f x = (thousands x, thousands $ length $ filter isEban [1..x])
thousands:: Int -> String
thousands = reverse . intercalate "," . chunksOf 3 . reverse . show
main :: IO ()
main = do
uncurry (printf "eban numbers up to and including 1000: %2s\n%s\n\n") $ r [1..1000]
uncurry (printf "eban numbers between 1000 and 4000: %2s\n%s\n\n") $ r [1000..4000]
mapM_ (uncurry (printf "eban numbers up and including %13s: %5s\n")) ebanCounts
where
ebanCounts = ebans [ 10_000
, 100_000
, 1_000_000
, 10_000_000
, 100_000_000
, 1_000_000_000 ]
r = ((,) <$> thousands . length <*> show) . filter isEban
- Output:
eban numbers up to and including 1000: 19 [2,4,6,30,32,34,36,40,42,44,46,50,52,54,56,60,62,64,66] eban numbers between 1000 and 4000: 21 [2000,2002,2004,2006,2030,2032,2034,2036,2040,2042,2044,2046,2050,2052,2054,2056,2060,2062,2064,2066,4000] eban numbers up and including 10,000: 79 eban numbers up and including 100,000: 399 eban numbers up and including 1,000,000: 399 eban numbers up and including 10,000,000: 1,599 eban numbers up and including 100,000,000: 7,999 eban numbers up and including 1,000,000,000: 7,999
J
Filter =: (#~`)(`:6)
itemAmend =: (29&< *. <&67)`(,: 10&|)}
iseban =: [: *./ 0 2 4 6 e.~ [: itemAmend [: |: (4#1000)&#:
(;~ #) iseban Filter >: i. 1000
┌──┬─────────────────────────────────────────────────────┐
│19│2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66│
└──┴─────────────────────────────────────────────────────┘
NB. INPUT are the correct integers, head and tail shown
({. , {:) INPUT =: 1000 + i. 3001
1000 4000
(;~ #) iseban Filter INPUT
┌──┬────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│21│2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000│
└──┴────────────────────────────────────────────────────────────────────────────────────────────────────────┘
(, ([: +/ [: iseban [: >: i.))&> 10000 * 10 ^ i. +:2
10000 79
100000 399
1e6 399
1e7 1599
Alternatively we could construct a sequence of eban numbers sufficient to satisfy some limit and then filter out any which exceed our limit:
ebanseq=: {{ (#~ y>:])}.,@([+/~1000*])^:(6<.<.1000^.y)~(,0 2 4 6+/~10*0 3 4 5 6) }}
(,:&":~ #) ebanseq 1000
19
2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66
(,:&":~ #) (#~ 1000<])ebanseq 4000
21
2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000
# ebanseq 1e4
79
# ebanseq 1e5
399
# ebanseq 1e6
399
# ebanseq 1e7
1599
# ebanseq 1e8
7999
# ebanseq 1e9
7999
# ebanseq 1e10
31999
# ebanseq 1e11
159999
# ebanseq 1e12
159999
# ebanseq 1e13
639999
# ebanseq 1e14
3199999
# ebanseq 1e15
3199999
# ebanseq 1e16
12799999
# ebanseq 1e17
63999999
Java
import java.util.List;
public class Main {
private static class Range {
int start;
int end;
boolean print;
public Range(int s, int e, boolean p) {
start = s;
end = e;
print = p;
}
}
public static void main(String[] args) {
List<Range> rgs = List.of(
new Range(2, 1000, true),
new Range(1000, 4000, true),
new Range(2, 10_000, false),
new Range(2, 100_000, false),
new Range(2, 1_000_000, false),
new Range(2, 10_000_000, false),
new Range(2, 100_000_000, false),
new Range(2, 1_000_000_000, false)
);
for (Range rg : rgs) {
if (rg.start == 2) {
System.out.printf("eban numbers up to and including %d\n", rg.end);
} else {
System.out.printf("eban numbers between %d and %d\n", rg.start, rg.end);
}
int count = 0;
for (int i = rg.start; i <= rg.end; ++i) {
int b = i / 1_000_000_000;
int r = i % 1_000_000_000;
int m = r / 1_000_000;
r = i % 1_000_000;
int t = r / 1_000;
r %= 1_000;
if (m >= 30 && m <= 66) m %= 10;
if (t >= 30 && t <= 66) t %= 10;
if (r >= 30 && r <= 66) r %= 10;
if (b == 0 || b == 2 || b == 4 || b == 6) {
if (m == 0 || m == 2 || m == 4 || m == 6) {
if (t == 0 || t == 2 || t == 4 || t == 6) {
if (r == 0 || r == 2 || r == 4 || r == 6) {
if (rg.print) System.out.printf("%d ", i);
count++;
}
}
}
}
}
if (rg.print) {
System.out.println();
}
System.out.printf("count = %d\n\n", count);
}
}
}
- Output:
eban numbers up to and including 1000 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000 count = 79 eban numbers up to and including 100000 count = 399 eban numbers up to and including 1000000 count = 399 eban numbers up to and including 10000000 count = 1599 eban numbers up to and including 100000000 count = 7999 eban numbers up to and including 1000000000 count = 7999
jq
Adapted from Julia and Wren
Works with gojq, the Go implementation of jq (*)
(*) gojq's memory requirements are rather extravagent and may prevent completion of the task beyond 1E+7; the output shown below was obtained using the C implementation of jq.
# quotient and remainder
def quotient($a; $b; f; g): f = (($a/$b)|floor) | g = $a % $b;
def tasks:
[2, 1000, true],
[1000, 4000, true],
(1e4, 1e5, 1e6, 1e7, 1e8 | [2, ., false]) ;
def task:
def update(f): if (f >= 30 and f <= 66) then f %= 10 else . end;
tasks as $rg
| if $rg[0] == 2
then "eban numbers up to and including \($rg[1]):"
else "eban numbers between \($rg[0]) and \($rg[1]) (inclusive):"
end,
( foreach (range( $rg[0]; 1 + $rg[1]; 2), null) as $i ( { count: 0 };
.emit = false
| if $i == null then .total = .count
else quotient($i; 1e9; .b; .r)
| quotient(.r; 1e6; .m; .r)
| quotient(.r; 1e3; .t; .r)
| update(.m) | update(.t) | update(.r)
| if all(.b, .m, .t, .r; IN(0, 2, 4, 6))
then .count += 1
| if ($rg[2]) then .emit=$i else . end
else .
end
end;
if .emit then .emit else empty end,
if .total then "count = \(.count)\n" else empty end) );
task
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 1E+4: count = 79 eban numbers up to and including 1E+5: count = 399 eban numbers up to and including 1E+6: count = 399 eban numbers up to and including 1E+7: count = 1599 eban numbers up to and including 1E+8: count = 7999
Julia
function iseban(n::Integer)
b, r = divrem(n, oftype(n, 10 ^ 9))
m, r = divrem(r, oftype(n, 10 ^ 6))
t, r = divrem(r, oftype(n, 10 ^ 3))
m, t, r = (30 <= x <= 66 ? x % 10 : x for x in (m, t, r))
return all(in((0, 2, 4, 6)), (b, m, t, r))
end
println("eban numbers up to and including 1000:")
println(join(filter(iseban, 1:100), ", "))
println("eban numbers between 1000 and 4000 (inclusive):")
println(join(filter(iseban, 1000:4000), ", "))
println("eban numbers up to and including 10000: ", count(iseban, 1:10000))
println("eban numbers up to and including 100000: ", count(iseban, 1:100000))
println("eban numbers up to and including 1000000: ", count(iseban, 1:1000000))
println("eban numbers up to and including 10000000: ", count(iseban, 1:10000000))
println("eban numbers up to and including 100000000: ", count(iseban, 1:100000000))
println("eban numbers up to and including 1000000000: ", count(iseban, 1:1000000000))
- Output:
eban numbers up to and including 1000: 2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56, 60, 62, 64, 66 eban numbers between 1000 and 4000 (inclusive): 2000, 2002, 2004, 2006, 2030, 2032, 2034, 2036, 2040, 2042, 2044, 2046, 2050, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 4000 eban numbers up to and including 10000: 79 eban numbers up to and including 100000: 399 eban numbers up to and including 1000000: 399 eban numbers up to and including 10000000: 1599 eban numbers up to and including 100000000: 7999 eban numbers up to and including 1000000000: 7999
K
eban: {1_((x<)_,/(,/(2*!4)+/:10*0,3+!4)+/:1000*)/0}@_:
#eban 1000
19
#(1000>)_eban 4000
21
#eban 1e4
79
#eban 1e5
399
#eban 1e6
399
#eban 1e7
1599
#eban 1e8
7999
#eban 1e9
7999
#eban 1e10
31999
#eban 1e11
159999
#eban 1e12
159999
#eban 1e13
639999
#eban 1e14
3199999
Kotlin
// Version 1.3.21
typealias Range = Triple<Int, Int, Boolean>
fun main() {
val rgs = listOf<Range>(
Range(2, 1000, true),
Range(1000, 4000, true),
Range(2, 10_000, false),
Range(2, 100_000, false),
Range(2, 1_000_000, false),
Range(2, 10_000_000, false),
Range(2, 100_000_000, false),
Range(2, 1_000_000_000, false)
)
for (rg in rgs) {
val (start, end, prnt) = rg
if (start == 2) {
println("eban numbers up to and including $end:")
} else {
println("eban numbers between $start and $end (inclusive):")
}
var count = 0
for (i in start..end step 2) {
val b = i / 1_000_000_000
var r = i % 1_000_000_000
var m = r / 1_000_000
r = i % 1_000_000
var t = r / 1_000
r %= 1_000
if (m >= 30 && m <= 66) m %= 10
if (t >= 30 && t <= 66) t %= 10
if (r >= 30 && r <= 66) r %= 10
if (b == 0 || b == 2 || b == 4 || b == 6) {
if (m == 0 || m == 2 || m == 4 || m == 6) {
if (t == 0 || t == 2 || t == 4 || t == 6) {
if (r == 0 || r == 2 || r == 4 || r == 6) {
if (prnt) print("$i ")
count++
}
}
}
}
}
if (prnt) println()
println("count = $count\n")
}
}
- Output:
Same as Go example.
Lua
function makeInterval(s,e,p)
return {start=s, end_=e, print_=p}
end
function main()
local intervals = {
makeInterval( 2, 1000, true),
makeInterval(1000, 4000, true),
makeInterval( 2, 10000, false),
makeInterval( 2, 1000000, false),
makeInterval( 2, 10000000, false),
makeInterval( 2, 100000000, false),
makeInterval( 2, 1000000000, false)
}
for _,intv in pairs(intervals) do
if intv.start == 2 then
print("eban numbers up to and including " .. intv.end_ .. ":")
else
print("eban numbers between " .. intv.start .. " and " .. intv.end_ .. " (inclusive)")
end
local count = 0
for i=intv.start,intv.end_,2 do
local b = math.floor(i / 1000000000)
local r = i % 1000000000
local m = math.floor(r / 1000000)
r = i % 1000000
local t = math.floor(r / 1000)
r = r % 1000
if m >= 30 and m <= 66 then m = m % 10 end
if t >= 30 and t <= 66 then t = t % 10 end
if r >= 30 and r <= 66 then r = r % 10 end
if b == 0 or b == 2 or b == 4 or b == 6 then
if m == 0 or m == 2 or m == 4 or m == 6 then
if t == 0 or t == 2 or t == 4 or t == 6 then
if r == 0 or r == 2 or r == 4 or r == 6 then
if intv.print_ then io.write(i .. " ") end
count = count + 1
end
end
end
end
end
if intv.print_ then
print()
end
print("count = " .. count)
print()
end
end
main()
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive) 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 eban numbers up to and including 1000000000: count = 7999
Mathematica /Wolfram Language
ClearAll[ZeroTwoFourSixQ, EbanNumbers]
ZeroTwoFourSixQ[n_Integer] := (n == 0 || n == 2 || n == 4 || n == 6)
EbanNumbers[min_, max_, show : (False | True)] :=
Module[{counter, output, i, b, r, t, m},
counter = 0;
output = "";
i = min;
While[(i += 2) <= max,
{b, r} = QuotientRemainder[i, 10^9];
{m, r} = QuotientRemainder[r, 10^6];
{t, r} = QuotientRemainder[r, 10^3];
If[30 <= m <= 66,
m = Mod[m, 10];
];
If[30 <= t <= 66,
t = Mod[t, 10];
];
If[30 <= r <= 66,
r = Mod[r, 10];
];
If[ZeroTwoFourSixQ[b] && ZeroTwoFourSixQ[m] && ZeroTwoFourSixQ[t] &&
ZeroTwoFourSixQ[r],
counter++;
If[show,
output = output <> ToString[i] <> " ";
]
]
];
Print[min, "-", max, ": ", output, " count = ", counter]
]
EbanNumbers[0, 1000, True]
EbanNumbers[1000, 4000, True]
EbanNumbers[0, 10^4, False]
EbanNumbers[0, 10^5, False]
EbanNumbers[0, 10^6, False]
EbanNumbers[0, 10^7, False]
- Output:
0-1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 1000-4000: 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 0-10000: count = 79 0-100000: count = 399 0-1000000: count = 399 0-10000000: count = 1599
Nim
Exhaustive search
import strformat
proc iseban(n: int): bool =
if n == 0:
return false
var b = n div 1_000_000_000
var r = n mod 1_000_000_000
var m = r div 1_000_000
r = r mod 1_000_000
var t = r div 1_000
r = r mod 1_000
m = if m in 30..66: m mod 10 else: m
t = if t in 30..66: t mod 10 else: t
r = if r in 30..66: r mod 10 else: r
return {b, m, t, r} <= {0, 2, 4, 6}
echo "eban numbers up to and including 1000:"
for i in 0..100:
if iseban(i):
stdout.write(&"{i} ")
echo "\n\neban numbers between 1000 and 4000 (inclusive):"
for i in 1_000..4_000:
if iseban(i):
stdout.write(&"{i} ")
var count = 0
for i in 0..10_000:
if iseban(i):
inc count
echo &"\n\nNumber of eban numbers up to and including {10000:8}: {count:4}"
count = 0
for i in 0..100_000:
if iseban(i):
inc count
echo &"\nNumber of eban numbers up to and including {100000:8}: {count:4}"
count = 0
for i in 0..1_000_000:
if iseban(i):
inc count
echo &"\nNumber of eban numbers up to and including {1000000:8}: {count:4}"
count = 0
for i in 0..10_000_000:
if iseban(i):
inc count
echo &"\nNumber of eban numbers up to and including {10000000:8}: {count:4}"
count = 0
for i in 0..100_000_000:
if iseban(i):
inc count
echo &"\nNumber of eban numbers up to and including {100000000:8}: {count:4}"
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 Number of eban numbers up to and including 10000: 79 Number of eban numbers up to and including 100000: 399 Number of eban numbers up to and including 1000000: 399 Number of eban numbers up to and including 10000000: 1599
Algorithmic computation
import math, strutils, strformat
#---------------------------------------------------------------------------------------------------
func ebanCount(p10: Natural): Natural =
## Return the count of eban numbers 1..10^p10.
let
n = p10 - p10 div 3
p5 = n div 2
p4 = (n + 1) div 2
result = 5^p5 * 4^p4 - 1
#---------------------------------------------------------------------------------------------------
func eban(n: Natural): bool =
## Return true if n is an eban number (only fully tested to 10e9).
if n == 0: return false
var n = n
while n != 0:
let thou = n mod 1000
if thou div 100 != 0: return false
if thou div 10 notin {0, 3, 4, 5, 6}: return false
if thou mod 10 notin {0, 2, 4, 6}: return false
n = n div 1000
result = true
#———————————————————————————————————————————————————————————————————————————————————————————————————
var s: seq[Natural]
for i in 0..1000:
if eban(i): s.add(i)
echo fmt"Eban to 1000: {s.join("", "")} ({s.len} items)"
s.setLen(0)
for i in 1000..4000:
if eban(i): s.add(i)
echo fmt"Eban 1000..4000: {s.join("", "")} ({s.len} items)"
import times
let t0 = getTime()
for i in 0..21:
echo fmt"ebanCount(10^{i}): {ebanCount(i)}"
echo ""
echo fmt"Time: {getTime() - t0}"
- Output:
Eban to 1000: 2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56, 60, 62, 64, 66 (19 items) Eban 1000..4000: 2000, 2002, 2004, 2006, 2030, 2032, 2034, 2036, 2040, 2042, 2044, 2046, 2050, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 4000 (21 items) ebanCount(10^0): 0 ebanCount(10^1): 3 ebanCount(10^2): 19 ebanCount(10^3): 19 ebanCount(10^4): 79 ebanCount(10^5): 399 ebanCount(10^6): 399 ebanCount(10^7): 1599 ebanCount(10^8): 7999 ebanCount(10^9): 7999 ebanCount(10^10): 31999 ebanCount(10^11): 159999 ebanCount(10^12): 159999 ebanCount(10^13): 639999 ebanCount(10^14): 3199999 ebanCount(10^15): 3199999 ebanCount(10^16): 12799999 ebanCount(10^17): 63999999 ebanCount(10^18): 63999999 ebanCount(10^19): 255999999 ebanCount(10^20): 1279999999 ebanCount(10^21): 1279999999 Time: 189 microseconds and 491 nanoseconds
Odin
package eban_numbers
/* imports */
import "core:fmt"
/* globals */
Range :: struct {
start: i32,
end: i32,
print: bool,
}
printcounter: i32 = 0
/* main block */
main :: proc() {
rgs := [?]Range{
{2, 1000, true},
{1000, 4000, true},
{2, 1e4, false},
{2, 1e5, false},
{2, 1e6, false},
{2, 1e7, false},
{2, 1e8, false},
{2, 1e9, false},
}
for rg in rgs {
if rg.start == 2 {
fmt.printf("eban numbers up to and including %d:\n", rg.end)
} else {
fmt.printf("eban numbers between %d and %d (inclusive):\n", rg.start, rg.end)
}
count := i32(0)
for i := rg.start; i <= i32(rg.end); i += i32(2) {
b := i / 1000000000
r := i % 1000000000
m := r / 1000000
r = i % 1000000
t := r / 1000
r %= 1000
if m >= 30 && m <= 66 {
m %= 10
}
if t >= 30 && t <= 66 {
t %= 10
}
if r >= 30 && r <= 66 {
r %= 10
}
if b == 0 || b == 2 || b == 4 || b == 6 {
if m == 0 || m == 2 || m == 4 || m == 6 {
if t == 0 || t == 2 || t == 4 || t == 6 {
if r == 0 || r == 2 || r == 4 || r == 6 {
if rg.print {
fmt.printf("%d ", i)
}
count += 1
}
}
}
}
}
if rg.print {
fmt.println()
}
fmt.println("count =", count, "\n")
}
}
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 eban numbers up to and including 1000000000: count = 7999
Perl
Exhaustive search
A couple of 'e'-specific optimizations keep the running time reasonable.
use strict;
use warnings;
use feature 'say';
use Lingua::EN::Numbers qw(num2en);
sub comma { reverse ((reverse shift) =~ s/(.{3})/$1,/gr) =~ s/^,//r }
sub e_ban {
my($power) = @_;
my @n;
for (1..10**$power) {
next unless 0 == $_%2;
next if $_ =~ /[789]/ or /[12].$/ or /[135]..$/ or /[135]...$/ or /[135].....$/;
push @n, $_ unless num2en($_) =~ /e/;
}
@n;
}
my @OK = e_ban(my $max = 7);
my @a = grep { $_ <= 1000 } @OK;
say "Number of eban numbers up to and including 1000: @{[1+$#a]}";
say join(', ',@a);
say '';
my @b = grep { $_ >= 1000 && $_ <= 4000 } @OK;
say "Number of eban numbers between 1000 and 4000 (inclusive): @{[1+$#b]}";
say join(', ',@b);
say '';
for my $exp (4..$max) {
my $n = + grep { $_ <= 10**$exp } @OK;
printf "Number of eban numbers and %10s: %d\n", comma(10**$exp), $n;
}
- Output:
eban numbers up to and including 1000: 2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56, 60, 62, 64, 66 eban numbers between 1000 and 4000 (inclusive): 2000, 2002, 2004, 2006, 2030, 2032, 2034, 2036, 2040, 2042, 2044, 2046, 2050, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 4000 Number of eban numbers up to 10,000: 79 Number of eban numbers up to 100,000: 399 Number of eban numbers up to 1,000,000: 399 Number of eban numbers up to 10,000,000: 1599
Algorithmically generate / count
Alternately, a partial translation of Raku. Does not need to actually generate the e-ban numbers to count them. Display counts up to 10**21.
use strict;
use warnings;
use bigint;
use feature 'say';
use Lingua::EN::Nums2Words 'num2word';
use List::AllUtils 'sum';
sub comma { reverse ((reverse shift) =~ s/(.{3})/$1,/gr) =~ s/^,//r }
sub nban {
my ($n, @numbers) = @_;
grep { lc(num2word($_)) !~ /[$n]/i } @numbers;
}
sub enumerate {
my ($n, $upto) = @_;
my @ban = nban($n, 1 .. 99);
my @orders;
for my $o (2 .. $upto) {
push @orders, [nban($n, map { $_ * 10**$o } 1 .. 9)];
}
for my $oom (@orders) {
next unless +@$oom;
my @these;
for my $num (@$oom) {
push @these, $num, map { $_ + $num } @ban;
}
push @ban, @these;
}
unshift @ban, 0 if nban($n, 0);
@ban
}
sub count {
my ($n, $upto) = @_;
my @orders;
for my $o (2 .. $upto) {
push @orders, [nban($n, map { $_ * 10**$o } 1 .. 9)];
}
my @count = scalar nban($n, 1 .. 99);
for my $o ( 0 .. $#orders - 1 ) {
push @count, sum(@count) * (scalar @{$orders[$o]}) + (scalar @{$orders[$o]});
}
++$count[0] if nban($n, 0);
for my $m ( 0 .. $#count - 1 ) {
next unless scalar $orders[$m];
if (nban($n, 10**($m+2))) { $count[$m]++; $count[$m + 1]-- }
}
map { sum( @count[0..$_] ) } 0..$#count;
}
for my $t ('e') {
my @bans = enumerate($t, 4);
my @count = count($t, my $max = 21);
my @j = grep { $_ <= 10 } @bans;
unshift @count, @{[1+$#j]};
say "\n============= $t-ban: =============";
my @a = grep { $_ <= 1000 } @bans;
say "$t-ban numbers up to 1000: @{[1+$#a]}";
say '[', join(' ',@a), ']';
say '';
my @b = grep { $_ >= 1000 && $_ <= 4000 } @bans;
say "$t-ban numbers between 1,000 & 4,000 (inclusive): @{[1+$#b]}";
say '[', join(' ',@b), ']';
say '';
say "Counts of $t-ban numbers up to ", lc(num2word(10**$max));
for my $exp (1..$max) {
my $nu = $count[$exp-1];
printf "Up to and including %23s: %s\n", lc(num2word(10**$exp)), comma($nu);
}
}
============= e-ban: ============= e-ban numbers up to 1000: 19 [2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66] e-ban numbers between 1,000 & 4,000 (inclusive): 21 [2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000] Counts of e-ban numbers up to one sextillion Up to and including ten: 3 Up to and including one hundred: 19 Up to and including one thousand: 19 Up to and including ten thousand: 79 Up to and including one hundred thousand: 399 Up to and including one million: 399 Up to and including ten million: 1,599 Up to and including one hundred million: 7,999 Up to and including one billion: 7,999 Up to and including ten billion: 31,999 Up to and including one hundred billion: 159,999 Up to and including one trillion: 159,999 Up to and including ten trillion: 639,999 Up to and including one hundred trillion: 3,199,999 Up to and including one quadrillion: 3,199,999 Up to and including ten quadrillion: 12,799,999 Up to and including one hundred quadrillion: 63,999,999 Up to and including one quintillion: 63,999,999 Up to and including ten quintillion: 255,999,999 Up to and including one hundred quintillion: 1,279,999,999 Up to and including one sextillion: 1,279,999,999
Phix
Why count when you can calculate?
with javascript_semantics function count_eban(integer p10) -- returns the count of eban numbers 1..power(10,p10) integer n = p10-floor(p10/3), p5 = floor(n/2), p4 = floor((n+1)/2) return power(5,p5)*power(4,p4)-1 end function function eban(integer n) -- returns true if n is an eban number (only fully tested to 10e9) if n=0 then return false end if while n do integer thou = remainder(n,1000) if floor(thou/100)!=0 then return false end if if not find(floor(thou/10),{0,3,4,5,6}) then return false end if if not find(remainder(thou,10),{0,2,4,6}) then return false end if n = floor(n/1000) end while return true end function sequence s = {} for i=0 to 1000 do if eban(i) then s = append(s,sprint(i)) end if end for printf(1,"eban to 1000 : %s\n\n",{join(shorten(s,"items",8))}) s = {} for i=1000 to 4000 do if eban(i) then s = append(s,sprint(i)) end if end for printf(1,"eban 1000..4000 : %s\n\n",{join(shorten(s,"items",4))}) atom t0 = time() for i=0 to 21 do printf(1,"count_eban(10^%d) : %,d\n",{i,count_eban(i)}) end for ?elapsed(time()-t0)
- Output:
eban to 1000 : 2 4 6 30 32 34 36 40 ... 50 52 54 56 60 62 64 66 (19 items) eban 1000..4000 : 2000 2002 2004 2006 ... 2062 2064 2066 4000 (21 items) count_eban(10^0) : 0 count_eban(10^1) : 3 count_eban(10^2) : 19 count_eban(10^3) : 19 count_eban(10^4) : 79 count_eban(10^5) : 399 count_eban(10^6) : 399 count_eban(10^7) : 1,599 count_eban(10^8) : 7,999 count_eban(10^9) : 7,999 count_eban(10^10) : 31,999 count_eban(10^11) : 159,999 count_eban(10^12) : 159,999 count_eban(10^13) : 639,999 count_eban(10^14) : 3,199,999 count_eban(10^15) : 3,199,999 count_eban(10^16) : 12,799,999 count_eban(10^17) : 63,999,999 count_eban(10^18) : 63,999,999 count_eban(10^19) : 255,999,999 count_eban(10^20) : 1,279,999,999 count_eban(10^21) : 1,279,999,999 "0s"
PicoLisp
(de _eban? (N)
(let
(B (/ N 1000000000)
R (% N 1000000000)
M (/ R 1000000)
R (% N 1000000)
Z (/ R 1000)
R (% R 1000) )
(and
(>= M 30)
(<= M 66)
(setq M (% M 10)) )
(and
(>= Z 30)
(<= Z 66)
(setq Z (% Z 10)) )
(and
(>= R 30)
(<= R 66)
(setq R (% R 10)) )
(fully
'((S)
(unless (bit? 1 (val S))
(>= 6 (val S)) ) )
'(B M Z R) ) ) )
(de eban (B A)
(default A 2)
(let R (cons 0 (cons))
(for (N A (>= B N) (+ N 2))
(and
(_eban? N)
(inc R)
(push (cdr R) N) ) )
(con R (flip (cadr R)))
R ) )
(off R)
(prinl "eban numbers up to an including 1000:")
(setq R (eban 1000))
(println (cdr R))
(prinl "count: " (car R))
(prinl)
(prinl "eban numbers between 1000 and 4000")
(setq R (eban 4000 1000))
(println (cdr R))
(prinl "count: " (car R))
(prinl)
(prinl "eban numbers up to an including 10000:")
(prinl "count: " (car (eban 10000)))
(prinl)
(prinl "eban numbers up to an including 100000:")
(prinl "count: " (car (eban 100000)))
(prinl)
(prinl "eban numbers up to an including 1000000:")
(prinl "count: " (car (eban 1000000)))
(prinl)
(prinl "eban numbers up to an including 10000000:")
(prinl "count: " (car (eban 10000000)))
- Output:
eban numbers up to an including 1000: (2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66) count: 19 eban numbers between 1000 and 4000 (2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000) count: 21 eban numbers up to an including 10000: count: 79 eban numbers up to an including 100000: count: 399 eban numbers up to an including 1000000: count: 399 eban numbers up to an including 10000000: count: 1599
Python
# Use inflect
"""
show all eban numbers <= 1,000 (in a horizontal format), and a count
show all eban numbers between 1,000 and 4,000 (inclusive), and a count
show a count of all eban numbers up and including 10,000
show a count of all eban numbers up and including 100,000
show a count of all eban numbers up and including 1,000,000
show a count of all eban numbers up and including 10,000,000
"""
import inflect
import time
before = time.perf_counter()
p = inflect.engine()
# eban numbers <= 1000
print(' ')
print('eban numbers up to and including 1000:')
print(' ')
count = 0
for i in range(1,1001):
if not 'e' in p.number_to_words(i):
print(str(i)+' ',end='')
count += 1
print(' ')
print(' ')
print('count = '+str(count))
print(' ')
# eban numbers 1000 to 4000
print(' ')
print('eban numbers between 1000 and 4000 (inclusive):')
print(' ')
count = 0
for i in range(1000,4001):
if not 'e' in p.number_to_words(i):
print(str(i)+' ',end='')
count += 1
print(' ')
print(' ')
print('count = '+str(count))
print(' ')
# eban numbers up to 10000
print(' ')
print('eban numbers up to and including 10000:')
print(' ')
count = 0
for i in range(1,10001):
if not 'e' in p.number_to_words(i):
count += 1
print(' ')
print('count = '+str(count))
print(' ')
# eban numbers up to 100000
print(' ')
print('eban numbers up to and including 100000:')
print(' ')
count = 0
for i in range(1,100001):
if not 'e' in p.number_to_words(i):
count += 1
print(' ')
print('count = '+str(count))
print(' ')
# eban numbers up to 1000000
print(' ')
print('eban numbers up to and including 1000000:')
print(' ')
count = 0
for i in range(1,1000001):
if not 'e' in p.number_to_words(i):
count += 1
print(' ')
print('count = '+str(count))
print(' ')
# eban numbers up to 10000000
print(' ')
print('eban numbers up to and including 10000000:')
print(' ')
count = 0
for i in range(1,10000001):
if not 'e' in p.number_to_words(i):
count += 1
print(' ')
print('count = '+str(count))
print(' ')
after = time.perf_counter()
print(" ")
print("Run time in seconds: "+str(after - before))
Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 Run time in seconds: 1134.289519125
Quackery
[ 20 /mod
4 /mod
[ table 0 2 4 6 ]
swap
[ table 0 30 40 50 60 ]
+
over 0 = iff nip done
swap recurse 1000 * + ] is n->eban ( n --> n )
[] 1
[ dup n->eban
dup 10000001 < while
swap dip join
1+ again ]
2drop
dup dup
say "eban numbers up to and including 1000:"
cr
findwith [ 1000 > ] [ ]
split drop dup echo cr
say "count: " size echo
cr cr
say "eban numbers between 1000 and 4000 (inclusive):"
cr
dup dup
findwith [ 999 > ] [ ]
split nip
dup
findwith [ 4001 > ] [ ]
split drop dup echo cr
say "count: " size echo
cr cr
say "number of eban numbers up to and including 10000: "
dup findwith [ 10001 > ] [ ]
echo
cr cr
say "number of eban numbers up to and including 100000: "
dup findwith [ 100001 > ] [ ]
echo
cr cr
say "number of eban numbers up to and including 1000000: "
dup findwith [ 1000001 > ] [ ]
echo
cr cr
say "number of eban numbers up to and including 10000000: "
findwith [ 10000001 > ] [ ]
echo
- Output:
eban numbers up to and including 1000 [ 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 ] count: 19 eban numbers between 1000 and 4000 (inclusive): [ 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 ] count: 21 number of eban numbers up to and including 10000: 79 number of eban numbers up to and including 100000: 399 number of eban numbers up to and including 1000000: 399 number of eban numbers up to and including 10000000: 1599
Raku
(formerly Perl 6)
Modular approach, very little is hard coded. Change the $upto order-of-magnitude limit to adjust the search/display ranges. Change the letter(s) given to the enumerate / count subs to modify which letter(s) to disallow.
Will handle multi-character 'bans'. Demonstrate for e-ban, t-ban and subur-ban.
Directly find :
- OEIS:A006933 Numbers without e: Eban
- OEIS:A008521 Numbers without o: Oban
- OEIS:A008523 Numbers without t: Tban
- OEIS:A072954 Numbers without a, i, l, t: TALIban
- OEIS:A072955 Numbers without b, r, s, u: SUBURban
- OEIS:A072956 Numbers without r, t, u: TURban
- OEIS:A072957 Numbers without r, u: URban
- OEIS:A072958 Numbers without a, c, i, l: CALIban
- OEIS:A089589 Numbers without i: Iban
- OEIS:A089590 Numbers without u: Uban
- and so on...
Considering numbers up to 1021, as the task directions suggest.
use Lingua::EN::Numbers;
sub nban ($seq, $n = 'e') { ($seq).map: { next if .&cardinal.contains(any($n.lc.comb)); $_ } }
sub enumerate ($n, $upto) {
my @ban = [nban(1 .. 99, $n)],;
my @orders;
(2 .. $upto).map: -> $o {
given $o % 3 { # Compensate for irregulars: 11 - 19
when 1 { @orders.push: [flat (10**($o - 1) X* 10 .. 19).map(*.&nban($n)), |(10**$o X* 2 .. 9).map: *.&nban($n)] }
default { @orders.push: [flat (10**$o X* 1 .. 9).map: *.&nban($n)] }
}
}
^@orders .map: -> $o {
@ban.push: [] and next unless +@orders[$o];
my @these;
@orders[$o].map: -> $m {
@these.push: $m;
for ^@ban -> $b {
next unless +@ban[$b];
@these.push: $_ for (flat @ban[$b]) »+» $m ;
}
}
@ban.push: @these;
}
@ban.unshift(0) if nban(0, $n);
flat @ban.map: *.flat;
}
sub count ($n, $upto) {
my @orders;
(2 .. $upto).map: -> $o {
given $o % 3 { # Compensate for irregulars: 11 - 19
when 1 { @orders.push: [flat (10**($o - 1) X* 10 .. 19).map(*.&nban($n)), |(10**$o X* 2 .. 9).map: *.&nban($n)] }
default { @orders.push: [flat (10**$o X* 1 .. 9).map: *.&nban($n)] }
}
}
my @count = +nban(1 .. 99, $n);
^@orders .map: -> $o {
@count.push: 0 and next unless +@orders[$o];
my $prev = so (@orders[$o].first( { $_ ~~ /^ '1' '0'+ $/ } ) // 0 );
my $sum = @count.sum;
my $these = +@orders[$o] * $sum + @orders[$o];
$these-- if $prev;
@count[1 + $o] += $these;
++@count[$o] if $prev;
}
++@count[0] if nban(0, $n);
[\+] @count;
}
#for < e o t tali subur tur ur cali i u > -> $n { # All of them
for < e t subur > -> $n { # An assortment for demonstration
my $upto = 21; # 1e21
my @bans = enumerate($n, 4);
my @counts = count($n, $upto);
# DISPLAY
my @k = @bans.grep: * < 1000;
my @j = @bans.grep: 1000 <= * <= 4000;
put "\n============= {$n}-ban: =============\n" ~
"{$n}-ban numbers up to 1000: {+@k}\n[{@k».&comma}]\n\n" ~
"{$n}-ban numbers between 1,000 & 4,000: {+@j}\n[{@j».&comma}]\n" ~
"\nCounts of {$n}-ban numbers up to {cardinal 10**$upto}"
;
my $s = max (1..$upto).map: { (10**$_).&cardinal.chars };
@counts.unshift: @bans.first: * > 10, :k;
for ^$upto -> $c {
printf "Up to and including %{$s}s: %s\n", cardinal(10**($c+1)), comma(@counts[$c]);
}
}
- Output:
============= e-ban: ============= e-ban numbers up to 1000: 19 [2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66] e-ban numbers between 1,000 & 4,000: 21 [2,000 2,002 2,004 2,006 2,030 2,032 2,034 2,036 2,040 2,042 2,044 2,046 2,050 2,052 2,054 2,056 2,060 2,062 2,064 2,066 4,000] Counts of e-ban numbers up to one sextillion Up to and including ten: 3 Up to and including one hundred: 19 Up to and including one thousand: 19 Up to and including ten thousand: 79 Up to and including one hundred thousand: 399 Up to and including one million: 399 Up to and including ten million: 1,599 Up to and including one hundred million: 7,999 Up to and including one billion: 7,999 Up to and including ten billion: 31,999 Up to and including one hundred billion: 159,999 Up to and including one trillion: 159,999 Up to and including ten trillion: 639,999 Up to and including one hundred trillion: 3,199,999 Up to and including one quadrillion: 3,199,999 Up to and including ten quadrillion: 12,799,999 Up to and including one hundred quadrillion: 63,999,999 Up to and including one quintillion: 63,999,999 Up to and including ten quintillion: 255,999,999 Up to and including one hundred quintillion: 1,279,999,999 Up to and including one sextillion: 1,279,999,999 ============= t-ban: ============= t-ban numbers up to 1000: 56 [0 1 4 5 6 7 9 11 100 101 104 105 106 107 109 111 400 401 404 405 406 407 409 411 500 501 504 505 506 507 509 511 600 601 604 605 606 607 609 611 700 701 704 705 706 707 709 711 900 901 904 905 906 907 909 911] t-ban numbers between 1,000 & 4,000: 0 [] Counts of t-ban numbers up to one sextillion Up to and including ten: 7 Up to and including one hundred: 9 Up to and including one thousand: 56 Up to and including ten thousand: 56 Up to and including one hundred thousand: 56 Up to and including one million: 57 Up to and including ten million: 392 Up to and including one hundred million: 785 Up to and including one billion: 5,489 Up to and including ten billion: 38,416 Up to and including one hundred billion: 76,833 Up to and including one trillion: 537,824 Up to and including ten trillion: 537,824 Up to and including one hundred trillion: 537,824 Up to and including one quadrillion: 537,825 Up to and including ten quadrillion: 3,764,768 Up to and including one hundred quadrillion: 7,529,537 Up to and including one quintillion: 52,706,752 Up to and including ten quintillion: 52,706,752 Up to and including one hundred quintillion: 52,706,752 Up to and including one sextillion: 52,706,752 ============= subur-ban: ============= subur-ban numbers up to 1000: 35 [1 2 5 8 9 10 11 12 15 18 19 20 21 22 25 28 29 50 51 52 55 58 59 80 81 82 85 88 89 90 91 92 95 98 99] subur-ban numbers between 1,000 & 4,000: 0 [] Counts of subur-ban numbers up to one sextillion Up to and including ten: 6 Up to and including one hundred: 35 Up to and including one thousand: 35 Up to and including ten thousand: 35 Up to and including one hundred thousand: 35 Up to and including one million: 36 Up to and including ten million: 216 Up to and including one hundred million: 2,375 Up to and including one billion: 2,375 Up to and including ten billion: 2,375 Up to and including one hundred billion: 2,375 Up to and including one trillion: 2,375 Up to and including ten trillion: 2,375 Up to and including one hundred trillion: 2,375 Up to and including one quadrillion: 2,375 Up to and including ten quadrillion: 2,375 Up to and including one hundred quadrillion: 2,375 Up to and including one quintillion: 2,375 Up to and including ten quintillion: 2,375 Up to and including one hundred quintillion: 2,375 Up to and including one sextillion: 2,375
Note that the limit to one sextillion is somewhat arbitrary and is just to match the task parameters.
This will quite happily count *-bans up to one hundred centillion. (10305) It takes longer, but still on the order of seconds, not minutes.
Counts of e-ban numbers up to one hundred centillion ... Up to and including one hundred centillion: 35,184,372,088,831,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999
REXX
Programming note: REXX has no shortcuts for if statements, so the multiple if statements weren't combined into one.
/*REXX program to display eban numbers (those that don't have an "e" their English name)*/
numeric digits 20 /*support some gihugic numbers for pgm.*/
parse arg $ /*obtain optional arguments from the cL*/
if $='' then $= '1 1000 1000 4000 1 -10000 1 -100000 1 -1000000 1 -10000000'
do k=1 by 2 to words($) /*step through the list of numbers. */
call banE word($, k), word($, k+1) /*process the numbers, from low──►high.*/
end /*k*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
banE: procedure; parse arg x,y,_; z= reverse(x) /*obtain the number to be examined. */
tell= y>=0 /*Is HI non-negative? Display eban #s.*/
#= 0 /*the count of eban numbers (so far).*/
do j=x to abs(y) /*probably process a range of numbers. */
if hasE(j) then iterate /*determine if the number has an "e". */
#= # + 1 /*bump the counter of eban numbers. */
if tell then _= _ j /*maybe add to a list of eban numbers. */
end /*j*/
if _\=='' then say strip(_) /*display the list (if there is one). */
say; say # ' eban numbers found for: ' x " " y; say copies('═', 105)
return
/*──────────────────────────────────────────────────────────────────────────────────────*/
hasE: procedure; parse arg x; z= reverse(x) /*obtain the number to be examined. */
do k=1 by 3 /*while there're dec. digit to examine.*/
@= reverse( substr(z, k, 3) ) /*obtain 3 dec. digs (a period) from Z.*/
if @==' ' then return 0 /*we have reached the "end" of the num.*/
uni= right(@, 1) /*get units dec. digit of this period. */
if uni//2==1 then return 1 /*if an odd digit, then not an eban #. */
if uni==8 then return 1 /*if an eight, " " " " " */
tens=substr(@, 2, 1) /*get tens dec. digit of this period. */
if tens==1 then return 1 /*if teens, then not an eban #. */
if tens==2 then return 1 /*if twenties, " " " " " */
if tens>6 then return 1 /*if 70s, 80s, 90s, " " " " " */
hun= left(@, 1) /*get hundreds dec. dig of this period.*/
if hun==0 then iterate /*if zero, then there is more of number*/
if hun\==' ' then return 1 /*any hundrEd (not zero) has an "e". */
end /*k*/ /*A "period" is a group of 3 dec. digs */
return 0 /*in the number, grouped from the right*/
- output when using the default inputs:
2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 19 eban numbers found for: 1 1000 ═════════════════════════════════════════════════════════════════════════════════════════════════════════ 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 21 eban numbers found for: 1000 4000 ═════════════════════════════════════════════════════════════════════════════════════════════════════════ 79 eban numbers found for: 1 -10000 ═════════════════════════════════════════════════════════════════════════════════════════════════════════ 399 eban numbers found for: 1 -100000 ═════════════════════════════════════════════════════════════════════════════════════════════════════════ 399 eban numbers found for: 1 -1000000 ═════════════════════════════════════════════════════════════════════════════════════════════════════════ 1599 eban numbers found for: 1 -10000000 ═════════════════════════════════════════════════════════════════════════════════════════════════════════
RPL
« IF DUP THEN 1000000000 IDIV2 1000000 IDIV2 1000 IDIV2 3 →LIST « → x « 30 x ≤ x 66 ≤ AND x 10 MOD x IFTE » » MAP + « { 0 2 4 6 } SWAP POS » MAP ΠLIST END » » 'EBAN?' STO « { } UNROT FOR j IF j EBAN? THEN j + END NEXT » » 'TASK1' STO « 0 1 ROT FOR j IF j EBAN? THEN 1 + END NEXT » » 'TASK2' STO
1 1000 TASK1 1000 4000 TASK1 10000 TASK2
- Output:
3: { 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 } 2: { 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 } 1: 79
Ruby
def main
intervals = [
[2, 1000, true],
[1000, 4000, true],
[2, 10000, false],
[2, 100000, false],
[2, 1000000, false],
[2, 10000000, false],
[2, 100000000, false],
[2, 1000000000, false]
]
for intv in intervals
(start, ending, display) = intv
if start == 2 then
print "eban numbers up to and including %d:\n" % [ending]
else
print "eban numbers between %d and %d (inclusive):\n" % [start, ending]
end
count = 0
for i in (start .. ending).step(2)
b = (i / 1000000000).floor
r = (i % 1000000000)
m = (r / 1000000).floor
r = (r % 1000000)
t = (r / 1000).floor
r = (r % 1000)
if m >= 30 and m <= 66 then
m = m % 10
end
if t >= 30 and t <= 66 then
t = t % 10
end
if r >= 30 and r <= 66 then
r = r % 10
end
if b == 0 or b == 2 or b == 4 or b == 6 then
if m == 0 or m == 2 or m == 4 or m == 6 then
if t == 0 or t == 2 or t == 4 or t == 6 then
if r == 0 or r == 2 or r == 4 or r == 6 then
if display then
print ' ', i
end
count = count + 1
end
end
end
end
end
if display then
print "\n"
end
print "count = %d\n\n" % [count]
end
end
main()
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 eban numbers up to and including 1000000000: count = 7999
Rust
use std::ops::{Div, Rem};
use std::println;
fn iseban(n: i64) -> bool {
let b = n.div(1_000_000_000);
let mut r = n.rem(1_000_000_000);
let m = r.div(1_000_000);
r = r.rem(1_000_000);
let t = r.div(1000);
r = r.rem(1000);
let mut arr: Vec<_> = [m, t, r]
.iter()
.map(|x| {
if &30 <= x && x <= &66 {
(*x).rem(10)
} else {
*x
}
})
.collect();
arr.push(b);
return arr.iter().all(|x| [0, 2, 4, 6].contains(x));
}
fn main() {
println!("Eban numbers up to and including 1000:");
println!(
"{}",
(1..=1_00_i64)
.filter(|x| iseban(*x))
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join(", ")
);
println!("Eban numbers between 1000 and 4000 (inclusive):");
println!(
"{}",
(1000..=4_000_i64)
.filter(|x| iseban(*x))
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join(", ")
);
println!(
"Eban numbers up to and including 10_000: {}",
(1..=10000).map(|x| iseban(x) as i32).sum::<i32>()
);
println!(
"Eban numbers up to and including 100_000: {}",
(1..=100000).map(|x| iseban(x) as i32).sum::<i32>()
);
println!(
"Eban numbers up to and including 1_000_000: {}",
(1..=1000000).map(|x| iseban(x) as i32).sum::<i32>()
);
println!(
"Eban numbers up to and including 10_000_000: {}",
(1..=10000000).map(|x| iseban(x) as i32).sum::<i32>()
);
println!(
"Eban numbers up to and including 100_000_000: {}",
(1..=100000000).map(|x| iseban(x) as i32).sum::<i32>()
);
println!(
"Eban numbers up to and including 1_000_000_000: {}",
(1..=1000000000).map(|x| iseban(x) as i32).sum::<i32>()
);
}
- Output:
Eban numbers up to and including 1000: 2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56, 60, 62, 64, 66 Eban numbers between 1000 and 4000 (inclusive): 2000, 2002, 2004, 2006, 2030, 2032, 2034, 2036, 2040, 2042, 2044, 2046, 2050, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 4000 Eban numbers up to and including 10_000: 79 Eban numbers up to and including 100_000: 399 Eban numbers up to and including 1_000_000: 399 Eban numbers up to and including 10_000_000: 1599 Eban numbers up to and including 100_000_000: 7999 Eban numbers up to and including 1_000_000_000: 7999
Scala
object EbanNumbers {
class ERange(s: Int, e: Int, p: Boolean) {
val start: Int = s
val end: Int = e
val print: Boolean = p
}
def main(args: Array[String]): Unit = {
val rgs = List(
new ERange(2, 1000, true),
new ERange(1000, 4000, true),
new ERange(2, 10000, false),
new ERange(2, 100000, false),
new ERange(2, 1000000, false),
new ERange(2, 10000000, false),
new ERange(2, 100000000, false),
new ERange(2, 1000000000, false)
)
for (rg <- rgs) {
if (rg.start == 2) {
println(s"eban numbers up to an including ${rg.end}")
} else {
println(s"eban numbers between ${rg.start} and ${rg.end}")
}
var count = 0
for (i <- rg.start to rg.end) {
val b = i / 1000000000
var r = i % 1000000000
var m = r / 1000000
r = i % 1000000
var t = r / 1000
r %= 1000
if (m >= 30 && m <= 66) {
m %= 10
}
if (t >= 30 && t <= 66) {
t %= 10
}
if (r >= 30 && r <= 66) {
r %= 10
}
if (b == 0 || b == 2 || b == 4 || b == 6) {
if (m == 0 || m == 2 || m == 4 || m == 6) {
if (t == 0 || t == 2 || t == 4 || t == 6) {
if (r == 0 || r == 2 || r == 4 || r == 6) {
if (rg.print) {
print(s"$i ")
}
count += 1
}
}
}
}
}
if (rg.print) {
println()
}
println(s"count = $count")
println()
}
}
}
- Output:
eban numbers up to an including 1000 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to an including 10000 count = 79 eban numbers up to an including 100000 count = 399 eban numbers up to an including 1000000 count = 399 eban numbers up to an including 10000000 count = 1599 eban numbers up to an including 100000000 count = 7999 eban numbers up to an including 1000000000 count = 7999
Tailspin
templates isEban
def number: $;
'$;' -> \(<'([246]|[3456][0246])(0[03456][0246])*'> $ !\) -> $number !
end isEban
In v0.5
isEban templates
number is $;
'$;' -> if <|'([246]|[3456][0246])(0[03456][0246])*'> -> $number !
end isEban
Alternatively, if regex is not your thing, we can do it numerically, which actually runs faster
templates isEban
def number: $;
$ -> \(<1..> $!\) -> #
when <=0> do $number !
when <?($ mod 1000 <=0|=2|=4|=6|30..66?($ mod 10 <=0|=2|=4|=6>)>)> do $ ~/ 1000 -> #
end isEban
Or in v0.5
isEban templates
number is $;
$ -> if <|1..> -> # !
when <|=0> do $number !
when <|?($ mod 1000 matches <|=0|=2|=4|=6|30..66?($ mod 10 matches <|=0|=2|=4|=6>)>)> do $ ~/ 1000 -> # !
end isEban
Either version is called by the following code
def small: [1..1000 -> isEban];
$small -> !OUT::write
'
There are $small::length; eban numbers up to and including 1000
' -> !OUT::write
def next: [1000..4000 -> isEban];
$next -> !OUT::write
'
There are $next::length; eban numbers between 1000 and 4000 (inclusive)
' -> !OUT::write
'
There are $:[1..10000 -> isEban] -> $::length; eban numbers up to and including 10 000
' -> !OUT::write
'
There are $:[1..100000 -> isEban] -> $::length; eban numbers up to and including 100 000
' -> !OUT::write
'
There are $:[1..1000000 -> isEban] -> $::length; eban numbers up to and including 1 000 000
' -> !OUT::write
'
There are $:[1..10000000 -> isEban] -> $::length; eban numbers up to and including 10 000 000
' -> !OUT::write
Or in v0.5
small is [1..1000 -> isEban];
$small !
'
There are $small::length; eban numbers up to and including 1000
' !
next is [1000..4000 -> isEban];
$next !
'
There are $next::length; eban numbers between 1000 and 4000 (inclusive)
' !
'
There are $:[1..10000 -> isEban] -> $::length; eban numbers up to and including 10 000
' !
'
There are $:[1..100000 -> isEban] -> $::length; eban numbers up to and including 100 000
' !
'
There are $:[1..1000000 -> isEban] -> $::length; eban numbers up to and including 1 000 000
' !
'
There are $:[1..10000000 -> isEban] -> $::length; eban numbers up to and including 10 000 000
' !
- Output:
[2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56, 60, 62, 64, 66] There are 19 eban numbers up to and including 1000 [2000, 2002, 2004, 2006, 2030, 2032, 2034, 2036, 2040, 2042, 2044, 2046, 2050, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 4000] There are 21 eban numbers between 1000 and 4000 (inclusive) There are 79 eban numbers up to and including 10 000 There are 399 eban numbers up to and including 100 000 There are 399 eban numbers up to and including 1 000 000 There are 1599 eban numbers up to and including 10 000 000
uBasic/4tH
Push 2, 10^7, 0
Push 2, 10^6, 0
Push 2, 10^5, 0
Push 2, 10^4, 0
Push 1000, 4000, 1
Push 2, 1000, 1
z = XOR(NOT(0), 6)
Do While Used()
p = Pop() : e = Pop() : s = Pop()
If s = 2 Then
Print "eban numbers up to and including ";e
Else
Print "eban numbers between ";s;" and ";e;" (inclusive):"
EndIf
c = 0
For i = s To e Step 2
b = i / 1000000000
m = (i % 1000000000) / 1000000
r = i % 1000000
t = r / 1000
r = r % 1000
If ((m < 30) = 0) * ((m > 66) = 0) Then m = m % 10
If ((t < 30) = 0) * ((t > 66) = 0) Then t = t % 10
If ((r < 30) = 0) * ((r > 66) = 0) Then r = r % 10
If (AND(b, z) = 0) * (AND(m, z) = 0) * (AND(t, z) = 0) * (AND(r, z) = 0) Then
If p Then Print i;" "; : Fi
c = c + 1
EndIf
Next
If p Then Print
Print "count = ";c : Print
Loop
Visual Basic .NET
Module Module1
Structure Interval
Dim start As Integer
Dim last As Integer
Dim print As Boolean
Sub New(s As Integer, l As Integer, p As Boolean)
start = s
last = l
print = p
End Sub
End Structure
Sub Main()
Dim intervals As Interval() = {
New Interval(2, 1_000, True),
New Interval(1_000, 4_000, True),
New Interval(2, 10_000, False),
New Interval(2, 100_000, False),
New Interval(2, 1_000_000, False),
New Interval(2, 10_000_000, False),
New Interval(2, 100_000_000, False),
New Interval(2, 1_000_000_000, False)
}
For Each intv In intervals
If intv.start = 2 Then
Console.WriteLine("eban numbers up to and including {0}:", intv.last)
Else
Console.WriteLine("eban numbers between {0} and {1} (inclusive):", intv.start, intv.last)
End If
Dim count = 0
For i = intv.start To intv.last Step 2
Dim b = i \ 1_000_000_000
Dim r = i Mod 1_000_000_000
Dim m = r \ 1_000_000
r = i Mod 1_000_000
Dim t = r \ 1_000
r = r Mod 1_000
If m >= 30 AndAlso m <= 66 Then
m = m Mod 10
End If
If t >= 30 AndAlso t <= 66 Then
t = t Mod 10
End If
If r >= 30 AndAlso r <= 66 Then
r = r Mod 10
End If
If b = 0 OrElse b = 2 OrElse b = 4 OrElse b = 6 Then
If m = 0 OrElse m = 2 OrElse m = 4 OrElse m = 6 Then
If t = 0 OrElse t = 2 OrElse t = 4 OrElse t = 6 Then
If r = 0 OrElse r = 2 OrElse r = 4 OrElse r = 6 Then
If intv.print Then
Console.Write("{0} ", i)
End If
count += 1
End If
End If
End If
End If
Next
If intv.print Then
Console.WriteLine()
End If
Console.WriteLine("count = {0}", count)
Console.WriteLine()
Next
End Sub
End Module
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 eban numbers up to and including 1000000000: count = 7999
V (Vlang)
struct Range {
start i64
end i64
print bool
}
fn main() {
rgs := [
Range{2, 1000, true},
Range{1000, 4000, true},
Range{2, 10000, false},
Range{2, 100000, false},
Range{2, 1000000, false},
Range{2, 10000000, false},
Range{2, 100000000, false},
Range{2, 1000000000, false}
]
for rg in rgs {
if rg.start == 2 {
println("eban numbers up to and including $rg.end:")
} else {
println("eban numbers between $rg.start and $rg.end (inclusive):")
}
mut count := 0
for i := rg.start; i <= rg.end; i += 2 {
b := i / 1000000000
mut r := i % 1000000000
mut m := r / 1000000
r = i % 1000000
mut t := r / 1000
r %= 1000
if m >= 30 && m <= 66 {
m %= 10
}
if t >= 30 && t <= 66 {
t %= 10
}
if r >= 30 && r <= 66 {
r %= 10
}
if b == 0 || b == 2 || b == 4 || b == 6 {
if m == 0 || m == 2 || m == 4 || m == 6 {
if t == 0 || t == 2 || t == 4 || t == 6 {
if r == 0 || r == 2 || r == 4 || r == 6 {
if rg.print {
print("$i ")
}
count++
}
}
}
}
}
if rg.print {
println('')
}
println("count = $count\n")
}
}
- Output:
eban numbers up to and including 1000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000: count = 79 eban numbers up to and including 100000: count = 399 eban numbers up to and including 1000000: count = 399 eban numbers up to and including 10000000: count = 1599 eban numbers up to and including 100000000: count = 7999 eban numbers up to and including 1000000000: count = 7999
Wren
var rgs = [
[2, 1000, true],
[1000, 4000, true],
[2, 1e4, false],
[2, 1e5, false],
[2, 1e6, false],
[2, 1e7, false],
[2, 1e8, false],
[2, 1e9, false]
]
for (rg in rgs) {
if (rg[0] == 2) {
System.print("eban numbers up to and including %(rg[1])")
} else {
System.print("eban numbers between %(rg[0]) and %(rg[1]) (inclusive):")
}
var count = 0
var i = rg[0]
while (i <= rg[1]) {
var b = (i/1e9).floor
var r = i % 1e9
var m = (r/1e6).floor
r = i % 1e6
var t = (r/1000).floor
r = r % 1000
if (m >= 30 && m <= 66) m = m % 10
if (t >= 30 && t <= 66) t = t % 10
if (r >= 30 && r <= 66) r = r % 10
if (b == 0 || b == 2 || b == 4 || b == 6) {
if (m == 0 || m == 2 || m == 4 || m == 6) {
if (t == 0 || t == 2 || t == 4 || t == 6) {
if (r == 0 || r == 2 || r == 4 || r == 6) {
if (rg[2]) System.write("%(i) ")
count = count + 1
}
}
}
}
i = i + 2
}
if (rg[2]) System.print()
System.print("count = %(count)\n")
}
- Output:
eban numbers up to and including 1000 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000 count = 79 eban numbers up to and including 100000 count = 399 eban numbers up to and including 1000000 count = 399 eban numbers up to and including 10000000 count = 1599 eban numbers up to and including 100000000 count = 7999 eban numbers up to and including 1000000000 count = 7999
XPL0
include xpllib; \for Print
int Rgs, Rg, Count, I, B, R, M, T;
[Rgs:= [
[2, 1000, true],
[1000, 4000, true],
[2, 10000, false],
[2, 100000, false],
[2, 1000000, false],
[2, 10000000, false],
[2, 100000000, false],
[2, 1000000000, false] ];
for Rg:= 0 to 8-1 do
[if Rgs(Rg,0) = 2 then
Print("eban numbers up to and including %d\n", Rgs(Rg,1))
else
Print("eban numbers between %d and %d (inclusive):\n", Rgs(Rg,0), Rgs(Rg,1));
Count:= 0;
I:= Rgs(Rg,0);
while I <= Rgs(Rg,1) do
[B:= (I/1_000_000_000);
M:= rem(0) / 1_000_000;
T:= rem(0) / 1_000;
R:= rem(0);
if M >= 30 and M <= 66 then M:= rem(M/10);
if T >= 30 and T <= 66 then T:= rem(T/10);
if R >= 30 and R <= 66 then R:= rem(R/10);
if B = 0 or B = 2 or B = 4 or B = 6 then
if M = 0 or M = 2 or M = 4 or M = 6 then
if T = 0 or T = 2 or T = 4 or T = 6 then
if R = 0 or R = 2 or R = 4 or R = 6 then
[if Rgs(Rg,2) then Print("%d ", I);
Count:= Count+1;
];
I:= I+2;
];
if Rgs(Rg,2) then CrLf(0);
Print("count = %d\n", Count);
];
]
- Output:
eban numbers up to and including 1000 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1000 and 4000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10000 count = 79 eban numbers up to and including 100000 count = 399 eban numbers up to and including 1000000 count = 399 eban numbers up to and including 10000000 count = 1599 eban numbers up to and including 100000000 count = 7999 eban numbers up to and including 1000000000 count = 7999
Yabasic
data 2, 100, true
data 1000, 4000, true
data 2, 1e4, false
data 2, 1e5, false
data 2, 1e6, false
data 2, 1e7, false
data 2, 1e8, false
REM data 2, 1e9, false // it takes a lot of time
data 0, 0, false
do
read start, ended, printable
if not start break
if start = 2 then
Print "eban numbers up to and including ", ended
else
Print "eban numbers between ", start, " and ", ended, " (inclusive):"
endif
count = 0
for i = start to ended step 2
b = int(i / 1000000000)
r = mod(i, 1000000000)
m = int(r / 1000000)
r = mod(i, 1000000)
t = int(r / 1000)
r = mod(r, 1000)
if m >= 30 and m <= 66 m = mod(m, 10)
if t >= 30 and t <= 66 t = mod(t, 10)
if r >= 30 and r <= 66 r = mod(r, 10)
if b = 0 or b = 2 or b = 4 or b = 6 then
if m = 0 or m = 2 or m = 4 or m = 6 then
if t = 0 or t = 2 or t = 4 or t = 6 then
if r = 0 or r = 2 or r = 4 or r = 6 then
if printable Print i;
count = count + 1
endif
endif
endif
endif
next
if printable Print
Print "count = ", count, "\n"
loop
zkl
rgs:=T( T(2, 1_000, True), // (start,end,print)
T(1_000, 4_000, True),
T(2, 1e4, False), T(2, 1e5, False), T(2, 1e6, False), T(2, 1e7, False),
T(2, 1e8, False), T(2, 1e9, False), // slow and very slow
);
foreach start,end,pr in (rgs){
if(start==2) println("eban numbers up to and including %,d:".fmt(end));
else println("eban numbers between %,d and %,d (inclusive):".fmt(start,end));
count:=0;
foreach i in ([start..end,2]){
b,r := i/100_0000_000, i%1_000_000_000;
m,r := r/1_000_000, i%1_000_000;
t,r := r/1_000, r%1_000;
if(30<=m<=66) m=m%10;
if(30<=t<=66) t=t%10;
if(30<=r<=66) r=r%10;
if(magic(b) and magic(m) and magic(t) and magic(r)){
if(pr) print(i," ");
count+=1;
}
}
if(pr) println();
println("count = %,d\n".fmt(count));
}
fcn magic(z){ z.isEven and z<=6 }
- Output:
eban numbers up to and including 1,000: 2 4 6 30 32 34 36 40 42 44 46 50 52 54 56 60 62 64 66 count = 19 eban numbers between 1,000 and 4,000 (inclusive): 2000 2002 2004 2006 2030 2032 2034 2036 2040 2042 2044 2046 2050 2052 2054 2056 2060 2062 2064 2066 4000 count = 21 eban numbers up to and including 10,000: count = 79 eban numbers up to and including 100,000: count = 399 eban numbers up to and including 1,000,000: count = 399 eban numbers up to and including 10,000,000: count = 1,599 eban numbers up to and including 100,000,000: count = 7,999 eban numbers up to and including 1,000,000,000: count = 7,999
- Programming Tasks
- Solutions by Programming Task
- 11l
- Ada
- ALGOL 68
- AppleScript
- AutoHotkey
- AWK
- BASIC
- BASIC256
- Chipmunk Basic
- Gambas
- C
- C sharp
- C++
- CLU
- D
- EasyLang
- Factor
- FreeBASIC
- Fōrmulæ
- Go
- Groovy
- Haskell
- J
- Java
- Jq
- Julia
- K
- Kotlin
- Lua
- Mathematica
- Wolfram Language
- Nim
- Odin
- Perl
- Phix
- PicoLisp
- Python
- Quackery
- Raku
- REXX
- RPL
- Ruby
- Rust
- Scala
- Tailspin
- UBasic/4tH
- Visual Basic .NET
- V (Vlang)
- Wren
- XPL0
- Yabasic
- Zkl