Eban numbers: Difference between revisions
Line 126:
count = 7999
</pre>
=={{header|J}}==
<lang J>
divrem =: <.@:%~ , |
Filter =: (#~`)(`:6)
itemAmend =: (29&< *. <&67)`(,:10&|)}
iseban =: [: , (monad define&>)
'b r' =: (10^9x) divrem y
'm r' =: (10^6x) divrem r
't r' =: (10^3x) divrem r
m =: itemAmend ,m
t =: itemAmend ,t
r =: itemAmend ,r
, *./ +./ 0 2 4 6 =/ b , m , t ,: r
)
(;~ #) 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│
└──┴────────────────────────────────────────────────────────────────────────────────────────────────────────┘
</lang>
=={{header|Julia}}==
|
Revision as of 01:35, 4 March 2019
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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.
Go
<lang 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") }
}</lang>
- 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
J
<lang J> divrem =: <.@:%~ , | Filter =: (#~`)(`:6) itemAmend =: (29&< *. <&67)`(,:10&|)}
iseban =: [: , (monad define&>)
'b r' =: (10^9x) divrem y 'm r' =: (10^6x) divrem r 't r' =: (10^3x) divrem r m =: itemAmend ,m t =: itemAmend ,t r =: itemAmend ,r , *./ +./ 0 2 4 6 =/ b , m , t ,: r
)
(;~ #) 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│ └──┴────────────────────────────────────────────────────────────────────────────────────────────────────────┘
</lang>
Julia
I changed your program but not the output. You had used the common cut-n-paste error repeating the 10000 println("eban numbers up to and including 10000:
<lang 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)) </lang>
- 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 10000: 399 eban numbers up to and including 10000: 399 eban numbers up to and including 10000: 1599 eban numbers up to and including 10000: 7999 eban numbers up to and including 10000: 7999
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 nban sub 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:A089589 Numbers without i: Iban
- OEIS:A089590 Numbers without u: Uban
- OEIS:A008521 Numbers without o: Oban
- OEIS:A008523 Numbers without t: Tban
- OEIS:A072958 Numbers without a, c, i, l: CALIban
- OEIS:A072954 Numbers without a, i, l, t: TALIban
- OEIS:A072957 Numbers without r, u: URban
- OEIS:A072956 Numbers without r, t, u: TURban
- OEIS:A072955 Numbers without b, r, s, u: SUBURban
- and so on...
<lang perl6>use Lingua::EN::Numbers::Cardinal;
sub nban ($seq, $n = 'e') { ($seq).map: { next if .&cardinal.contains(any($n.comb)); $_ } }
sub filter ($n, $upto) {
my @ban = flat ((1 .. 99),).map: *.&nban($n); my @orders = (2 .. $upto).map({ 10**$_ X* 1..9 }).map: *.&nban($n); for @orders -> @order { next unless +@order; my @these; @these.append: flat $_, flat @ban X+ $_ for @order; @ban.append: @these } @ban.unshift(0) if 0.&nban($n); @ban
}
sub comma { $^i.flip.comb(3).join(',').flip }
for 'e', 't', 'subur' -> $n {
my $upto = 10; # 1e10 my @bans = filter($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.gist}\n\n" ~ "{$n}-ban numbers between 1,000 & 4,000: {+@j}\n{@j».&comma.gist}\n";
for (1 .. $upto).map: { 10**$_ } -> $e { my $f = @bans.first( * > $e, :k ); printf "Up to %14s: %s\n", comma($e), comma($f ?? +@bans[^$f] !! +@bans); }
}</lang>
- 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] Up to 10: 3 Up to 100: 19 Up to 1,000: 19 Up to 10,000: 79 Up to 100,000: 399 Up to 1,000,000: 399 Up to 10,000,000: 1,599 Up to 100,000,000: 7,999 Up to 1,000,000,000: 7,999 Up to 10,000,000,000: 31,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 [] Up to 10: 7 Up to 100: 9 Up to 1,000: 56 Up to 10,000: 56 Up to 100,000: 56 Up to 1,000,000: 57 Up to 10,000,000: 392 Up to 100,000,000: 393 Up to 1,000,000,000: 2,745 Up to 10,000,000,000: 19,208 ============= 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 [] Up to 10: 6 Up to 100: 35 Up to 1,000: 35 Up to 10,000: 35 Up to 100,000: 35 Up to 1,000,000: 36 Up to 10,000,000: 216 Up to 100,000,000: 1,295 Up to 1,000,000,000: 1,295 Up to 10,000,000,000: 1,295
REXX
Programming note: REXX has no shortcuts for if statements, so the multiple if statements weren't combined into one. <lang rexx>/*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*/</lang>
- 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 ═════════════════════════════════════════════════════════════════════════════════════════════════════════