36
\$\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\$
  • 3
    \$\begingroup\$ @betseq: That´s close; but this one has a variable range (and requires no modulo). \$\endgroup\$ – Titus Jan 20 '17 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\$ – Jonathan Allan Jan 20 '17 at 5:45
  • 1
    \$\begingroup\$ @JonathanAllan : I will update examples. \$\endgroup\$ – Arasuvel Jan 20 '17 at 5:51
  • 4
    \$\begingroup\$ Test case: 50, 59 -> 0. \$\endgroup\$ – Zgarb Jan 20 '17 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\$ – theonlygusti Jan 21 '17 at 10:36

51 Answers 51

1
\$\begingroup\$

PowerShell, 37 36 bytes

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

Try it online!

\$\endgroup\$
  • \$\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\$ – AdmBorkBork Jan 20 '17 at 15:09
  • \$\begingroup\$ Doh, how'd I miss that?! Thanks @AdmBorkBork \$\endgroup\$ – briantist Jan 20 '17 at 15:11
1
\$\begingroup\$

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.
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ Redundant whitespace at &&. I think that you can do a^b in each case you check for disequality, such as abs(i%10)!=5. \$\endgroup\$ – Yytsi Jan 20 '17 at 7:20
  • \$\begingroup\$ @TuukkaX I'm gonna have to modify this answer anyways since it would not work for 150, 500 \$\endgroup\$ – Abel Tom Jan 20 '17 at 7:25
  • \$\begingroup\$ Useless whitespace at (f==0) j++. If f can't be negative, you can check whether f<1. \$\endgroup\$ – Yytsi Jan 20 '17 at 13:02
  • \$\begingroup\$ @TuukkaX You're right! Updated! \$\endgroup\$ – Abel Tom Jan 20 '17 at 13:14
  • \$\begingroup\$ You don't need the first if(a<b). OP says "The start number will always be smaller than the end number." \$\endgroup\$ – nmjcman101 Jan 20 '17 at 13:29
1
\$\begingroup\$

Perl 5, 29 bytes

perl -le 'print 0+grep!/5/,shift..shift' 4 17               #prints 12
\$\endgroup\$
  • \$\begingroup\$ Nice answer, welcome to the site! \$\endgroup\$ – DJMcMayhem Jan 23 '17 at 18:21
1
\$\begingroup\$

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

\$\endgroup\$
  • 1
    \$\begingroup\$ std::to_string(start++).find('5')<0; \$\endgroup\$ – Christoph Jan 23 '17 at 9:28
  • 1
    \$\begingroup\$ @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! \$\endgroup\$ – BrainStone Jan 23 '17 at 23:54
  • \$\begingroup\$ Damn you're right! nice that I could help anyway :) \$\endgroup\$ – Christoph Jan 24 '17 at 11:56
1
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Jakob Jan 20 '17 at 17:32
  • \$\begingroup\$ 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 :( \$\endgroup\$ – Golden Ratio Jan 25 '17 at 9:41
1
\$\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\$
  • \$\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 '17 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 '17 at 2:52
0
\$\begingroup\$

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}
\$\endgroup\$
  • \$\begingroup\$ If I read this right you are returning the list of numbers in the range, you need to return the count. \$\endgroup\$ – TheLethalCoder Jan 20 '17 at 12:57
  • \$\begingroup\$ @TheLethalCoder Crap. Ignore this... \$\endgroup\$ – Ismael Miguel Jan 20 '17 at 13:02
  • \$\begingroup\$ Fixed! (I hope...) \$\endgroup\$ – Ismael Miguel Jan 20 '17 at 13:06
0
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ I think one of those two using System.Linq; should be removed (byte-count is correct, though). ;) \$\endgroup\$ – Kevin Cruijssen Jan 20 '17 at 15:01
  • \$\begingroup\$ @KevinCruijssen Woops looks like I can't copy and paste! \$\endgroup\$ – TheLethalCoder Jan 20 '17 at 15:03
0
\$\begingroup\$

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

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

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

\$\endgroup\$
  • \$\begingroup\$ 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). \$\endgroup\$ – Dada Jan 20 '17 at 15:18
0
\$\begingroup\$

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.

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

Clojure, 64 bytes

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

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)))
\$\endgroup\$
  • \$\begingroup\$ I think your answer is missing a count, the function "...should return the number of integers within it...". \$\endgroup\$ – NikoNyrh Jan 21 '17 at 12:53
  • \$\begingroup\$ @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. \$\endgroup\$ – Carcigenicate Jan 21 '17 at 14:33
  • \$\begingroup\$ *preformed -> pregolfed \$\endgroup\$ – Carcigenicate Jan 21 '17 at 14:43
0
\$\begingroup\$

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;
}
\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$
  • 2
    \$\begingroup\$ You can remove all the unnecessary space to save bytes \$\endgroup\$ – Cows quack Jan 23 '17 at 9:21
  • \$\begingroup\$ @KritixiLithos Forgot it. thanks! by the way, do you like how it works? \$\endgroup\$ – Matthew Roh Jan 23 '17 at 9:23
  • 1
    \$\begingroup\$ By moving the int declarations around, you can save some bytes: tio.run/nexus/… \$\endgroup\$ – Cows quack Jan 23 '17 at 9:30
  • \$\begingroup\$ 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 ! \$\endgroup\$ – Christoph Jan 24 '17 at 13:59
0
\$\begingroup\$

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'
\$\endgroup\$
0
\$\begingroup\$

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.

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

SmileBASIC, 52 bytes

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

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

\$\endgroup\$
0
\$\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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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