Don't give me five!

38

3

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.

Arasuvel

Posted 2017-01-20T05:27:49.293

Reputation: 403

3@betseq: That´s close; but this one has a variable range (and requires no modulo). – Titus – 2017-01-20T05:42:28.650

4I'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. – Jonathan Allan – 2017-01-20T05:45:40.683

@Qwerp-Derp: Add winning criteria. – Arasuvel – 2017-01-20T05:50:54.857

1@JonathanAllan : I will update examples. – Arasuvel – 2017-01-20T05:51:33.527

4Test case: 50, 59 -> 0. – Zgarb – 2017-01-20T12:28:30.243

Test case: -10 4 – Joshpbarron – 2017-01-20T13:47:55.357

Can the input contain 5? – Digital Trauma – 2017-01-20T16:04:58.430

14You say: "The start number will always be smaller than the end number." but one of your examples (-50,-59) directly contradicts this – theonlygusti – 2017-01-21T10:36:06.020

What about giving a bounty on the most "mathematical" answer that you think? – Matthew Roh – 2017-01-23T09:16:00.840

Answers

21

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))

Arnauld

Posted 2017-01-20T05:27:49.293

Reputation: 111 334

(I normally prefer test over exec when you only need a boolean.) – Neil – 2017-01-20T09:01:27.247

@Neil That makes more sense indeed. Updated. – Arnauld – 2017-01-20T09:07:45.603

NB: I couldn't find any tip about ES6 currying syntax, so I wrote one.

– Arnauld – 2017-01-20T10:51:04.547

Wow, that's a great answer! Almost two times smaller than mine... Can you explain a bit how it works? I can see you call F recursively and save its return value which is based on the regex. But that currying syntax? How does that happen? Its so mind-blowing to me. – Hristiyan Dodov – 2017-01-20T11:32:56.277

Assuming I read your snippet correctly, you can remove the b<a check because of this line in the question: The start number will always be smaller than the end number. – TheLethalCoder – 2017-01-20T12:26:56.250

5@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. – ETHproductions – 2017-01-20T12:37:10.273

@ETHproductions I wasn't 100% I was right as I'm not that familiar with JavaScript :) – TheLethalCoder – 2017-01-20T12:40:03.147

1@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. – Arnauld – 2017-01-20T14:06:00.823

@Arnauld you should probably add that explanation to the body of your answer. – Patrick Roberts – 2017-01-20T18:22:57.943

@PatrickRoberts Done :) – Arnauld – 2017-01-20T18:33:11.227

Strict mode might be angry with you. :) – Craig Lafferty – 2017-01-20T23:01:22.863

@Arasuvel Thanks for accepting this. But since this is a code-golf challenge, you should either accept the shortest code or no answer at all. – Arnauld – 2017-11-30T08:14:58.657

17

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).

Jonathan Allan

Posted 2017-01-20T05:27:49.293

Reputation: 67 804

rAw€5¬S saves a byte. – Dennis – 2017-01-20T08:22:22.233

@Dennis thanks! Is my description "treats that number as a decimal list" accurate? – Jonathan Allan – 2017-01-20T08:36:38.560

2Pretty much. w casts an integer argument to its decimal digits. – Dennis – 2017-01-20T08:37:53.517

13

Bash + grep, 17 bytes

seq $@|grep -cv 5

Try it online!

Dennis

Posted 2017-01-20T05:27:49.293

Reputation: 196 637

13

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.

Emigna

Posted 2017-01-20T05:27:49.293

Reputation: 50 798

You can remove the ``` as it behaves the same on arrays :p. – Adnan – 2017-01-20T11:34:54.927

@Adnan: Thanks! I was gonna test that but forgot ;) – Emigna – 2017-01-20T12:45:27.780

9

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)

Yytsi

Posted 2017-01-20T05:27:49.293

Reputation: 3 582

Would if!\x`.count('5')` work? – Titus – 2017-01-20T06:29:46.850

2@Titus Python has not operator that is ! in C-like languages, but that takes 3 bytes :( – Yytsi – 2017-01-20T06:31:41.527

1Think about using logical short-circuiting with and and or. – xnor – 2017-01-20T07:37:43.583

@xnor Got it, thanks! I had to only use and though. – Yytsi – 2017-01-20T07:46:24.893

1Yup, nicely done! Now think about shortening that not. – xnor – 2017-01-20T07:48:22.277

@xnor I can't seem to get to the right solution... I can do ~- before the parentheses, but that negates the result, which I fix with another minus sign... bringing the solution back to 43 bytes :/ Any hints? – Yytsi – 2017-01-20T08:17:48.780

1You're really close! Keep trying stuff. – xnor – 2017-01-20T08:28:12.693

@xnor I'm still not getting it under 43 bytes :/ I need to negate the ('5'in'a') expression, without Python making an implicit cast to boolean, but each operator that I use, makes the cast. – Yytsi – 2017-01-20T09:11:53.627

Let us continue this discussion in chat.

– xnor – 2017-01-20T09:12:49.757

6

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!

busukxuan

Posted 2017-01-20T05:27:49.293

Reputation: 2 728

6

Bash / Unix utilities, 21 bytes

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

Try it online!

Mitchell Spector

Posted 2017-01-20T05:27:49.293

Reputation: 3 392

6

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

Emigna

Posted 2017-01-20T05:27:49.293

Reputation: 50 798

05AB1E also has vectorized å, which is , so you can do Ÿ5.å_O for 6 bytes. – Adnan – 2017-01-20T11:24:12.403

negate meaning -n, or n==0?1:0? – ETHproductions – 2017-01-20T12:38:05.837

@ETHproductions: Sorry, that was unclear. I meant logical negation, so n==0?1:0 – Emigna – 2017-01-20T12:46:47.983

5

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

Laikoni

Posted 2017-01-20T05:27:49.293

Reputation: 23 676

5

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.

smls

Posted 2017-01-20T05:27:49.293

Reputation: 4 352

4

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>

Titus

Posted 2017-01-20T05:27:49.293

Reputation: 13 814

Isn't this PHP7.1 syntax? – aross – 2017-01-20T10:06:44.567

@aross: It is. But PHP 7.1 is older than 5 hours (pubished on December, 1)

– Titus – 2017-01-20T10:50:47.270

1of 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 – aross – 2017-01-20T11:00:04.587

1Convention for PHP - as far as I have seen - is to use the most recent version unless specified otherwise. – Titus – 2017-01-20T16:12:29.083

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. – aross – 2017-01-20T16:17:03.607

@aross What is FC? – Titus – 2017-01-20T16:55:39.503

v5.5 shouldn't be considered lcd, it was end-of-lifed six months ago... – Alex Howansky – 2017-01-20T21:57:13.747

FC is Fedora Core. @AlexHowansky: right, I forgot about 5.6. But I doubt even 7.0 is the dominant version at the moment, never mind 7.1 – aross – 2017-01-23T09:09:52.480

4

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!

Gurupad Mamadapur

Posted 2017-01-20T05:27:49.293

Reputation: 1 791

4

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.

Greg Martin

Posted 2017-01-20T05:27:49.293

Reputation: 13 940

1Count[Range@##,x_/;IntegerDigits@x~FreeQ~5]& – DavidC – 2017-01-20T12:59:11.760

1Tr@Boole[FreeQ@5/@IntegerDigits@Range@##]& – alephalpha – 2017-01-21T03:42:52.763

4

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

plannapus

Posted 2017-01-20T05:27:49.293

Reputation: 8 610

4

Octave, 36 bytes

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

Try it online!

Luis Mendo

Posted 2017-01-20T05:27:49.293

Reputation: 87 464

3

Ruby, 36 35 bytes

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

Thx IMP1 for -1 byte

G B

Posted 2017-01-20T05:27:49.293

Reputation: 11 099

1Doesn't this return the list without the numbers containing 5, rather than the size of that list? – IMP1 – 2017-01-20T10:49:04.303

You are right, I have copy/pasted the wrong version. – G B – 2017-01-20T11:00:16.317

1You can also use ?5 (the '5' character) instead of /5/ in the search to save a byte. – IMP1 – 2017-01-20T11:03:28.057

3

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

Kevin Cruijssen

Posted 2017-01-20T05:27:49.293

Reputation: 67 575

3

PowerShell, 42 41 bytes

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

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

mcmurdo

Posted 2017-01-20T05:27:49.293

Reputation: 71

1You 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). – AdmBorkBork – 2017-01-20T15:18:06.190

Ah, nice, thanks @AdmBorkBork – mcmurdo – 2017-01-20T20:46:46.683

2

Swift 52 bytes

($0...$1).filter { !String($0).contains("5") }.count

Arasuvel

Posted 2017-01-20T05:27:49.293

Reputation: 403

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. – clismique – 2017-01-20T05:53:05.817

2

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

sagiksp

Posted 2017-01-20T05:27:49.293

Reputation: 1 249

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). – Yytsi – 2017-01-20T06:59:54.900

@TuukkaX Thanks! also removed space between in and `x` – sagiksp – 2017-01-20T07:52:16.977

You can remove the []. You also don't need the space before if. – Dennis – 2017-01-20T08:16:45.557

@Dennis I tried that already, but it complains that "object of type 'generator' has no len()". – Yytsi – 2017-01-20T08:26:11.303

@TuukkaX Right. lambda a,b:sum(not"5"in`n`for n in range(a,b+1)) works though. https://tio.run/nexus/python2#S1OwVYj5n5OYm5SSqJCok2RVXJqrkZdfomSqlJmXkJeQll@kkKeQmadQlJiXnqoBVKFtqKn5v6AoM69EIU3DRMfQXPM/AA

– Dennis – 2017-01-20T08:29:35.693

2

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.

Neil

Posted 2017-01-20T05:27:49.293

Reputation: 95 035

2

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.

ElPedro

Posted 2017-01-20T05:27:49.293

Reputation: 5 301

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? – ElPedro – 2017-01-20T13:10:57.827

That's exactly what it is and that's why it is deferent. Sorry, maybe should have made my comment different. – ElPedro – 2017-01-20T18:34:12.473

Same algorithm, different way of implementing. No problem with your comments. Is that better worded? – ElPedro – 2017-01-20T18:36:48.617

It is, yes :) I'll remove these comments to make the comment section look clean. – Yytsi – 2017-01-20T20:58:27.910

2

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`

aross

Posted 2017-01-20T05:27:49.293

Reputation: 1 583

Ah dang I forgot about the second trim parameter again. – Titus – 2017-01-20T10:51:42.370

2

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.

aditsu quit because SE is EVIL

Posted 2017-01-20T05:27:49.293

Reputation: 22 326

Not "pure" but nice method. here, get a +1 :) – Matthew Roh – 2017-01-23T09:13:49.030

@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? – aditsu quit because SE is EVIL – 2017-01-23T09:35:29.113

1

C#, 77 bytes

(n,m)=>{var g=0;for(var i=n;i<m+1;i++)g+=(i+"").Contains("5")?0:1;return g;};

Anonymous lambda call.

Uses n (first number) and m (last number) as input, then checks via string containment ("".Contains("")).

devRicher

Posted 2017-01-20T05:27:49.293

Reputation: 1 609

I'm not the one downvoting, but modulo 5 isn't the correct solution for the challenge given by OP. It should exclude anything containing the digit 5 in its number, so 10 (which your answer wouldn't count) should be counted. – Kevin Cruijssen – 2017-01-20T08:41:19.483

@KevinCruijssen Fixed. – devRicher – 2017-01-20T11:02:35.783

This doesn't compile as g must be initialised when stated as it is named var so you need var g=""; and you can use currying i.e. n=>m=> – TheLethalCoder – 2017-01-20T12:30:55.307

Also this outputs the list not the count – TheLethalCoder – 2017-01-20T12:32:36.467

Fixed both of this. @TheLethalCoder – devRicher – 2017-01-20T13:34:32.267

I meant it should output the count of items in the range not the items added together, see the test cases in the OP. This is still not working. – TheLethalCoder – 2017-01-20T13:52:17.220

1@KevinCruijssen With your edits this is essentially my answer... – TheLethalCoder – 2017-01-20T14:53:24.913

@TheLethalCoder Ah, didn't realize there was a third C# answer.. I'll delete my comment and upvote your answer. :) @ devRicher: If you change ?0:i in your current code to ?0:1 it should work. – Kevin Cruijssen – 2017-01-20T14:57:50.827

@KevinCruijssen Well I added 2 because the logic/code was essentially completely different – TheLethalCoder – 2017-01-20T15:00:10.397

1

C 143 141 132 122 bytes

f(a,b){j=0,k,f;for(;a<=b;a++){k=a;f=0;while(k!=0){if(abs(k%10)==5){f=1;break;}else f=0;k/=10;}if(f<1)j++;}printf("%d",j);}

This is a solution that adopts a mathematical approach and checks every digit for number 5. Can definitely be shortened!

Ungolfed version:

  void f(int a,int b)
  { 
       int j=0,k=0,f=0;

       for(;a<=b;a++)     
       { 
          k=a;f=0;

          while(k!=0)
          {          

            if(abs(k%10)==5) // If one of the digits in the number is 5, set a flag and break while loop, else reset the flag and continue checking.
            {
              f=1; 
              break;
            }  
            else
              f=0;

            k/=10; 

          }        

       if(f<1)
         j++; 
      }
      printf("%d ",j);       


  }

@TuukkaX Thanks for saving 2 bytes.

@nmjcman101 Thanks for saving 9 bytes.

@nmjcman101 Thanks for saving 10 bytes more, make so much sense. :)

Abel Tom

Posted 2017-01-20T05:27:49.293

Reputation: 1 150

Redundant whitespace at &&. I think that you can do a^b in each case you check for disequality, such as abs(i%10)!=5. – Yytsi – 2017-01-20T07:20:26.160

@TuukkaX I'm gonna have to modify this answer anyways since it would not work for 150, 500 – Abel Tom – 2017-01-20T07:25:24.000

Useless whitespace at (f==0) j++. If f can't be negative, you can check whether f<1. – Yytsi – 2017-01-20T13:02:47.663

@TuukkaX You're right! Updated! – Abel Tom – 2017-01-20T13:14:32.840

You don't need the first if(a<b). OP says "The start number will always be smaller than the end number." – nmjcman101 – 2017-01-20T13:29:41.773

@nmjcman101 Thanks for the clarification regarding input validation. – Abel Tom – 2017-01-20T14:02:49.617

More suggestions: i is useless, do for(;a<=b;a++) , l is useless also, do abs(k%10)==5. use a for loop instead of a while for(;k;k/=10). Then about the logic, there's two paths: current path - don't have the else in the while, then you don't need to break b/c f will stay 1 until the end. Also, set f=1 initially and then if(.==5)f=0; so that at the end you can do if(f)j++ or j+=f; The other option is to do if(==5)j--,break; in the loop and then always do j++ and skip the f entirely, I don't know which is shorter – nmjcman101 – 2017-01-20T14:30:51.960

Sure, It is mathematical, but not mathematical as mine. :P – Matthew Roh – 2017-01-23T09:11:08.163

while(k){f|=abs(k%10)==5;k/=10;}j+=1-f;} should save a bit. (Oh, I see, this is like what @nmjcman101 is saying.) – Matt – 2017-01-23T14:39:05.597

1

TI-BASIC, 37 34 bytes

:Prompt A,B
:Delvar CFor(N,A,B
:C+not(inString(toString(N),"5→C
:End
:C

I believe count is correct, however toString() is only supported on the TI-84+ CE calculators which I do not have, so I was unable to count it or test it to make sure it runs correctly. I therefore counted it as 2 bytes in addition to the others which were counted directly on a TI-84.

Thx to Jakob Cornell for removing

Golden Ratio

Posted 2017-01-20T05:27:49.293

Reputation: 143

Try DelVar C on line 2. Then you can combine lines 2 and 3.

Also on line 4, not( should work in place of 0=.

And finally, print and "return" C on the last line by omitting Disp. – Jakob – 2017-01-20T17:32:52.340

Wow, thx, I'll make the changes. Looking at this again now, yeah I definitely wasn't thinking about cutting that down, especially with Disp C :( – Golden Ratio – 2017-01-25T09:41:15.517

1

JavaScript (ES6), 58 56 49 bytes

let f =

(s,e)=>{for(c=0;s<=e;)c+=!/5/.test(s++);return c}

console.log(f(1, 9));
console.log(f(4, 17));
console.log(f(-9, -1));

Golfed 7 bytes thanks to ETHproductions.

Hristiyan Dodov

Posted 2017-01-20T05:27:49.293

Reputation: 191

1You can use c+=!/5/.test(s++) to save a few bytes :-) – ETHproductions – 2017-01-20T12:41:05.260

Thanks a lot! I had to delete my golfs, though. I was so proud of them. :( – Hristiyan Dodov – 2017-01-20T12:55:22.880

I think you can use currying i.e.s=>e=> – TheLethalCoder – 2017-01-20T12:58:25.697

The top answer uses currying syntax. I won't edit mine because it would become almost the same. Thanks for pointing that out, though!

– Hristiyan Dodov – 2017-01-20T13:01:18.557

1

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 !

Tobias Meister

Posted 2017-01-20T05:27:49.293

Reputation: 11

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")? – Christoph – 2017-01-27T06:56:08.163

1@Christoph sadly no, since in Java a boolean really is just a boolean. So a ternary operation is the only way to go. – Tobias Meister – 2017-01-27T09:13:15.197

Hm that's sad. What about (""+a).contains("5")||r++? – Christoph – 2017-01-27T09:15:01.297

1@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 ;) – Tobias Meister – 2017-01-27T13:45:08.607

1

C#, 67 bytes

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

TheLethalCoder

Posted 2017-01-20T05:27:49.293

Reputation: 6 930

I was hoping to use for(int c=0;...) but then it fails to compile because the return is outside the scope for c – TheLethalCoder – 2017-01-20T12:48:25.750

1

MATL, 10 bytes

&:!V53-!As

Try it online!

Explanation

        % Implicitly grab two input arguments
&:      % Create an array from [input1....input2]
!V      % Convert to a string where each number is it's own row
53-     % Subtract ASCII '5' from each character.
!A      % Detect which rows have no false values (no 5's). Returns a logical array
s       % Sum the logical array to get the # numbers without 5's
        % Implicitly display the result

Suever

Posted 2017-01-20T05:27:49.293

Reputation: 10 257

1

PowerShell, 37 36 bytes

($args[0]..$args[1]-notmatch5).Count

Try it online!

briantist

Posted 2017-01-20T05:27:49.293

Reputation: 3 110

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). – AdmBorkBork – 2017-01-20T15:09:25.227

Doh, how'd I miss that?! Thanks @AdmBorkBork – briantist – 2017-01-20T15:11:48.483

1

Actually, 13 bytes

u@x`$'5íuY`░l

Try it online!

Explanation:

u@x`$'5íuY`░l
u@x            range(a, b+1)
   `$'5íuY`░   take where:
    $            string representation
     '5íuY       does not contain "5"
            l  length

Mego

Posted 2017-01-20T05:27:49.293

Reputation: 32 998

1

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.

GCaldL

Posted 2017-01-20T05:27:49.293

Reputation: 21

#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 ! :) – Christoph – 2017-01-24T14:05:32.857

1Your 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 :) – GCaldL – 2017-01-27T02:52:30.397

1

CJam, 18 17 bytes

q~:S-){S+s'5&!},,

Input is end number followed by start number.

Try it online!

How it works

q~                  Read and evaluate all input. Pushes end and start.
  :S                Save the start in S.
    -)              Subtract and increment, computing L =: end - start + 1.
      {       },    Filter [0 ... L-1]; for each N in the range:
       S+             Add S to N.
         s            Cast to string.
          '5&         Intersect with '5'.
             !        Take the logical NOT.
                ,   Compute the length of the resulting array.

Dennis

Posted 2017-01-20T05:27:49.293

Reputation: 196 637

1

C++, 84 81 + 16 = 100 97 bytes

int f(int a,int b){int c;while(a<=b)c+=!~std::to_string(a++).find('5');return c;}

#include<string> - +16

Ungolfed:

int func(int start, int end) {
  // Defaults to 0
  int count;

  // Iterates from start to end (inclusive) and increments the count by one
  // if '5' is not found
  while (start <= end)
    count += !~std::to_string(start++).find('5');

  return count;
}

The function itself should be pretty clear. I essentially just iterate from start (or a) to end (or b). The only more complex line is this:

count += !~std::to_string(start++).find('5');

However it is also easiy explained. find returns std::npos which is the maximum value size_t can hold (exact value depends on how the compiler defines it) when the character cannot be found. Which essentially means the it is an integer value filled with binary ones. ~ performs a binary not, meaning that the value is 0 when no 5 character could be found and not 0 when it could. Then ! converts it to a bool (0 => false, everything else => true) and itverts it. So now when the 5 could be found the value is false and true if it could not. Then it gets added to the count variable. (true => 1, false => 0).

Try it online!

@Christoph Thanks for giving me the idea to save 3 bytes

BrainStone

Posted 2017-01-20T05:27:49.293

Reputation: 1 501

1std::to_string(start++).find('5')<0; – Christoph – 2017-01-23T09:28:18.627

1@Christoph since size_t (the return type of find) is an unsiged integer the check < 0 is always false since -1 becomes int max. However using bitwise manipulation I managed to work out a short solution. Thanks for giving me the idea for it though! – BrainStone – 2017-01-23T23:54:27.787

Damn you're right! nice that I could help anyway :) – Christoph – 2017-01-24T11:56:52.213

1

Perl 5, 29 bytes

perl -le 'print 0+grep!/5/,shift..shift' 4 17               #prints 12

Kjetil S.

Posted 2017-01-20T05:27:49.293

Reputation: 1 049

Nice answer, welcome to the site! – James – 2017-01-23T18:21:28.497

0

C#, 82 81 bytes

using System.Linq;a=>b=>Enumerable.Range(a,++b-a).Count(n=>(n+"").All(d=>d!=53));

Added as a separate answer as it's logic is different.

TheLethalCoder

Posted 2017-01-20T05:27:49.293

Reputation: 6 930

I think one of those two using System.Linq; should be removed (byte-count is correct, though). ;) – Kevin Cruijssen – 2017-01-20T15:01:56.650

@KevinCruijssen Woops looks like I can't copy and paste! – TheLethalCoder – 2017-01-20T15:03:18.070

0

SimpleTemplate, 63 bytes

This was harder than expected.

Expects each number as a single parameter in the class, outputting the number of element without 5.

{@eachargv as_}{@if"~5~"is not matches_}{@incX}{@/}{@/}{@echoX}

Ungolfed

{@each argv as argument}
    {@if "~5~"is not matches argument}
        {@inc result}
    {@/}
{@/}
{@echo result}

Ismael Miguel

Posted 2017-01-20T05:27:49.293

Reputation: 6 797

If I read this right you are returning the list of numbers in the range, you need to return the count. – TheLethalCoder – 2017-01-20T12:57:49.360

@TheLethalCoder Crap. Ignore this... – Ismael Miguel – 2017-01-20T13:02:03.817

Fixed! (I hope...) – Ismael Miguel – 2017-01-20T13:06:09.577

0

Perl, 35 20+1 bytes

$\+=!/5/ for$_..<>}{

After considerable help from @Dada in the comment below, this turned into a beautiful 20 bytes - plus 1 for the p. I've left my original answer below, for posterity.

for(shift..shift){$z+=!/5/}print$z;

Call from command line as no5s.pl 1 20.

First Perl golf, so hopefully someone can improve it :)

Also using Strawberry Perl on Windows, so I can run no5s.pl 1 20 directly on the command line and it works - might try using perl -e ...

mcmurdo

Posted 2017-01-20T05:27:49.293

Reputation: 71

Nice first Perl golf. shift..pop will save you one 2 bytes. Using the for in statement modifier position ($z+=!/5/ for shift..pop) should save3 more bytes. Using $\ instead of $z should save two bytes (since just print with no argument will print it). Drop the last semi column. And finally, you can combine all of this and take the numbers from stdin instead of @ARGV. It becomes then perl -pe '$\+=!/5/ for$_..<>}{' (with a little trick with -p and }{, see here).

– Dada – 2017-01-20T15:18:56.083

0

Clojure, 73 bytes

(fn[i a](count(for[n(range i(inc a)):when(every? #(not=\5 %)(str n))]n)))

I had to rollback my previous "improvement", as somehow count was dropped from the new version, and it ended up being longer when I fixed it.

Filters the range of numbers; selecting only the numbers where every digit is not a 5.

(defn count-minus-5 [mi ma]
  (count ; Get the length of the resulting list
    ; Comprehension over the range mi(n) to ma(x).
    (for [n (range mi (inc ma))
          ; Only allow the number when every digit isn't a 5.
          :when (every? #(not= \5 %) (str n))]
      n)))

Carcigenicate

Posted 2017-01-20T05:27:49.293

Reputation: 3 295

I think your answer is missing a count, the function "...should return the number of integers within it...". – NikoNyrh – 2017-01-21T12:53:51.347

@NikoNyrh That'd weird. Somehow it got taken out of the golfed version (note the preformed version has it). I'll update it in a bit. – Carcigenicate – 2017-01-21T14:33:13.543

*preformed -> pregolfed – Carcigenicate – 2017-01-21T14:43:41.247

0

QBIC, 33 32 bytes

Saved a byte by reversing the conditional and moving the increment to ELSE

::[a,b|~instr(!c$,@5`)|\d=d+1}?d

Explanation:

::       get a and b from the command line
[a,b|    FOR c = a; c <= b; c++
~instr(  IF indexOf ( instr is a QBasic function that doesn't have a QBIC equivalent)
    !c$  our loop iterator cast to string
    ,@5` a literal 5
)        instr returns 0 if it didn't find '5', which is truthy.
|        THEN --> Don't do anything for values with a '5'
\d=d+1   ELSE count this number into the total
}        Close all constructs (END IF, NEXT c)
?d       Print 'd': the total number of numbers without a '5'

steenbergh

Posted 2017-01-20T05:27:49.293

Reputation: 7 772

0

Perl 6, 21 bytes

+(+*..+*).grep:{!/5/}

Basically equivalent to smls's solution, but I was able to shave off a couple of bytes by expressing the range as (+*..+*) and eliminating the brackets. (The plusses are necessary, otherwise the stars would be interpreted as negative or positive infinity rather than as arguments to the WhateverCode lambda.)

Sean

Posted 2017-01-20T05:27:49.293

Reputation: 4 136

0

Scala, 51 bytes

(a:Int,b:Int)=>a to b map{_+""indexOf "5"}count(0>)

I haven't been able to concisely combine the map and count.

jaxad0127

Posted 2017-01-20T05:27:49.293

Reputation: 281

0

Clojure, 64 bytes

#(count(for[i(range % (inc %2)):when(not(some #{\5}(str i)))]i))

NikoNyrh

Posted 2017-01-20T05:27:49.293

Reputation: 2 361

0

C++ (function), 115

int f(int a,int b){int r=b-a+1,t;while((t=a++)<=b)while(t!=0)if(abs(t)%10==5){r--;break;}else t/=10;std::cout<<r;}

C++ (full), 143

#include<iostream> 
int main(){int a=0,b=4,r=b-a+1,t;while((t=a++)<=b)while(t!=0)if(abs(t)%10==5){r--;break;}else t/=10;std::cout<<r;return 0;}

Ungolfed version:

#include<iostream> 
int main()
{
    int a=0, b=4, r = b-a+1, t;
    while((t = a++) <= b)
        while(t != 0)
            if(abs(t) % 10 == 5)
            {
                r--;
                break;
            }
            else 
                t /= 10;
    std::cout<<r;
    return 0;
}

vedran

Posted 2017-01-20T05:27:49.293

Reputation: 1

0

Java 8, 68 bytes

(a,b)->IntStream.range(a,b+1).map(i->(""+i).contains("5")?0:1).sum()

This is basically just a rewrite of the Java7 solution by @Kevin Cruijssen to Java8. And I hope we don't care about imports here, otherwise it would be longer by 17 bytes due to the package).

Ungolfed:

(a,b)->IntStream.range(a,b+1)
  .map(i->(""+i).contains("5")?0:1)
  .sum()

Test code:

Try it here.

import java.util.function.BiFunction;
import java.util.stream.IntStream;

class M {
  public static void main (String[] args) {
    BiFunction<Integer, Integer, Integer> dontGimme5 = 
      (a,b)->IntStream.range(a,b+1).map(i->(""+i).contains("5")?0:1).sum();
    System.out.println(dontGimme5.apply(1,9));
    System.out.println(dontGimme5.apply(4,17));
    System.out.println(dontGimme5.apply(-50,-59));
  }
}

Output:

8
12
0

Vaskrist

Posted 2017-01-20T05:27:49.293

Reputation: 1

0

C++, 187 bytes

int f(int a,int b){int r=0;for(int i=a;i<=b;i++){r++;for(int j=0;j<floor(log(abs(i)));j++){int k=floor(abs(i)%int(pow(10,j+1))/pow(10,j));if(k==5){r--;break;}}}return r;}

#include <cmath> - 16 bytes

I couldn't think of a purely mathematical way, so I did this.

  1. Loop through a to b
  2. Calculate the length with floor(log(abs(i)))
  3. Get numbers of each digit with floor(abs(i)%int(pow(10, j + 1)) / pow(10,j))
  4. If it is 5, subtract then move to next number

Still, isn't practical for code-golf, but used much math as I could.

Try it online!

Matthew Roh

Posted 2017-01-20T05:27:49.293

Reputation: 5 043

2You can remove all the unnecessary space to save bytes – user41805 – 2017-01-23T09:21:01.943

@KritixiLithos Forgot it. thanks! by the way, do you like how it works? – Matthew Roh – 2017-01-23T09:23:23.723

somewhat around i/pow(10,j)%10 should save a lot of bytes. j<9 should work, too. There's still a lot to golf, keep trying ! – Christoph – 2017-01-24T13:59:03.073

0

TI-Basic, 43 bytes

Since linear regression to string is so costly, let's try a different approach.

DelVar AInput 
For(I,X,Y
1
For(J,1,9
Ans and 5≠int(10fPart(I/10^(J
End
A+Ans→A
End

Old method, 55 bytes

Majority of the program size is converting number to string through linear regression... why wasn't there a built-in for this?

DelVar AInput 
For(I,X,Y
{0,1→L₁
{0,A→L₂
LinReg(ax+b) Y₁
Equ►String(Y₁,Str1
A+not(inString(Str1,"5→A
End

P.S. (For both methods:) Since the last statement evaluated by the program is that seventh line, it will return the value as normal through Ans. Also, Input stores to X and Y similar to Prompt X,Y.

Timtech

Posted 2017-01-20T05:27:49.293

Reputation: 12 038

0

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.

12Me21

Posted 2017-01-20T05:27:49.293

Reputation: 6 110

0

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)

RenderSettings

Posted 2017-01-20T05:27:49.293

Reputation: 620