44
\$\begingroup\$

Question :

You will be given the starting and ending integers of a sequence and should return the number of integers within it which do not contain the digit 5. The start and end numbers should be included!

Examples:

1,9 → 1,2,3,4,6,7,8,9 → Result 8

4,17 → 4,6,7,8,9,10,11,12,13,14,16,17 → Result 12

50,60 → 60 → Result 1

-59,-50 → → Result 0

The result may contain five.

The start number will always be smaller than the end number. Both numbers can be also negative!

I'm very curious for your solutions and the way you solve it. Maybe someone of you will find an easy pure mathematics solution.

Edit This is a code-golf challenge, so the shortest code wins.

\$\endgroup\$
9
  • 3
    \$\begingroup\$ @betseq: That´s close; but this one has a variable range (and requires no modulo). \$\endgroup\$
    – Titus
    Jan 20, 2017 at 5:42
  • 4
    \$\begingroup\$ I'd recommend shortest code as winning criterion and the code-golf tag (I didn't even spot that it wasn't!). Also, you should probably should put a test case that spans 50 or 500; also maybe one that spans -50, and one that spans 0 would be a good idea. \$\endgroup\$ Jan 20, 2017 at 5:45
  • 1
    \$\begingroup\$ @JonathanAllan : I will update examples. \$\endgroup\$
    – Arasuvel
    Jan 20, 2017 at 5:51
  • 4
    \$\begingroup\$ Test case: 50, 59 -> 0. \$\endgroup\$
    – Zgarb
    Jan 20, 2017 at 12:28
  • 14
    \$\begingroup\$ You say: "The start number will always be smaller than the end number." but one of your examples (-50,-59) directly contradicts this \$\endgroup\$ Jan 21, 2017 at 10:36

56 Answers 56

21
\$\begingroup\$

JavaScript (ES6), 36 33 bytes

Takes input with currying syntax (a)(b).

a=>F=b=>b<a?0:!/5/.test(b)+F(b-1)

Formatted and commented

a =>                 // outer function: takes 'a' as argument, returns F
  F = b =>           // inner function F: takes 'b' as argument, returns the final result
    b < a ?          // if b is less than a
      0              //   return 0
    :                // else
      !/5/.test(b) + //   add 1 if the decimal representation of b does not contain any '5'
      F(b - 1)       //   and do a recursive call to F with b - 1

Test cases

let f =

a=>F=b=>b<a?0:!/5/.test(b)+F(b-1)

console.log(f(1)(9))
console.log(f(4)(17))
console.log(f(50)(60))
console.log(f(-50)(-59))

\$\endgroup\$
12
  • \$\begingroup\$ (I normally prefer test over exec when you only need a boolean.) \$\endgroup\$
    – Neil
    Jan 20, 2017 at 9:01
  • \$\begingroup\$ @Neil That makes more sense indeed. Updated. \$\endgroup\$
    – Arnauld
    Jan 20, 2017 at 9:07
  • \$\begingroup\$ NB: I couldn't find any tip about ES6 currying syntax, so I wrote one. \$\endgroup\$
    – Arnauld
    Jan 20, 2017 at 10:51
  • 6
    \$\begingroup\$ @TheLethalCoder b<a is there to stop the recursion after counting through all numbers from b to a, so removing it would just cause an infinite recursion. \$\endgroup\$ Jan 20, 2017 at 12:37
  • 1
    \$\begingroup\$ @HristiyanDodov The unnamed outer function takes a as argument and returns the F function, which in turn takes b as argument and -- as you noticed -- is called recursively to iterate from b to a, incrementing a counter for all integers that do not contain a 5 in their decimal representation. \$\endgroup\$
    – Arnauld
    Jan 20, 2017 at 14:06
17
\$\begingroup\$

Jelly, 8 7 bytes

-1 byte thanks to Dennis (use fact that indexing into a number treats that number as a decimal list)

rAw€5¬S

TryItOnline!

How?

rAw€5¬S - Main link: from, to    e.g. -51, -44
r       - range(from, to)        e.g. [-51,-50,-49,-48,-47,-46,-45,-44]
 A      - absolute value         e.g. [51,50,49,48,47,46,45,44]
  w€    - first index of... for €ach (0 if not present)
    5   - five                   e.g. [1,1,0,0,0,0,2,0]
     ¬  - logical not            e.g. [0,0,1,1,1,1,0,1]
      S - sum                    e.g. 5

* The absolute value atom, A is necessary since a negative number cast to a decimal list has negative entries, none of which would ever be a 5 (the given example would count all eight rather than two).

\$\endgroup\$
3
  • \$\begingroup\$ rAw€5¬S saves a byte. \$\endgroup\$
    – Dennis
    Jan 20, 2017 at 8:22
  • \$\begingroup\$ @Dennis thanks! Is my description "treats that number as a decimal list" accurate? \$\endgroup\$ Jan 20, 2017 at 8:36
  • 2
    \$\begingroup\$ Pretty much. w casts an integer argument to its decimal digits. \$\endgroup\$
    – Dennis
    Jan 20, 2017 at 8:37
15
\$\begingroup\$

Bash + grep, 17 bytes

seq $@|grep -cv 5

Try it online!

\$\endgroup\$
13
\$\begingroup\$

2sable, 6 5 bytes

Saved a byte thanks to Adnan

Ÿ5¢_O

Try it online!

Explanation

 Ÿ      # inclusive range
  5¢    # count 5's in each element of the range
    _   # negate
     O  # sum

Note: This works due to a bug in ¢ making the function apply itself to each element instead of counting matching elements in the list.

\$\endgroup\$
2
  • \$\begingroup\$ You can remove the ` as it behaves the same on arrays :p. \$\endgroup\$
    – Adnan
    Jan 20, 2017 at 11:34
  • \$\begingroup\$ @Adnan: Thanks! I was gonna test that but forgot ;) \$\endgroup\$
    – Emigna
    Jan 20, 2017 at 12:45
9
\$\begingroup\$

Python2, 59 55 52 51 47 43 42 bytes

f=lambda a,b:a<=b and-(`5`in`a`)-~f(a+1,b)

A recursive solution. Thanks to @xnor for giving me motivation to find a solution using logical operators! Also, thanks to @JonathanAllan and @xnor for guiding me and chopping the byte from 43 to 42!

Other attempts at 43 bytes

f=lambda a,b:a<=b and-~-(`5`in`a`)+f(a+1,b)
f=lambda a,b:a<=b and 1-(`5`in`a`)+f(a+1,b)
\$\endgroup\$
9
  • \$\begingroup\$ Would if!`x`.count('5') work? \$\endgroup\$
    – Titus
    Jan 20, 2017 at 6:29
  • 2
    \$\begingroup\$ @Titus Python has not operator that is ! in C-like languages, but that takes 3 bytes :( \$\endgroup\$
    – Yytsi
    Jan 20, 2017 at 6:31
  • 1
    \$\begingroup\$ Think about using logical short-circuiting with and and or. \$\endgroup\$
    – xnor
    Jan 20, 2017 at 7:37
  • 1
    \$\begingroup\$ Yup, nicely done! Now think about shortening that not. \$\endgroup\$
    – xnor
    Jan 20, 2017 at 7:48
  • 1
    \$\begingroup\$ You're really close! Keep trying stuff. \$\endgroup\$
    – xnor
    Jan 20, 2017 at 8:28
6
\$\begingroup\$

Bash / Unix utilities, 21 bytes

seq $*|sed /5/d|wc -l

Try it online!

\$\endgroup\$
6
\$\begingroup\$

05AB1E, 8 7 6 bytes

Saved a byte thanks to Adnan

Ÿ5.å_O

Try it online!

Explanation

Ÿ         # inclusive range
 5.å      # map 5 in y for each y in the list
    _     # logical negation 
     O    # sum
\$\endgroup\$
3
  • \$\begingroup\$ 05AB1E also has vectorized å, which is , so you can do Ÿ5.å_O for 6 bytes. \$\endgroup\$
    – Adnan
    Jan 20, 2017 at 11:24
  • \$\begingroup\$ negate meaning -n, or n==0?1:0? \$\endgroup\$ Jan 20, 2017 at 12:38
  • \$\begingroup\$ @ETHproductions: Sorry, that was unclear. I meant logical negation, so n==0?1:0 \$\endgroup\$
    – Emigna
    Jan 20, 2017 at 12:46
6
\$\begingroup\$

Pyth, 9 8 bytes

Saved a byte thanks to FryAmTheEggman!

lf-\5T}E

Explanation:

        Q # Input
      }E  # Form an inclusive range starting from another input
          #   order is reversed, but doesn't matter
 f-\5T    # Filter by absence of '5'
l         # Count the number of elements left

Try it online!

\$\endgroup\$
0
5
\$\begingroup\$

Perl 6, 23 bytes

{+grep {!/5/},$^a..$^b}

Try it online!

How it works

{                     }  # A lambda.
              $^a..$^b   # Range between the two lambda arguments.
  grep {!/5/},           # Get those whose string representation doesn't match the regex /5/.
 +                       # Return the size of this list.
\$\endgroup\$
5
\$\begingroup\$

Haskell, 39 bytes

s!e=sum[1|x<-[s..e],notElem '5'$show x]

Try it online! Usage:

Prelude> 4 ! 17
12

Explanation:

             [s..e]                     -- yields the range from s to e inclusive
          x<-[s..e]                     -- for each x in this range
          x<-[s..e],notElem '5'$show x  -- if the char '5' is not in the string representation of x
       [1|x<-[s..e],notElem '5'$show x] -- then add a 1 to the resulting list      
s!e=sum[1|x<-[s..e],notElem '5'$show x] -- take the sum of the list
\$\endgroup\$
4
\$\begingroup\$

R, 33 bytes

f=function(x,y)sum(!grepl(5,x:y))

Usage:

> f=function(x,y)sum(!grepl(5,x:y))
> f(40,60)
[1] 10
> f(1,9)
[1] 8
> f(4,17)
[1] 12
\$\endgroup\$
4
\$\begingroup\$

Octave, 36 bytes

@(m,n)sum(all(dec2base(m:n,10)'-52))

Try it online!

\$\endgroup\$
0
4
\$\begingroup\$

Groovy, 47 45 43 40 bytes

{a,b->(a..b).findAll{!(it=~/5/)}.size()}

This is an unnamed closure. findAll is similar to adding an if condition in a list comprehension in python.

Try it online!

\$\endgroup\$
4
\$\begingroup\$

PHP 7.1, 57 55 bytes

for([,$a,$b]=$argv;$a<=$b;)$n+=!strstr($a++,53);echo$n;

Run with php -r '<code>' <a> <b>

\$\endgroup\$
8
  • \$\begingroup\$ Isn't this PHP7.1 syntax? \$\endgroup\$
    – aross
    Jan 20, 2017 at 10:06
  • \$\begingroup\$ @aross: It is. But PHP 7.1 is older than 5 hours (pubished on December, 1) \$\endgroup\$
    – Titus
    Jan 20, 2017 at 10:50
  • 1
    \$\begingroup\$ of course, I just asked because I'm used to specifying the version if it's 7 or up. That's also kind of the convention for Python \$\endgroup\$
    – aross
    Jan 20, 2017 at 11:00
  • 1
    \$\begingroup\$ Convention for PHP - as far as I have seen - is to use the most recent version unless specified otherwise. \$\endgroup\$
    – Titus
    Jan 20, 2017 at 16:12
  • \$\begingroup\$ I don't think many people have the latest minor version. The least common denominator at the moment would probably be 5.5. Personally I'm using FC 25 (considered pretty cutting edge), which currently distributes PHP 7.0. If you're on Windows you probably need to update manually. \$\endgroup\$
    – aross
    Jan 20, 2017 at 16:17
4
\$\begingroup\$

Mathematica, 46 44 42 bytes

Thanks to alephalpha and DavidC for saving 2 bytes each!

Tr@Boole[FreeQ@5/@IntegerDigits@Range@##]&

Unnamed function taking two integer arguments and returning an integer. IntegerDigits@Range@## converts all the numbers between the inputs into lists of digits; FreeQ@5 tests those lists to decide which ones do not contain any 5. Then Boole converts booleans to zeros and ones, and Tr sums the results.

Other solutions (44 and 47 bytes):

Count[Range@##,x_/;IntegerDigits@x~FreeQ~5]&

IntegerDigits@x~FreeQ~5 determines whether the list of digits of a number is free of 5s, and Count[Range@##,x_/;...]& counts how many numbers between the inputs pass that test.

Tr[Sign[1##&@@IntegerDigits@#-5]^2&/@Range@##]&

1##&@@IntegerDigits@#-5 takes the list of digits of a number, subtracts 5 from all of them, and multplies the answers together; Sign[...]^2 then converts all nonzero numbers to 1.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Count[Range@##,x_/;IntegerDigits@x~FreeQ~5]& \$\endgroup\$
    – DavidC
    Jan 20, 2017 at 12:59
  • 1
    \$\begingroup\$ Tr@Boole[FreeQ@5/@IntegerDigits@Range@##]& \$\endgroup\$
    – alephalpha
    Jan 21, 2017 at 3:42
3
\$\begingroup\$

Ruby, 36 35 bytes

->a,b{(a..b).count{|x|!x.to_s[?5]}}

Thx IMP1 for -1 byte

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Doesn't this return the list without the numbers containing 5, rather than the size of that list? \$\endgroup\$
    – IMP1
    Jan 20, 2017 at 10:49
  • \$\begingroup\$ You are right, I have copy/pasted the wrong version. \$\endgroup\$
    – G B
    Jan 20, 2017 at 11:00
  • 1
    \$\begingroup\$ You can also use ?5 (the '5' character) instead of /5/ in the search to save a byte. \$\endgroup\$
    – IMP1
    Jan 20, 2017 at 11:03
3
\$\begingroup\$

Java 7, 80 78 bytes

int c(int a,int b){int r=0;for(;a<=b;)r+=(""+a++).contains("5")?0:1;return r;}

Ungolfed:

int c(int a, int b){
  int r = 0;
  for (; a <= b; ) {
    r += ("" + a++).contains("5")
          ? 0
          : 1;
  }
  return r;
}

Test code:

Try it here.

class M{
  static int c(int a,int b){int r=0;for(;a<=b;)r+=(""+a++).contains("5")?0:1;return r;}

  public static void main(String[] a){
    System.out.println(c(1, 9));
    System.out.println(c(4, 17));
  }
}

Output:

8
12
\$\endgroup\$
3
\$\begingroup\$

PowerShell, 42 41 bytes

param($a,$b)$a..$b|%{$z+=!($_-match5)};$z

Called from the command line as .\no5s.ps1 1 20

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can drop the space to save a byte. With strictly numerical regex patterns, you don't need a delimiter (e.g., -replace3 or -split1 or -notmatch5). \$\endgroup\$ Jan 20, 2017 at 15:18
  • \$\begingroup\$ Ah, nice, thanks @AdmBorkBork \$\endgroup\$
    – mcmurdo
    Jan 20, 2017 at 20:46
3
\$\begingroup\$

Regex 🐇 (Perl / PCRE), 160 147 bytes

^(?(?=-x*,(?!-))-?+x*(,x*(?!$))?|-?(?=(x*),-?(x*))(?=(x*),?(?=\2)(?=\3)(x*,-?|[^,]*)(x*))\4,?+x*)(?!((?=(x+)(\8{9}x*))\9)*(x{10})*x{5}\b)(?(4)\4\6)

Try it online! - Perl
Try it online! - PCRE (faster)

Takes its input in unary, as two strings of x characters whose lengths represent the numbers, with optional - signs on their left side, joined by a , delimiter. Returns its output as the number of ways the regex can match. (The rabbit emoji indicates this output method.)

Most of the logic of this regex is taken up with handling the logic of integer ranges. It's rather unnatural... literally. Natural numbers (including zero) are much easier for a regex to operate on.

^
(?(?=-x*,(?!-))
    # Do the following if A is negative and B is nonnegative
    -?+                     # skip sign of A, if any
    x*                      # handle the range from larger to zero, inclusive
    (,x*(?!$))?             # handle the range from B inclusive to zero exclusive
|
    # Do the following if A is nonnegative or B is negative
    -?                      # skip sign of A, if any
    (?=
          (x*),             # \2 = abs(A); 
        -?(x*)              # \3 = abs(B)
    )
    (?=
        (x*),?(?=\2)(?=\3)  # \4 = what to skip so tail = the larger of A or B;
                            # tail = the larger of A or B
        (x*,-?|[^,]*)(x*)   # \6 = {the smaller of A or B} - \4
    )
    \4,?+                   # tail = the larger of A or B
    x*                      # handle the range from larger to {smaller or zero}
)
(?!                         # Negative lookahead - assert this can't match
    (
        (?=(x+)(\8{9}x*))   # \8 = floor(tail / 10); \9 = tail - \8
        \9                  # tail = tail - \9 == \8
    )*                      # Iterate the above any number of times, minimum zero
    (x{10})*x{5}\b          # Assert tail % 10 == 5
)
(?(4)\4\6)                  # If \4 is set, clamp the range at the smaller end

It uses conditionals, which are not supported by ECMAScript, but it'd be easy enough to port (though the regex would be even longer). The 🐇 output method is required for this algorithm to be possible in ECMAScript (there isn't yet a regex engine that can emulate ECMAScript and count possible matches, but I'm planning on adding this to RegexMathEngine soon).

Regex (.NET), 163 bytes

^(?=(-x*,(?!-))?)(?>-?)(?(1)|(?=(x*),-?(x*))(?=(x*),?(?=\2)(?=\3)(x*,-?|[^,]*)(x*))\4(?>,?))(?(,)(?(1),)|(?(((?=(x+)(\8{9}x*))\9)*(x{10})*x{5}\b)|())x?)*(?(4)\4\6)

Try it online!

Returns its output as the capture count of group \11.

^
(?=
    (-x*,(?!-))?            # \1 = set iff A is negative and B is nonnegative
)
(?>-?)                      # skip sign of A, if any
(?(1)
|
    # Do the following if A is nonnegative or B is negative
    (?=
          (x*),             # \2 = abs(A); 
        -?(x*)              # \3 = abs(B)
    )
    (?=
        (x*),?(?=\2)(?=\3)  # \4 = what to skip so tail = the larger of A or B;
                            # tail = the larger of A or B
        (x*,-?|[^,]*)(x*)   # \6 = {the smaller of A or B} - \4
    )
    \4                      # tail = the larger of A or B
    (?>,?)                  # skip sign of B, if any
)
                            # First handle the range from larger inclusive to
                            # {smaller inclusive or 0 exclusive}
(?(,)
    (?(1),)                 # If crossing from negative to nonnegative, handle
                            # the inclusive range from B to 0
|
    (?(
        (
            (?=(x+)(\8{9}x*))   # \8 = floor(tail / 10); \9 = tail - \8
            \9                  # tail = tail - \9 == \8
        )*                      # Iterate the above any number of times
        (x{10})*x{5}\b          # Assert tail % 10 == 5
      )
    |
        ()                  # Push a capture onto the \11 stack
    )
    x?                      # Advance by 1, but if already at the end, allow the
                            # loop to iterate once more so as to include 0 in
                            # the count.
)*
(?(4)\4\6)                  # If \4 is set, clamp the range at the smaller end

It could also be ported to an output method of the sum of the lengths of two capture groups (two, because the output can exceed the largest of the two inputs), though this would probably make it significantly longer.

\$\endgroup\$
3
\$\begingroup\$

Thunno 2 S, 6 bytes

Id5ȷc~

(No ATO link since it's down at the moment)

Explanation

Id5ȷc~  # Implicit input   ->    1,                                  10
I       # Inclusive range  ->   [1,  2,  3,  4,  5,  6,  7,  8,  9,  10]
 d      # Cast to digits   ->  [[1],[2],[3],[4],[5],[6],[7],[8],[9],[1,0]]
   ȷ    # To each list:    ->   [1] [2] [3] [4] [5] [6] [7] [8] [9] [1,0]
  5 c   #  Count 5s        ->    0   0   0   0   1   0   0   0   0   0
     ~  # Logical NOT      ->   [1,  1,  1,  1,  0,  1,  1   1,  1,  1]
        # Implicit sum     ->                      9
        # Implicit output
\$\endgroup\$
2
\$\begingroup\$

Python 2, 61 56 bytes

lambda a,b:len([n for n in range(a,b+1) if not"5"in`n`])

-5 bytes thanks to tukkaaX

\$\endgroup\$
5
  • \$\begingroup\$ Don't get discouraged! Having fun and challenging yourself is what matters. You can remove two whitespaces at not "5" in :) Also, if you're using Python2, you can surround x with `` quotes, instead of doing str(x). \$\endgroup\$
    – Yytsi
    Jan 20, 2017 at 6:59
  • \$\begingroup\$ @TuukkaX Thanks! also removed space between in and `x` \$\endgroup\$
    – sagiksp
    Jan 20, 2017 at 7:52
  • \$\begingroup\$ You can remove the []. You also don't need the space before if. \$\endgroup\$
    – Dennis
    Jan 20, 2017 at 8:16
  • \$\begingroup\$ @Dennis I tried that already, but it complains that "object of type 'generator' has no len()". \$\endgroup\$
    – Yytsi
    Jan 20, 2017 at 8:26
  • \$\begingroup\$ @TuukkaX Right. lambda a,b:sum(not"5"in`n`for n in range(a,b+1)) works though. tio.run/nexus/… \$\endgroup\$
    – Dennis
    Jan 20, 2017 at 8:29
2
\$\begingroup\$

Swift 52 bytes

($0...$1).filter { !String($0).contains("5") }.count
\$\endgroup\$
1
  • \$\begingroup\$ Since your challenge is a codegolf challenge, you should include your bytecount. Also, in codegolf (at least here), it's a requirement that all programs muse be actually contending (e.g. your function name can be just a single character, your actual function can probably be reduced to a single line). I don't know Swift, you might have to correct me on stuff. \$\endgroup\$
    – clismique
    Jan 20, 2017 at 5:53
2
\$\begingroup\$

Batch, 95 bytes

@set/an=0,i=%1
:g
@if "%i%"=="%i:5=%" set/an+=1
@set/ai+=1
@if %i% leq %2 goto g
@echo %n%

Manually looping saves some bytes because I need the loop counter in a variable anyway.

\$\endgroup\$
2
\$\begingroup\$

PHP, 56 bytes

for($i=$argv[1];$i<=$argv[2];)trim(5,$i++)&&$x++;echo$x;

Run like this:

php -r 'for($i=$argv[1];$i<=$argv[2];)trim(5,$i++)&&$x++;echo$x;' 1 9 2>/dev/null;echo
> 8

A version for PHP 7.1 would be 53 bytes (credits to Titus):

for([,$i,$e]=$argv;$i<=$e;)trim(5,$i++)&&$x++;echo$x;

Explanation

for(
  $i=$argv[1];          # Set iterator to first input.
  $i<=$argv[2];         # Loop until second input is reached.
)
  trim(5,$i++) && $x++; # Trim string "5" with the characters in the
                        # current number; results in empty string when
                        # `5` is present in the number. If that is not
                        # the case, increment `$x`

echo$x;                 # Output `$x`
\$\endgroup\$
1
  • \$\begingroup\$ Ah dang I forgot about the second trim parameter again. \$\endgroup\$
    – Titus
    Jan 20, 2017 at 10:51
2
\$\begingroup\$

CJam "easy pure mathematics solution", 60

{{Ab5+_,\_5#)<\9e]);_4f>.m9b}%}:F;q~_:z$\:*0>{((+F:-}{F:+)}?

Try it online

It takes the numbers in any order, in an array.

Explanation:

One core problem is to calculate f(n) = the number of non-5 numbers from 1 to n (inclusive) for any positive n. And the answer is: take n's decimal digits, replace all digits after the first 5 (if any) with 9, then replace all digits 5..9 with 4..8 (decrement), and convert from base 9. E.g. 1752 → 1759 → 1648 → 1*9^3+6*9^2+4*9+8=1259. Basically, each digit position has 9 acceptable values, and a 5xxxx is equivalent to a 49999 because there are no more valid numbers between them.

Once we solved this, we have a few cases: if the input numbers (say a and b, a<b) are (strictly) positive, then the result is f(b)-f(a-1). If they are negative, then we can take the absolute values, reorder them and use the same calculation. And if a<=0<=b then the result is f(-a)+f(b)+1.

The program first implements the function F as described above (but applied to each number in an array), then reads the input, converts the numbers to the absolute value and reorders them, and uses one of the 2 calculations above, based on whether a*b>0 initially.

\$\endgroup\$
2
  • \$\begingroup\$ Not "pure" but nice method. here, get a +1 :) \$\endgroup\$ Jan 23, 2017 at 9:13
  • \$\begingroup\$ @MatthewRoh thanks, but what do you mean not pure? It's a solution that does fairly direct mathematical calculations on the input numbers, without iterating through the range. What else were you expecting? \$\endgroup\$ Jan 23, 2017 at 9:35
2
\$\begingroup\$

Python 2, 54 bytes

i,j=input();k=0
while i<=j:k+=not"5"in`i`;i+=1
print k

Try it online!

Not the shortest Python answer Uses same algorithm but a different way of implementing with a while loop and is not a lambda function.

\$\endgroup\$
4
  • \$\begingroup\$ It is a program and not a function and it uses while instead of for. What is not different? OK, it is still looking for a string "5" inside the incremented input, agreed. Is there a better way? \$\endgroup\$
    – ElPedro
    Jan 20, 2017 at 13:10
  • \$\begingroup\$ That's exactly what it is and that's why it is deferent. Sorry, maybe should have made my comment different. \$\endgroup\$
    – ElPedro
    Jan 20, 2017 at 18:34
  • \$\begingroup\$ Same algorithm, different way of implementing. No problem with your comments. Is that better worded? \$\endgroup\$
    – ElPedro
    Jan 20, 2017 at 18:36
  • \$\begingroup\$ It is, yes :) I'll remove these comments to make the comment section look clean. \$\endgroup\$
    – Yytsi
    Jan 20, 2017 at 20:58
2
\$\begingroup\$

C++ | in too many bytes, 165 125 thanks to Christoph!

int main(){int c=0;for(int i=0;i<=8;i++){int d;int n=i>=0?i:-i;while(n!=0){if(d=n%10==5){break;}n=n/10;c++;break;}}return c;}   

I took the liberty of creating a function e_ to determine if a 5(or any other number) is present in an integer instead of using to_string() and .find() so that must count for something. note: e_ is only declared as an extra function in the un-golfed version for readability.

un-golfed:

int e_(int e,int i){
    int d;
    int n=i>=0?i:-i;
    while (n != 0){
        d=n%10;
        if (d==e){
        return 1;}
        n=n/10;}
        return 0;}
int main() {
    int l = 1;int h = 8;int e = 5;int c = 0;
    for(int i=l; i<=h; i++){
        if (e_(e,i)==0)     
        c++;}
    return c;}

How e_ function works:

int n=i>=0?i:-i; Inverses our number if it is less than 0 so it's always positive. d=n%10; Divides it by 10 and gets remainder (n%base; will always return the last digit of an integer). We check that it equals 5, if it does the number can be discarded, if not n=n/10; removes the end digit and loops again.

\$\endgroup\$
2
  • \$\begingroup\$ #include <iostream> and using namespace std; can be dropped. Declaring an extra function is not going to save you bytes. if (e_(e,i)==0) c++;could be reduced to c+=e_(e,i)==0;. Come on ! You can do better ! :) \$\endgroup\$
    – Christoph
    Jan 24, 2017 at 14:05
  • 1
    \$\begingroup\$ Your right declaring an extra function is not going to save me bytes which is why It was only left in the un-golfed version for readability, <iostream> and namespace std; are unnecessary not sure why I didn't realise, habit I guess... thanks for the input and pointing out my mistake :) \$\endgroup\$
    – GCaldL
    Jan 27, 2017 at 2:52
2
\$\begingroup\$

Hoon, 110 94 bytes

Hoon's range function, gulf, doesn't work for signed integers, which increases the length by a bit :(

=+
si^f=:(curr lien test 53)
|=
{a/@s b/@s}
|-
?:
=(a b)
(f <b>)
(add (f <a>) $(a (sum -1 a)))

Use the signed integer library. Create a function f: :(a b c d) is a macro that expands into (a b (a c d)) so this is (curr lien (curr test 53)), aka create a curried function that tests if any element of a list is 53 ('5')

Create a function that takes a and b. Create a loop: if a==b return f(tostring(b)), else return add(f(tostring(a)) recurse(a=a+1))

> =f =+
  si^f=:(curr lien test 53)
  |=
  {a/@s b/@s}
  |-
  ?:
  =(a b)
  (f <b>)
  (add (f <a>) $(a (sum -1 a)))
> (f -1 -9)
8
> (f -4 -17)
12
> (f -50 -60)
1
> (f --59 --50)
0

(Hoon's signed integers use - as a prefix, so --5 is negative 5 and -5 is positive 5)

\$\endgroup\$
2
\$\begingroup\$

SmileBASIC, 55 bytes

INPUT S,E
FOR I=S TO E
INC N,INSTR(STR$(I),"5")<0NEXT?N

Nothing special, just uses INSTR and STR$ to check for 5.

\$\endgroup\$
1
\$\begingroup\$

Java 7, 77 bytes

This is an improvement of Kevins Answer, but since I don't have the reputation to comment yet, this new answer will have to do.

So what I did was:

  • Replace the indexOf statements with contains (-1 byte)
  • Move the incrementing part of the for-loop into the conditional statement (-2 bytes)

for-loop (77 bytes):

int c(int a,int b){int r=1;for(;a++<b;)r+=(""+a).contains("5")?0:1;return r;}

recursive (79 bytes):

int d(int r,int a,int b){r+=(""+a).contains("5")?0:1;return a!=b?d(r,a+1,b):r;}

Output:

8
12

8
12

Test it here !

\$\endgroup\$
4
  • \$\begingroup\$ Wellcome to PPCG ! Nice findings in an already quite nicely golfed answer. I don't know about Java that much but shouldn't (""+a).contains("5")?0:1 be replacable by !(""+a).contains("5")? \$\endgroup\$
    – Christoph
    Jan 27, 2017 at 6:56
  • 1
    \$\begingroup\$ @Christoph sadly no, since in Java a boolean really is just a boolean. So a ternary operation is the only way to go. \$\endgroup\$ Jan 27, 2017 at 9:13
  • \$\begingroup\$ Hm that's sad. What about (""+a).contains("5")||r++? \$\endgroup\$
    – Christoph
    Jan 27, 2017 at 9:15
  • 1
    \$\begingroup\$ @Christoph that won't work either, because you can't have a boolean expression on its own. I've been trying to make it work in other places (like the for-loop declaration) but not with much success. Nice idea tho ;) \$\endgroup\$ Jan 27, 2017 at 13:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.