(Continuing on the number sequences code-golf, here is an interesting sequence)
Eban Numbers (A006933) are the sequence of numbers whose names (in English) do not contain the letter "e" (i.e., "e" is "banned")
The first few numbers in the sequence are:
2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56
Given an integer n, via function argument or STDIN, return the first n terms of the Eban Numbers (in numbers) .
Since some answers will involve some sort of string check for character e, assume that the maximum value of n can be such that the nth Eban number is less than 1 Quadrillion.
-
\$\begingroup\$ related: codegolf.stackexchange.com/questions/36512/… \$\endgroup\$Howard– Howard2014年09月12日 13:34:02 +00:00Commented Sep 12, 2014 at 13:34
-
\$\begingroup\$ Searching questions on this site is pretty primitive ... Anyways, Eban numbers are more tricky than Iban in so many ways :) \$\endgroup\$Optimizer– Optimizer2014年09月12日 13:38:22 +00:00Commented Sep 12, 2014 at 13:38
-
\$\begingroup\$ Do the terms have to be output numerically, or may they be output as words? \$\endgroup\$Digital Trauma– Digital Trauma2014年09月12日 20:08:27 +00:00Commented Sep 12, 2014 at 20:08
-
\$\begingroup\$ Yes, numeric output. \$\endgroup\$Optimizer– Optimizer2014年09月12日 20:13:52 +00:00Commented Sep 12, 2014 at 20:13
-
\$\begingroup\$ Are we allowed to use modules off CPAN that aren't in the core if doing a Perl solution? \$\endgroup\$hmatt1– hmatt12014年09月12日 21:24:00 +00:00Commented Sep 12, 2014 at 21:24
5 Answers 5
(削除) Mathematica (削除ここまで) CJam, (削除) 108 (削除ここまで) (削除) 95 (削除ここまで) (削除) 46 (削除ここまで) (削除) 35 (削除ここまで) 30 bytes
Edit: Ported to CJam! The original and ungolfed Mathematica code is at the bottom and explains the algorithm quite well.
li,{)Kb65430s2046sm*$f=0s*ip}/
And now I know CJam. :D Thanks to Dennis for some golfing improvements.
After analysing them a bit to determine how many there are below one quadrillion, I came to the conclusion that all eban numbers are basically base-1000 numbers using only a set of 20 digits:
0, 2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56, 60, 62, 64, 66
So we enumerate them by converting the input to base 20, picking the right digit from the set and build a base 1000 number from it.
This is how the code works in detail:
li "Read from STDIN, convert to integer n";
li, "Turn into a range array [0 ... n-1]";
li,{ }/ "For each number execute a block";
li,{) }/ "Increment";
li,{)K }/ "K is initialised to 20, push that";
li,{)Kb }/ "Convert to base 20";
li,{)Kb65430s }/ "Push a string with possible multiples of 10";
li,{)Kb65430s2046s }/ "Push a string with possible least significant digits";
li,{)Kb65430s2046sm* }/ "Take the Cartesian product of the two character
arrays, generating the 20 'digits'";
li,{)Kb65430s2046sm*$ }/ "Sort the result";
li,{)Kb65430s2046sm*$f= }/ "For each digit in our base-20 number, get the
base-1000 digit from the list";
li,{)Kb65430s2046sm*$f=0s }/ "Push a '0' character";
li,{)Kb65430s2046sm*$f=0s* }/ "Join all the digits, with that '0' as the delimiter";
li,{)Kb65430s2046sm*$f=0s*ip}/ "Convert to an integer and print the result";
Here was the original Mathematica code, which doesn't encode the digit list and is hence fairly readable:
{0,2,4,6,30,32,34,36,40,42,44,46,50,52,54,56,60,62,64,66}[[IntegerDigits[#,20]+1]]~FromDigits~1000 & /@ Range @ # &
-
1\$\begingroup\$ Unprintable characters would work just fine. You can replace
20withK,1000with1e3,{i41-}%with41f-and{")+-/GIKMQSUW[]_aegik"41f-=}%with")+-/GIKMQSUW[]_aegik"41f-f=. Futhermore, the array (string) could be pushed as[4U5Z6][U4Y6]m*Afb$(m*is Cartesian product,$is sort), for a total of 33 bytes (35 if you prependlito read from STDIN). \$\endgroup\$Dennis– Dennis2014年09月13日 06:39:19 +00:00Commented Sep 13, 2014 at 6:39 -
\$\begingroup\$ @Dennis I knew I was missing out on a lot of good tricks, thanks! ;) I just remembered that CJam happily deals with large bases so I quickly wanted to throw something together, because I figured this could beat all other answers. I'll go through your tips and work them in when I understand why they work. :) \$\endgroup\$Martin Ender– Martin Ender2014年09月13日 08:11:17 +00:00Commented Sep 13, 2014 at 8:11
-
\$\begingroup\$ You can save 5 more bytes by using strings instead of numbers, eliminating the need for the last two base conversions:
li,{)Kb65430s2046sm*$f=0s*ip}/. Unfortunately,'ヨis'०ishas the same byte count as65430s2046s. \$\endgroup\$Dennis– Dennis2014年09月13日 12:56:23 +00:00Commented Sep 13, 2014 at 12:56 -
\$\begingroup\$ @Dennis Interesting. What's the difference between
/and%? \$\endgroup\$Martin Ender– Martin Ender2014年09月13日 13:11:33 +00:00Commented Sep 13, 2014 at 13:11 -
\$\begingroup\$ Doesn't really matter here, just force of habit.
%collects the results in an array, so it leaves an empty array on the stack here. Since those aren't printed, it would only matter for a function. \$\endgroup\$Dennis– Dennis2014年09月13日 13:19:33 +00:00Commented Sep 13, 2014 at 13:19
Bash+coreutils+BSDGames package, (削除) 79 (削除ここまで) 70 bytes
seq $[9**16]|while read n
do number $n|grep -q e||echo $n
done|sed 1ドルq
Unfortunately this spawns number $n|grep -q e for every number, so is rather slow.
Output:
$ ./eban.sh 5
2
4
6
30
32
$
Previous answer - outputs words instead of digits, 43 bytes
seq $[9**16]|number -l|grep -v [e.]|sed 1ドルq
This outputs each term written in words:
$ ./eban.sh 5
two
four
six
thirty
thirty-two
$
A bit faster, because each process is only spawned once.
Much faster, no dependence on cheaty number, 77 bytes
t=0{0,3,4,5,6}{0,2,4,6}
eval echo $t$t$t$t$t|tr \ '
'|sed "s/^0*//;$[1ドル+1]q"
This one uses bash brace expansion to generate all (according to my thinking) eban numbers up to 10^15. Looking at each group of 3 digits, the units digit must be one of {zero,two,four,six}, the tens digit must be one of {zero,thirty,forty,fifty,sixty}, and the hundreds digit must be zero. Since x-illion contains no e's up to quadrillion, then we can just combine the groups of three digits up to one quadrillion. The only exception is zero which must be skipped.
So we simply build a brace expansion to generate all these numbers. There are thus 205-1 of them (3.2 million). Evaluating the full bash brace expansion takes less than 5 seconds on my VM.
The sed expression just strips off leading zeros and counts to n.
Output:
$ time ./eban.bash 5
2
4
6
30
32
real 0m4.065s
user 0m3.724s
sys 0m0.276s
$ ./eban.bash 10000000 | wc -w
3199999
$ ./eban.bash 3199999 | tail -5
66066066066056
66066066066060
66066066066062
66066066066064
66066066066066
$
-
\$\begingroup\$ Will this first generate 10^15 numbers and then stop at 1ドル ? or incrementally check and stop generating after 5th number ? \$\endgroup\$Optimizer– Optimizer2014年09月12日 20:01:57 +00:00Commented Sep 12, 2014 at 20:01
-
\$\begingroup\$ @Optimizer
seqcan generate that many numbers, but because this is all a long pipeline, whenever any one of the processes quits, the shell will send a SIGPIPE to all processes in the pipeline, and thus they will all quit. In this case, thesed 1ドルqwill quit after the nth line it receives, and thus the rest of the pipline will be torn down, beforeseqcan count much further (modulo buffering in each pipe). \$\endgroup\$Digital Trauma– Digital Trauma2014年09月12日 20:04:59 +00:00Commented Sep 12, 2014 at 20:04 -
\$\begingroup\$ I think you can probably play around and print the actual number instead of the English version. Maybe via awk/sed. \$\endgroup\$Optimizer– Optimizer2014年09月12日 20:10:01 +00:00Commented Sep 12, 2014 at 20:10
-
1\$\begingroup\$ please do it... \$\endgroup\$Optimizer– Optimizer2014年09月12日 20:13:03 +00:00Commented Sep 12, 2014 at 20:13
-
1\$\begingroup\$ @Optimizer Looks like that old bash version has poor memory management. If you're serious about testing the more Linuxey answers, I recommend you install some distro (Ubuntu is easy) in a VM. Virtualbox and VMWare player are free, I think. Another thing you can try for this answer is replace
$t$t$t$t$twith$t$t$t$t. With this the script will work with numbers up to 1 trillion. \$\endgroup\$Digital Trauma– Digital Trauma2014年09月12日 23:42:27 +00:00Commented Sep 12, 2014 at 23:42
Ruby, (削除) 128 (削除ここまで) (削除) 121 (削除ここまで) 119 bytes
f=->n{a=[]
i=0
(j=i+=2
b=p
(m=j%t=1000
b=b||m%2>0||m%10==8||m>9&&m<30||m>69
j/=t)while j>0
a<<i if !b)while a.size<n
a}
I'm basically just checking groups of three digits for numbers that contain es, because none of {thousand, million, billion, trillion, quadrillion} contains an e.
-
\$\begingroup\$ You can safely do
i+=2as all numbers in Eban numbers are even \$\endgroup\$Optimizer– Optimizer2014年09月12日 18:32:32 +00:00Commented Sep 12, 2014 at 18:32 -
\$\begingroup\$ @Optimizer lol yeah, since I have a
m%2>0||I was even aware of that. :D thanks! \$\endgroup\$Martin Ender– Martin Ender2014年09月12日 18:34:02 +00:00Commented Sep 12, 2014 at 18:34 -
\$\begingroup\$ Can you probably find out
nwhere it crosses a quadrillion ? I don't have the setup and online compilers won't run for that bign\$\endgroup\$Optimizer– Optimizer2014年09月12日 18:47:52 +00:00Commented Sep 12, 2014 at 18:47 -
\$\begingroup\$ @Optimizer Not with the program. I'd need an optimised version which skips over thousands/millions/etc if the offending "e" comes from one of the more significant digits. But if I'm not mistaken, there should be Σ(n=1...5) 19^n = 2,613,659 eban numbers below a quadrillion. \$\endgroup\$Martin Ender– Martin Ender2014年09月12日 19:41:14 +00:00Commented Sep 12, 2014 at 19:41
-
1\$\begingroup\$ @Optimizer I think I was mistaken. I think it should be 20^5-1 = 3199999 eban numbers below a quadrillion instead. \$\endgroup\$Martin Ender– Martin Ender2014年09月12日 22:35:19 +00:00Commented Sep 12, 2014 at 22:35
Perl - 78
Here is a Perl one-liner to do it.
perl -MLingua::EN::Numbers=num2en -nE'while($n<=$_){$n++&&say$i if num2en($i)!~/e/;$i++}' <(echo 5)
It is 50 characters plus 1 for the M, 1 for the n, and 26 for Lingua::EN::Numbers=num2len.
Using Lingua::EN::Numbers from CPAN. Here are instructions for installing CPAN modules.
Vyxal, 66 bitsv2 , 8.25 bytes
Þ∞'∆ċ\ec¬;Ẏ
Bitstring:
001001110101101011111000111110011011000101110000000110101001010010
Þ∞'∆ċ\ec¬;Ẏ
Þ∞ # infinite list of integers
' ; # filter by
∆ċ\ec¬ # cardinal of the number does not contain 'e'
Ẏ # slice to length of input
💎
Created with the help of Luminespire.
-
1\$\begingroup\$ 6.125 bytes:
∆ċ\e$F)ȯ(vyncoded) \$\endgroup\$2023年10月28日 03:55:58 +00:00Commented Oct 28, 2023 at 3:55