¡No me des cinco!

38

Pregunta:

Se le darán los enteros iniciales y finales de una secuencia y deberá devolver el número de enteros que no contienen el dígito 5. ¡Se deben incluir los números de inicio y fin!

Ejemplos:

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

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

50,60 → 60 → Resultado 1

-59, -50 → → Resultado 0

El resultado puede contener cinco.

El número inicial siempre será más pequeño que el número final. ¡Ambos números también pueden ser negativos!

Tengo mucha curiosidad por sus soluciones y la forma en que las resuelve. Quizás alguien de ustedes encuentre una solución matemática pura y fácil.

Editar Este es un desafío de código de golf, por lo que gana el código más corto.

Arasuvel
fuente
3
@betseq: Eso está cerca; pero este tiene un rango variable (y no requiere módulo).
Titus
44
Recomendaría el código más corto como criterio ganador y la etiqueta de código de golf (¡ni siquiera vi que no lo era!). Además, probablemente debería poner un caso de prueba que abarque 50 o 500; También tal vez uno que abarque -50, y uno que abarque 0 sería una buena idea.
Jonathan Allan
1
@ JonathanAllan: Actualizaré ejemplos.
Arasuvel
44
Caso de prueba: 50, 59 -> 0.
Zgarb
14
Usted dice: "El número inicial siempre será más pequeño que el número final". pero uno de sus ejemplos (-50, -59) contradice esto directamente
theonlygusti

Respuestas:

21

JavaScript (ES6), 36 33 bytes

Toma entrada con la sintaxis de curry (a)(b).

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

Formateado y comentado

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

Casos de prueba

Arnauld
fuente
(Normalmente prefiero testmás execcuando sólo se necesita un valor lógico.)
Neil
@Neil Eso tiene más sentido. Actualizado.
Arnauld
NB: no pude encontrar ningún consejo sobre la sintaxis de curry ES6, así que escribí uno .
Arnauld
55
@TheLethalCoder b<aestá allí para detener la recursividad después de contar todos los números desde bhasta a, por lo que eliminarla solo causaría una recursión infinita.
ETHproductions
1
@HristiyanDodov La función externa sin nombre toma acomo argumento y devuelve la Ffunción, que a su vez toma bcomo argumento y, como notó, se llama recursivamente para iterar de ba a, incrementando un contador para todos los enteros que no contienen un 5en su decimal representación.
Arnauld
17

Gelatina , 8 7 bytes

-1 byte gracias a Dennis (use el hecho de que la indexación en un número trata ese número como una lista decimal)

rAw€5¬S

TryItOnline!

¿Cómo?

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

* El átomo de valor absoluto Aes necesario ya que un número negativo emitido a una lista decimal tiene entradas negativas, ninguna de las cuales sería nunca un 5(el ejemplo dado contaría los ocho en lugar de dos).

Jonathan Allan
fuente
rAw€5¬SGuarda un byte.
Dennis
@ Dennis gracias! ¿Es precisa mi descripción "trata ese número como una lista decimal"?
Jonathan Allan
2
Más o menos. wlanza un argumento entero a sus dígitos decimales.
Dennis
13

2sable , 6 5 bytes

Salvó un byte gracias a Adnan

Ÿ5¢_O

Pruébalo en línea!

Explicación

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

Nota: Esto funciona debido a un error al ¢hacer que la función se aplique a cada elemento en lugar de contar elementos coincidentes en la lista.

Emigna
fuente
Puede eliminar el `que se comporta igual en las matrices: p.
Adnan
@Adnan: ¡Gracias!
Iba
9

Python2, 59 55 52 51 47 43 42 bytes

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

Una solución recursiva. ¡Gracias a @xnor por motivarme a encontrar una solución utilizando operadores lógicos! Además, gracias a @JonathanAllan y @xnor por guiarme y cortar el byte del 43 al 42!

Otros intentos a 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
fuente
Funcionaria if!`x`.count('5')?
Tito
2
@Titus Python tiene un notoperador que está !en lenguajes tipo C, pero que requiere 3 bytes :(
Yytsi
1
Piense en usar un cortocircuito lógico con andy or.
xnor
1
Sí, bien hecho! Ahora piensa en acortar eso not.
xnor
1
Estás muy cerca! Sigue intentando cosas.
xnor
6

05AB1E , 8 7 6 bytes

Salvó un byte gracias a Adnan

Ÿ5.å_O

Pruébalo en línea!

Explicación

Ÿ         # inclusive range
 5.å      # map 5 in y for each y in the list
    _     # logical negation 
     O    # sum
Emigna
fuente
05AB1E también se ha vectorizado å, que es , por lo que puede hacerlo Ÿ5.å_Opor 6 bytes.
Adnan
negatesignificado -n, o n==0?1:0?
ETHproductions
@ETHproductions: Lo siento, eso no estaba claro. n==0?1:0
Quise
6

Pyth, 9 8 bytes

¡Ahorré un byte gracias a FryAmTheEggman!

lf-\5T}E

Explicación:

        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

Pruébalo en línea!

busukxuan
fuente
5

Perl 6 , 23 bytes

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

Pruébalo en línea!

Cómo funciona

{                     }  # 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
fuente
5

Haskell , 39 bytes

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

Pruébalo en línea! Uso:

Prelude> 4 ! 17
12

Explicación:

             [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
fuente
4

R, 33 bytes

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

Uso:

> 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
fuente
4

Groovy, 47 45 43 40 bytes

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

Este es un cierre sin nombre. findAlles similar a agregar unif condición en una lista de comprensión en python.

Pruébalo en línea!

Gurupad Mamadapur
fuente
4

PHP 7.1, 57 55 bytes

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

Corre con php -r '<code>' <a> <b>

Tito
fuente
¿No es esta sintaxis PHP7.1?
aross
@aross: lo es. Pero PHP 7.1 es anterior a 5 horas ( publicado el 1 de diciembre )
Titus
1
Por supuesto, solo pregunté porque estoy acostumbrado a especificar la versión si es 7 o superior. Esa también es una especie de convención para Python
Aross
1
Convención para PHP, hasta donde he visto, es usar la versión más reciente a menos que se especifique lo contrario.
Titus
No creo que muchas personas tengan la última versión menor. El mínimo común denominador en este momento probablemente sea 5.5. Personalmente estoy usando FC 25 (considerado bastante vanguardista), que actualmente distribuye PHP 7.0. Si estás en Windows, probablemente necesites actualizarlo manualmente.
Aross
4

Mathematica, 46 44 42 bytes

¡Gracias a alephalpha y DavidC por guardar 2 bytes cada uno!

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

Función sin nombre que toma dos argumentos enteros y devuelve un entero. IntegerDigits@Range@##convierte todos los números entre las entradas en listas de dígitos; FreeQ@5prueba esas listas para decidir cuáles no contienen ninguna 5. Luego Booleconvierte los booleanos a ceros y unos, y Trsuma los resultados.

Otras soluciones (44 y 47 bytes):

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

IntegerDigits@x~FreeQ~5determina si la lista de dígitos de un número no tiene 5 segundos y Count[Range@##,x_/;...]&cuenta cuántos números entre las entradas pasan esa prueba.

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

1##&@@IntegerDigits@#-5toma la lista de dígitos de un número, resta 5 de todos ellos y multiplica las respuestas juntas; Sign[...]^2luego convierte todos los números distintos de cero a 1.

Greg Martin
fuente
1
Count[Range@##,x_/;IntegerDigits@x~FreeQ~5]&
DavidC
1
Tr@Boole[FreeQ@5/@IntegerDigits@Range@##]&
alephalpha
3

Ruby, 36 35 bytes

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

Thx IMP1 para -1 byte

GB
fuente
1
¿No devuelve esto la lista sin los números que contienen 5, en lugar del tamaño de esa lista?
IMP1
Tienes razón, he copiado / pegado la versión incorrecta.
GB
1
También puede usar ?5(el '5'carácter) en lugar de /5/ en la búsqueda para guardar un byte.
IMP1
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;}

Sin golf:

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

Código de prueba:

Pruébalo aquí

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

Salida:

8
12
Kevin Cruijssen
fuente
3

PowerShell, 42 41 bytes

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

Llamado desde la línea de comando como. \ No5s.ps1 1 20

mcmurdo
fuente
1
Puede soltar el espacio para guardar un byte. Con los patrones de expresiones regulares estrictamente numéricos, que no es necesario un delimitador (por ejemplo, -replace3o -split1o -notmatch5).
AdmBorkBork
Ah, bien, gracias @AdmBorkBork
mcmurdo
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 gracias a tukkaaX

sagiksp
fuente
¡No te desanimes! Divertirse y desafiarse es lo que importa. Puede eliminar dos espacios en blanco en not "5" in:) Además, si está utilizando Python2, puede rodear xcon `` comillas, en lugar de hacerlo str(x).
Yytsi
@TuukkaX ¡Gracias! También se eliminó el espacio entre in y `x`
sagiksp
Puedes eliminar el []. Tampoco necesitas el espacio antes if.
Dennis
@ Dennis Ya lo intenté, pero se queja de que "el objeto de tipo 'generador' no tiene len ()".
Yytsi
@TuukkaX Derecha. lambda a,b:sum(not"5"in`n`for n in range(a,b+1))funciona sin embargo. tio.run/nexus/…
Dennis
2

Swift 52 bytes

($0...$1).filter { !String($0).contains("5") }.count
Arasuvel
fuente
Como su desafío es un desafío de codegolf, debe incluir su bytecount. Además, en codegolf (al menos aquí), es un requisito que todos los programas puedan estar contendiendo realmente (por ejemplo, el nombre de su función puede ser solo un carácter, su función real probablemente puede reducirse a una sola línea). No sé Swift, es posible que tengas que corregirme en cosas.
clismique
2

Lote, 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%

El bucle manual ahorra algunos bytes porque de todos modos necesito el contador de bucle en una variable.

Neil
fuente
2

PHP, 56 bytes

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

Corre así:

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

Una versión para PHP 7.1 tendría 53 bytes (créditos para Titus):

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

Explicación

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
fuente
Ah, demonios, me olvidé del segundo trimparámetro nuevamente.
Titus
2

CJam "solución matemática pura y fácil", 60

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

Pruébalo en línea

Toma los números en cualquier orden, en una matriz.

Explicación:

Un problema central es calcular f (n) = el número de números que no son 5 de 1 a n (inclusive) para cualquier n positivo. Y la respuesta es: tome los dígitos decimales de n, reemplace todos los dígitos después de los primeros 5 (si los hay) con 9, luego reemplace todos los dígitos 5..9 con 4..8 (decremento), y convierta desde la base 9. Ej. 1752 → 1759 → 1648 → 1 * 9 ^ 3 + 6 * 9 ^ 2 + 4 * 9 + 8 = 1259. Básicamente, cada posición de dígito tiene 9 valores aceptables, y un 5xxxx es equivalente a un 49999 porque no hay más números válidos entre ellos.

Una vez que resolvimos esto, tenemos algunos casos: si los números de entrada (digamos a y b, a <b) son (estrictamente) positivos, entonces el resultado es f (b) -f (a-1). Si son negativos, entonces podemos tomar los valores absolutos, reordenarlos y usar el mismo cálculo. Y si a <= 0 <= b, entonces el resultado es f (-a) + f (b) +1.

El programa primero implementa la función F como se describió anteriormente (pero se aplica a cada número en una matriz), luego lee la entrada, convierte los números al valor absoluto y los reordena, y usa uno de los 2 cálculos anteriores, en función de si * b> 0 inicialmente.

aditsu
fuente
No es "puro" pero es un buen método. aquí, obtén un +1 :)
Matthew Roh
@MatthewRoh gracias, pero ¿qué quieres decir con no puro? Es una solución que realiza cálculos matemáticos bastante directos sobre los números de entrada, sin iterar a través del rango. ¿Qué más estabas esperando?
aditsu
2

Python 2 , 54 bytes

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

Pruébalo en línea!

No es la respuesta más corta de Python. Utiliza el mismo algoritmo pero una forma diferente de implementar con un ciclo while y no es una función lambda.

ElPedro
fuente
Es un programa y no una función, y usa while en lugar de for. ¿Qué no es diferente? OK, todavía está buscando una cadena "5" dentro de la entrada incrementada, de acuerdo. ¿Hay una mejor manera?
ElPedro
Eso es exactamente lo que es y por eso es deferente. Lo siento, tal vez debería haber hecho mi comentario diferente.
ElPedro
Mismo algoritmo, diferente forma de implementación. No hay problema con tus comentarios. ¿Está mejor redactado?
ElPedro
Sí, sí :) Eliminaré estos comentarios para que la sección de comentarios se vea limpia.
Yytsi
1

Java 7, 77 bytes

Esta es una mejora de la respuesta de Kevins , pero dado que aún no tengo la reputación de comentar, esta nueva respuesta tendrá que funcionar.

Entonces lo que hice fue:

  • Reemplace las indexOfdeclaraciones concontains (-1 byte)
  • Mueva la parte incremental del ciclo for a la instrucción condicional (-2 bytes)

bucle for ( 77 bytes ):

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

recursivo ( 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;}

Salida:

8
12

8
12

¡Pruébalo aquí !

Tobias Meister
fuente
¡Bienvenido a PPCG! Bonitos hallazgos en una respuesta ya bastante bien desarrollada. No sé mucho sobre Java, pero ¿no debería (""+a).contains("5")?0:1ser reemplazable por !(""+a).contains("5")?
Christoph
1
@Christoph lamentablemente no, ya que en Java un booleano realmente es solo un booleano. Entonces, una operación ternaria es el único camino a seguir.
Tobias Meister
Hm eso es triste. ¿Qué hay de (""+a).contains("5")||r++?
Christoph
1
@ Christoph que tampoco funcionará, porque no puede tener una expresión booleana por sí sola. He estado tratando de que funcione en otros lugares (como la declaración for-loop) pero no con mucho éxito. Buena idea aunque;)
Tobias Meister
1

C #, 67 bytes

a=>b=>{int c=0;for(;a<=b;)c+=(a+++"").Contains("5")?0:1;return c;};
TheLethalCoder
fuente
Tenía la esperanza de usar for(int c=0;...)pero luego falla al compilar porque el retorno está fuera del alcance dec
TheLethalCoder
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));

Golfó 7 bytes gracias a ETHproductions .

Hristiyan Dodov
fuente
1
Puede usar c+=!/5/.test(s++)para guardar algunos bytes :-)
ETHproductions
¡Muchas gracias! Sin embargo, tuve que eliminar mis campos de golf. Estaba muy orgulloso de ellos. :(
Hristiyan Dodov
Creo que puedes usar curry, es decir, s => e => `
TheLethalCoder
La respuesta principal usa la sintaxis curry. No editaré el mío porque sería casi lo mismo. ¡Gracias por señalar eso, sin embargo!
Hristiyan Dodov
1

MATL , 10 bytes

&:!V53-!As

Pruébalo en línea!

Explicación

        % 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
fuente
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;};

Llamada anónima lambda.

Utiliza n(primer número) y m(último número) como entrada, luego verifica mediante la contención de cadena ( "".Contains("")).

devRicher
fuente
No soy el que votó a favor, pero el módulo 5 no es la solución correcta para el desafío de OP. Debe excluir cualquier cosa que contenga el dígito 5en su número, por lo 10que (lo que su respuesta no contaría) debe contarse.
Kevin Cruijssen
@KevinCruijssen Corregido.
devRicher
Esto no se compila, ya que gdebe inicializarse cuando se indica como se llama, varpor lo que necesita var g="";y puede usar curry, es decirn=>m=>
TheLethalCoder
También esto genera la lista, no el recuento
TheLethalCoder
1
@KevinCruijssen Con sus ediciones, esta es esencialmente mi respuesta ...
TheLethalCoder
1

En realidad , 13 bytes

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

Pruébalo en línea!

Explicación:

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
fuente