| Bytes | Lang | Time | Link |
|---|---|---|---|
| 027 | Vyxal 3 | 250805T150436Z | Themooni |
| 085 | AWK | 241105T164131Z | xrs |
| 058 | Perl 5 ap | 201208T163953Z | Xcali |
| 022 | Jelly | 201127T113046Z | caird co |
| 039 | MATL | 160218T001601Z | Luis Men |
| 140 | Lua | 160218T085906Z | Katenkyo |
| nan | 160219T224923Z | Sumeet | |
| 034 | CJam | 160217T215449Z | Martin E |
| 169 | Lua | 160219T173534Z | DavisDud |
| 096 | PowerShell | 160217T210652Z | AdmBorkB |
| 094 | Haskell | 160219T001613Z | Michael |
| 096 | Python 2 | 160219T013050Z | xnor |
| 067 | Bash + GNU utilities | 160217T215124Z | Digital |
| 229 | Oracle SQL 11.2 | 160218T152211Z | Jeto |
| 087 | JavaScript ES6 | 160218T145740Z | edc65 |
| 110 | JavaScript ES6 | 160218T011433Z | Neil |
| 168 | C# 6 | 160218T134330Z | Paulo C& |
| 107 | R | 160218T104656Z | plannapu |
| 082 | Ruby | 160217T210710Z | Doorknob |
| 191 | JavaScript ES6 | 160217T231506Z | Conor O& |
| 103 | Python 3 | 160217T202825Z | Morgan T |
| 032 | Pyth | 160217T202819Z | Blue |
AWK, 95 85 bytes
{for(i=0;z<$1;i++){t=i;if(gsub(/[469]/,X,t)+2*gsub(/0|8/,X,t)>=$2&&X~t&&++z)print i}}
{for(i=0;z<$1;i++) # z is hit count
{t=i; # temp
if(gsub(/[469]/,X,t) # count and delete matches
+2*gsub(/0|8/,X,t) # 2x hits
>=$2 # goal holiness
&&X~t # string should now be empty
&&++z) # increment hit counter
print i}} # print
Old attempt
{for(j=i=0;j!=$1;i++){a=i;i~/[12357]/||gsub(/[469]/,X,a)+2*gsub(/[80]/,X,a)>=$2&&++j}print i-1}
...
{for(j=i=0;j!=$1;i++) # j counts number of hits up to n
{a=i; # tmp
i~/[12357]/|| # unholy numbers
gsub(/[469]/,X,a)+ # gsub returns number of matches/subs
2*gsub(/[80]/,X,a) # 2 points per match
>=$2&&++j} # if >= h, add hit
print i-1} # overshoot
Perl 5 -ap, 58 bytes
$_=0;$n=<>;$_++while/[12357]/||y/64980//+y/80//<"@F"||--$n
Input is on two lines with h on the first and n on the second.
Jelly, 23 22 bytes
“J,1’D=þD§S×ẠƊ
0Ç<Cɗ#Ṫ
How it works
0Ç<Cɗ#Ṫ - Main link. Takes h on the left and n on the right
ɗ - Group the previous 3 links into a dyad f(k, h):
Ç - Call the helper link on k
< - Less than h?
C - Complement; 0 -> 1, 1 -> 0
0 # - Count up k = 0, 1, 2, ... until n k's return true under f(k, h)
Ṫ - Take the last k
“J,1’D=þD§S×ẠƊ - Helper link. Takes an integer k on the left
D - Digits of k
“J,1’ - Compressed integer 4698800
D - Converted to digits
þ - Outer product with:
= - Equality
§ - Sum of each row
Ɗ - Group the previous 3 links into a monad g(s) over the sums:
S - Sum
Ạ - All are non-zero?
× - Product
This calculates the holiness of k, which is 0 if k isn't holy
MATL, 39 40 bytes
x~q`QtV4688900V!=stA*s2G<?T}N1G=?F1$}tT
Inputs are n and h in that order.
We need to keep track of two numbers: current candidate number (to check its holiness) and amount of numbers found that are holy enough. The first is the top od the stack, and the latter is kept as the number of elements in the stack. When the program finishes, only the top needs to displayed.
x~q % implicitly take two inputs. Delete one and transform the other into -1
` % do...while loop
Q % add 1 to current candidate number
tV % duplicate and convert to string
4688900V! % column char array of '4', '6' etc. Note '8' and '0' are repeated
= % compare all combinations. Gives 2D array
s % sum of each column: holiness of each digit of candidate number
tA* % are all digits holy? Multiply by that
s % sum of holiness of all digits, provided they are all holy
2G< % is that less than second input (h)?
? % if so: current candidate not valid. We'll try the next
T % push true to be used as loop condition: next iteration
} % else: current candidate valid
N1G= % does stack size equal first input (n)?
? % if so: we're done
F1$ % push false to exit loop. Spec 1 input, to display only top
} % else: make a copy of this number
tT % duplicate number. Push true to continue with next iteration
% implicit end if
% implicit end if
% implicit end do...while. If top of stack is truthy: next iteration
% implicit display
Lua, 155 141 140 Bytes
Takes both inputs by command-line argument(first argument is n, then h)
Edit: Thanks to @DavisDude, who helped me shaving 14 bytes off and reminded me I didn't have to print all the holy numbers up to n, but only the nth.
a={}x=0while(#a<arg[1])do b,c=(x..""):gsub("[08]","")e,d=b:gsub("[469]","")a[#a+1],x=c*2+d>=arg[2]and #e<1 and x or nil,x+1 end print(a[#a])
Ungolfed and explanations
x,a=0,{} -- initialise a counter, and the array which
-- contains the holy numbers found
while(#a<arg[1]) -- iterate while we found less holy numbers than n
do
b,c=(x..""):gsub("[08]","") -- replace [08] by "", b=the new string
-- c=the number of subsitution
e,d=b:gsub("[469]","") -- same thing for [469]
a[#a+1]=c*2+d>=arg[2] -- insert the number into a if:nb[08]*2+nb[469]>h
and #e<1 -- and e is empty (no unholy numbers)
and x or nil
x=x+1 -- increment x
end
print(a[#a]) -- print the last element of a
Swift
func f(n: Int, h: Int) {
var m = 0
let a = [1,2,3,5,7]
for j in 0..<Int.max {
var c = 0
for i in (j.description.characters.map{(String($0) as NSString).integerValue}) {
c += (a.contains(i)) ? 0 : (i == 8 || i == 0) ? 2 :1
}
if c >= h { m += 1; if m >= n {print(j); break}}
}
}
CJam, 36 34 bytes
Thanks to aditsu for saving 2 bytes.
Wq~:X;{{)_Ab39643Zbf=_:*g*1bX<}g}*
Lua, 169 bytes
function a(n,h)H=0N=0I=-1while N<n do I=I+'1'H=0 if not I:find('[12357]') then _,b=I:gsub('[469]',1)_,c=I:gsub('[08]',1)H=b+2*c end N=H>=h and N+1 or N end print(I) end
Ungolfed:
function a(n,h) -- nth term, holiness
H=0N=0I=-1 -- Really ugly, but hey, it works. Set up 3 vars
while N<n do -- While nth term is lower than desired term
I=''..I+1 -- Convert number to string (can't coerce since it will become a float)
if not I:find('[12357]') then -- If the number doesn't have those numbers
_,b=I:gsub('[469]',1) -- _ is the new string, b is the number of changes
_,c=I:gsub('[08]',1) -- Same as above. Use 1 to replace to save chars
H=b+2*c -- Increase holiness appropriately
end
N=H>=h and N+1 or N -- If current holiness >= desired holiness, increment N
end
print(I) -- Once the loop ends, print the current term
end
PowerShell, 163 150 141 101 98 96 bytes
param($n,$h)for(--$i;$n){if(++$i-notmatch"[12357]"-and($i-replace"8|0",11).Length-ge$h){$n--}}$i
Takes input, then loops until $n is zero. We initially setting $i=-1 by using a pre-processing trick, which works because $i, having not previously been declared, is $null. Then we -- it, which causes PowerShell to evaluate it as $i = $null - 1, which is $i=-1.
Each loop we increment $i and then execute a lengthy if statement. The first part of the conditional verifies that $i doesn't have any of 12357 in it by using the -notmatch operator, to filter out the unholy numbers.
The second part of the conditional checks the quantity of holes in $i. It uses the -replace operator to replace each 8 or 0 with 11, and then compares whether the length is >= $h. We don't need to worry about stripping out the unholy numbers, since that's in the first part of the conditional, and the single-holed numbers are the same length as 1 anyway, so we don't need to replace them, either.
If that is still truthy, we decrement $n (as that means we've found another number that satisfies input requirements). Thus when the for condition is recalculated to check if $n is zero, that means we've found the nth one, so we exit the for loop, output $i and terminate.
Edit -- saved 13 bytes by using an array instead of string for $l and changing how $n is decremented/checked
Edit 2 -- saved an additional 9 bytes by checking for $n in the for conditional and moving the output outside the loop
Edit 3 -- saved a whopping 40 more bytes by radically changing how we calculate the holes
Edit 4 -- saved an additional 3 bytes by moving the ++ to be a pre-increment on the first part of the conditional
Edit 5 -- saved another 2 bytes thanks to TessellatingHeckler
Haskell, 94 bytes
c is the holiness of a digit, v the holiness of a number, n!h does the rest.
c=([2,0,0,0,1,0,1,0,2,1]!!)
v n|n>9=c(mod n 10)+v(div n 10)|1<2=c n
n!h=[i|i<-[0..],v i<=h]!!n
Note: I think this is the only answer without the characters 4,6,8.
Python 2, 96 bytes
f=lambda n,h,k=0,s="0046889":-0**n or-~f(n-(sum(map(s.count,`k`))>=h<set(str(k))<=set(s)),h,k+1)
The holyness condition on k is checked by
sum(map(s.count,`k`))>=h, which counts the number of holes by summing the counts for each character ins="0046889", where0and8appear twice.set(str(k))<=set(s)), which checks that the numbers are all holy.stris used rather than backticks to avoid the suffixLfor longs.
These are chained into a single equality using the Python 2 fact that numbers are smaller than sets.
The function is defined recursively to count up numbers k, decreasing the counter n each time a holy number of hit unless it hits 0. It could then return the k that triggered this, but it's shorter to keep the count recursively by adding 1 each time, though an off-by-one requires a base count of -1 to fix.
Bash + GNU utilities, 67
- 20 bytes saved thanks to @TobySpeight!
seq 0 NaN|sed -r "h;/[12357]/d;s/8|0/&&/g;/^.{$1}/!d;x"|sed $2!d\;q
seqsimply generates integers starting from0upwardssed -r:hcopy the input line to the hold space/12357/ddelete unholy numberss/8|0/&&/greplace doubly holy digits with twice themselves. Thus singly holy digits are counted once and doubly holy digits are counted twice./^.{$1}/!dIf not matching at least$1holes, delete and continue to the next linexbring original number back to the pattern space- implicit print
sed$2!don any lines before line$2, delete and continue to the next lineqmust be at line$2- quit (and implicit print)
Oracle SQL 11.2, 229 bytes
WITH v(c,p,i,j,n)AS(SELECT 0,-1,0,0,0 FROM DUAL UNION ALL SELECT c+1,c,REGEXP_COUNT(c||'','[4,6,9]'),REGEXP_COUNT(c,'[8,0]'),n+DECODE(LENGTH(p),i+j,DECODE(SIGN(i+j*2-:h),-1,0,1),0)FROM v WHERE p<c AND n<:n)SELECT MAX(p)-1 FROM v;
Un-golfed
:h -> required min holy value
:n -> nth number
curv -> current number
precv -> previous number
prech1 -> number of holy 1 letters in previous number
prech2 -> number of holy 2 letters in previous number
n -> how many numbers with at least the required holy value
WITH v(curv,precv,prech1,prech2,n)AS
(
SELECT 0 curv, -1 precv, 0 prech1, 0 prech2, 0 n FROM DUAL -- Start with 0
UNION ALL
SELECT curv+1, -- Next number
curv, -- Current Number
REGEXP_COUNT(curv||'','[4,6,9]'), -- number of holy 1 letters
REGEXP_COUNT(curv,'[8,0]'), -- number of holy 2 letters
n+DECODE(LENGTH(precv),prech1+prech2,DECODE(SIGN(prech1+prech2*2-:h),-1,0,1),0) -- Is the previous number holy enough ?
FROM v
WHERE precv<curv -- Needed to trick oracle cycle detection
AND n<:n -- Until clause
)
SELECT MAX(precv)-1 FROM v
JavaScript (ES6), 87
(n,h)=>eval("for(i=0;[...i+''].map(d=>r-=~!(d%8),r=0),/[12357]/.test(i)|r<h||--n;)++i")
Less golfed
f=(n,h)=>{
for (i=0;
// this is the loop condition
/[12357]/.test(i) // go on if not holy
||([...i+''].map(d=>r-=~!(d%8),r=0),r<h) // go on if not holy enough
||--n; // ok, found one! go on if we need to find more
)
++i; // loop body - using eval this is the returned value
return i; // not using eval, an explicit return is needed
}
Test
f=(n,h)=>eval("for(i=0;[...i+''].map(d=>r-=~!(d%8),r=0),/[12357]/.test(i)|r<h||--n;)++i")
function test() {
var a,b
[a,b]=I.value.match(/\d+/g)
R.textContent = f(a,b)
}
test()
N, H: <input id=I value="25 2" oninput="test()"> >>
<span id=R></span>
JavaScript (ES6), 110 bytes
f=(n,h,r=[],i=0)=>r.length<n?f(n,h,/[12357]/.test(i)|[...''+i].reduce((t,c)=>t+1+!(c%8),0)<h?r:[...r,i],i+1):r
Tail recursive solution that accumulates holy numbers in an array.
Out of interest, not requiring the number to be wholly(!) holy makes the holiness count more awkward, but it still saves 10% overall:
f=(n,h,r=[],i=0)=>r.length<n?f(n,h,[...''+i].reduce((t,c)=>+"2000101021"[c]+t,0)<h?r:[...r,i],i+1):r
C# 6, 168 bytes
(n,h)=>{for(int i=0;i<=int.MaxValue;i++){string d=$"{i}";if(d.Any(y=>"12357".Contains(y)))continue;n-=d.Sum(y=>y=='0'||y=='8'?2:1)>=h?1:0;if(n==0)return i;}return -1;}
This is a Lambda Expression of type Func< int, int, int>. This code is otimized for min size (not performatic).
Below, the beautified code in method declaration (with more performance):
int GetHolyNumber(int n, int h)
{
for (int i = 0; i <= int.MaxValue; i++)
{
string d = $"{i}";
char[] cs = "12357".ToArray();
if (d.Any(y => cs.Contains(y))) continue;
n -= d.Sum(y => y == '0' || y == '8' ? 2 : 1) >= h ? 1 : 0;
if (n == 0)
return i;
}
return -1;
}
R, 109 107 bytes
f=function(n,h){m=-1;while(n){m=m+1;if(!grepl("[12357]",m))if(nchar(gsub("([08])","\\1\\1",m))>=h)n=n-1};m}
With new lines and indentations:
f=function(n,h){
m=-1
while(n){
m=m+1
if(!grepl("[12357]",m))
if(nchar(gsub("([08])","\\1\\1",m))>=h)
n=n-1
}
m
}
Usage:
> f(4,3)
[1] 68
> f(4,2)
[1] 44
> f(6,2)
[1] 48
> f(10,2)
[1] 66
Ruby, 109 105 95 82 bytes
->n,h{(?0..?9*99).select{|x|x.count('469')+2*x.count('80')>=h&&/[12357]/!~x}[n-1]}
This is the terrible "calculate from 0 to 99999999999..." approach that happens to be 13 bytes shorter than its lazy counterpart. However, this version is unlikely to finish before the heat death of the universe. Worth 13 bytes, anyway ¯\_(ツ)_/¯
You can test it for smaller values by changing ?9*99 to, say, '99999'.
Here's the old version (95 bytes, with lazy evaluation, which runs near-instantly rather than near-never):
->n,h{(?0..?9*99).lazy.select{|x|x.count('469')+2*x.count('80')>=h&&/[12357]/!~x}.first(n)[-1]}
->n,h{
(?0..?9*99) # range '0' (string) to '9' repeated 99 times, way more than 2**64
.lazy # make the range lazy, so we can call `select' on it
.select{|x| # choose only elements such that...
x.count('469')+2*x.count('80') # naive holiness calculation
>=h # is at least h
&&/[12357]/!~x # naive "is holy" calculation
}
.first(n) # take the first n elements that satisfy the condition
[-1] # choose the last one from this array
}
JavaScript ES6, 191 bytes
Sure, this isn't the most efficient way. But you know me, I love generators <3
H=(x,o=x+"")=>(F=/^[46890]+$/).test(o)&&[...o].map(y=>d+=(F.test(y)+/8|0/.test(y)),d=0)&&d;(n,h)=>(a=(function*(h){q=0;while(1){if(H(q)>=h)yield q;q++}})(h),eval("a.next().value;".repeat(n)))
Slightly ungolfed:
H = (x, o = x + "") => (F = /^[46890]+$/).test(o) && [...o].map(y => d += (F.test(y) + /8|0/.test(y)), d = 0) && d;
Q = (n, h) => (a = (function*(h) {
q = 0;
while (1) {
if (H(q) >= h) yield q;
q++
}
})(h), eval("a.next().value;".repeat(n)))
Python 3, 103
lambda n,h,l='4698080':[y for y in range(2**64-1)if(sum(l.count(x)-(x not in l)for x in str(y))>=h)][n]
Here's a solution that uses a more memory efficient approach, but otherwise uses the same algorithm if you want to test it.
l='4689080'
def f(n,h):
c=i=0
while i<n:
if sum(l.count(x)-(x not in l)for x in str(c))>=h:u=c;i+=1
c+=1
return u
Test cases:
assert f(3, 1) == 6
assert f(4, 2) == 44
Pyth, 32 bytes
e.fg*g.{`46890J`Z++lJ/J`8/J`0QE0
Explanation
- autoassign Q = eval(input())
.f E0 - first eval(input()) terms of func V starting Z=0
g.{`46890J`Z - Are all the digits in Z in "46890"?
`Z - str(Z)
J - autoassign J = ^
g - is_subset(V,^)
.{`46890 - set("46890")
* - ^*V (Only return non-zero if only contains holy numbers)
++lJ/J`8/J`0 - Get the holiness of the number
lJ - len(J)
+ - ^+V
/J`8 - J.count("8")
+ - ^+V
/J`0 - J.count("0")
g Q - ^>=Q (Is the holiness great enough)
e - ^[-1]
Takes input in the form h \n n