Não me dê cinco!

38

Pergunta:

Você receberá os números inteiros inicial e final de uma sequência e deve retornar o número inteiro que não contém o dígito 5. Os números inicial e final devem ser incluídos!

Exemplos:

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

O resultado pode conter cinco.

O número inicial sempre será menor que o número final. Ambos os números também podem ser negativos!

Estou muito curioso por suas soluções e pela maneira como você as resolve. Talvez alguém encontre uma solução fácil de matemática pura.

Editar Este é um desafio do código-golfe, portanto o código mais curto vence.

Arasuvel
fonte
3
@betseq: Está perto; mas este tem um intervalo variável (e não requer módulo).
Titus
4
Eu recomendaria o código mais curto como critério de vencimento e a tag code-golf (eu nem percebi que não era!). Além disso, você provavelmente deve colocar um caso de teste que abranja 50 ou 500; talvez também um que cubra -50 e outro que cubra 0 seja uma boa idéia.
Jonathan Allan
1
@ JonathanAllan: Vou atualizar exemplos.
Arasuvel
4
Caso de teste: 50, 59 -> 0.
Zgarb
14
Você diz: "O número inicial sempre será menor que o número final". mas um de seus exemplos (-50, -59) contradiz isso diretamente
theonlygusti

Respostas:

21

JavaScript (ES6), 36 33 bytes

Recebe entrada com sintaxe de currying (a)(b).

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

Formatado e 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 teste

Arnauld
fonte
(I normalmente preferem testmais execquando você só precisa de um boolean.)
Neil
@ Neil Isso faz mais sentido mesmo. Atualizada.
Arnauld
NB: Não encontrei nenhuma dica sobre a sintaxe de curry do ES6, então escrevi uma .
precisa saber é o seguinte
5
O @TheLethalCoder b<aestá lá para interromper a recursão depois de contar todos os números de bpara a, portanto, removê-lo causaria uma recursão infinita.
ETHproductions
1
@HristiyanDodov A função externa sem nome recebe acomo argumento e retorna a Ffunção, que por sua vez recebe bcomo argumento e - como você notou - é chamada recursivamente para iterar de bpara a, incrementando um contador para todos os números inteiros que não contenham a 5em decimal representação.
precisa
17

Geléia , 8 7 bytes

-1 byte graças a Dennis (use o fato de que a indexação em um número trata esse número como uma lista decimal)

rAw€5¬S

TryItOnline!

Quão?

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

* O átomo de valor absoluto Aé necessário, pois um número negativo convertido para uma lista decimal possui entradas negativas, nenhuma das quais seria um 5(o exemplo dado contaria todos os oito em vez de dois).

Jonathan Allan
fonte
rAw€5¬Ssalva um byte.
Dennis
@Dennis thanks! Minha descrição "trata esse número como uma lista decimal" é precisa?
Jonathan Allan
2
Bastante. wlança um argumento inteiro para seus dígitos decimais.
Dennis
13

2sable , 6 5 bytes

Guardou um byte graças a Adnan

Ÿ5¢_O

Experimente online!

Explicação

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

Nota: Isso funciona devido a um erro ao ¢fazer a função se aplicar a cada elemento em vez de contar os elementos correspondentes na lista.

Emigna
fonte
Você pode remover o `que se comporta da mesma maneira nas matrizes: p.
Adnan
@ Adnan: Obrigado! Eu estava indo para testar isso, mas esqueci;)
Emigna 20/0117
9

Python2, 59 55 52 51 47 43 42 bytes

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

Uma solução recursiva. Agradeço ao @xnor por me motivar a encontrar uma solução usando operadores lógicos! Além disso, obrigado a @ JonathanAllan e @ xnor por me orientarem e cortarem o byte de 43 para 42!

Outras tentativas em 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
fonte
Funcionaria if!`x`.count('5')?
Titus
2
O @Titus Python possui um notoperador que está !em linguagens do tipo C, mas que leva 3 bytes :(
Yytsi 20/01/17
1
Pense em usar um curto-circuito lógico com ande or.
Xnor
1
Sim, muito bem feito! Agora pense em encurtar isso not.
Xnor
1
Você está realmente perto! Continue tentando coisas.
Xnor
6

Utilitários Bash / Unix, 21 bytes

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

Experimente online!

Mitchell Spector
fonte
6

05AB1E , 8 7 6 bytes

Guardou um byte graças a Adnan

Ÿ5.å_O

Experimente online!

Explicação

Ÿ         # inclusive range
 5.å      # map 5 in y for each y in the list
    _     # logical negation 
     O    # sum
Emigna
fonte
05AB1E também foi vetorizado å, ou seja , é possível fazer isso Ÿ5.å_Opor 6 bytes.
Adnan
negatesignificado -n, ou n==0?1:0?
ETHproductions
@ETHproductions: Desculpe, isso não estava claro. Eu quis dizer negação lógica, entãon==0?1:0
Emigna
6

Pitão, 9 8 bytes

Guardou um byte graças a FryAmTheEggman!

lf-\5T}E

Explicação:

        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

Experimente online!

busukxuan
fonte
5

Perl 6 , 23 bytes

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

Experimente online!

Como 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
fonte
5

Haskell , 39 bytes

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

Experimente online! Uso:

Prelude> 4 ! 17
12

Explicação:

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

Groovy, 47 45 43 40 bytes

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

Este é um fechamento sem nome. findAllé semelhante a adicionar uma ifcondição em uma compreensão de lista em python.

Experimente online!

Gurupad Mamadapur
fonte
4

PHP 7.1, 57 55 bytes

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

Correr com php -r '<code>' <a> <b>

Titus
fonte
Não é esta sintaxe do PHP7.1?
aross
@aross: É. Mas o PHP 7.1 tem mais de 5 horas ( publicado em 1 de dezembro )
Titus
1
é claro, eu apenas perguntei porque estou acostumado a especificar a versão, se é 7 ou superior. Esse também é o tipo de convenção para o Python
cerca de 20/01/17
1
A convenção para PHP - até onde eu vi - é usar a versão mais recente, a menos que seja especificado o contrário.
Titus
Eu não acho que muitas pessoas tenham a última versão menor. O denominador menos comum no momento provavelmente seria 5,5. Pessoalmente, estou usando o FC 25 (considerado de ponta), que atualmente distribui o PHP 7.0. Se você estiver no Windows, provavelmente precisará atualizar manualmente.
aross
4

Mathematica, 46 44 42 bytes

Obrigado a alephalpha e DavidC por economizar 2 bytes cada!

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

Função sem nome, recebendo dois argumentos inteiros e retornando um número inteiro. IntegerDigits@Range@##converte todos os números entre as entradas em listas de dígitos; FreeQ@5testa essas listas para decidir quais não contêm nenhuma 5. Em seguida, Booleconverte booleanos em zeros e uns e Trsoma os resultados.

Outras soluções (44 e 47 bytes):

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

IntegerDigits@x~FreeQ~5determina se a lista de dígitos de um número está livre de 5s e Count[Range@##,x_/;...]&conta quantos números entre as entradas passam no teste.

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

1##&@@IntegerDigits@#-5pega a lista de dígitos de um número, subtrai 5 de todos eles e multiplica as respostas; Sign[...]^2depois converte todos os números diferentes de zero em 1.

Greg Martin
fonte
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
fonte
1
Isso não retorna a lista sem os números que contêm 5, e não o tamanho dessa lista?
IMP1
Você está certo, eu copiei / colei a versão errada.
GB
1
Você também pode usar ?5(o '5'caractere) em vez de /5/ na pesquisa para salvar um 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;}

Ungolfed:

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

Código do teste:

Experimente aqui.

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

Saída:

8
12
Kevin Cruijssen
fonte
3

PowerShell, 42 41 bytes

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

Chamado na linha de comando como. \ No5s.ps1 1 20

mcmurdo
fonte
1
Você pode soltar o espaço para salvar um byte. Com padrões de regex estritamente numéricos, você não precisa de um delimitador (por exemplo, -replace3ou -split1ou -notmatch5).
precisa saber é o seguinte
Ah, bom, obrigado @AdmBorkBork
mcmurdo 20/01
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 graças a tukkaaX

sagiksp
fonte
Não desanime! Divertir-se e desafiar a si mesmo é o que importa. Você pode remover dois espaços em branco em not "5" in:) Além disso, se você estiver usando o Python2, poderá colocar x`` aspas, em vez de fazê-lo str(x).
Yytsi
@TuukkaX Thanks! também removeu o espaço entre in e `x`
sagiksp
Você pode remover o []. Você também não precisa do espaço antes if.
Dennis
@ Dennis Eu tentei isso já, mas reclama que "o objeto do tipo 'gerador' não tem len ()".
Yytsi
@TuukkaX Right. lambda a,b:sum(not"5"in`n`for n in range(a,b+1))funciona embora. tio.run/nexus/…
Dennis
2

Swift 52 bytes

($0...$1).filter { !String($0).contains("5") }.count
Arasuvel
fonte
Como seu desafio é um desafio de codegolf, você deve incluir seu número de bytes. Além disso, no codegolf (pelo menos aqui), é um requisito que todos os programas sejam realmente concorrentes (por exemplo, o nome da sua função pode ser apenas um caractere, sua função real provavelmente pode ser reduzida a uma única linha). Eu não conheço Swift, talvez você precise me corrigir.
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%

O loop manual salva alguns bytes porque, de qualquer maneira, eu preciso do contador de loop em uma variável.

Neil
fonte
2

PHP, 56 bytes

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

Execute assim:

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

Uma versão para PHP 7.1 seria de 53 bytes (créditos para Titus):

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

Explicação

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
fonte
Ah, esqueci o segundo trimparâmetro novamente.
Titus
2

CJam "solução fácil de matemática pura", 60

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

Experimente online

Leva os números em qualquer ordem, em uma matriz.

Explicação:

Um problema central é calcular f (n) = o número de números não-5 de 1 a n (inclusive) para qualquer n positivo. E a resposta é: pegue os dígitos decimais de n, substitua todos os dígitos após os 5 primeiros (se houver) por 9, depois substitua todos os dígitos 5..9 por 4..8 (decremento) e converta da base 9. Por exemplo, 1752 → 1759 → 1648 → 1 * 9 ^ 3 + 6 * 9 ^ 2 + 4 * 9 + 8 = 1259. Basicamente, cada posição de dígito possui 9 valores aceitáveis ​​e um 5xxxx é equivalente a um 49999 porque não há mais números válidos entre eles.

Depois que resolvemos isso, temos alguns casos: se os números de entrada (digamos aeb, a <b) forem (estritamente) positivos, o resultado será f (b) -f (a-1). Se eles são negativos, podemos pegar os valores absolutos, reordená-los e usar o mesmo cálculo. E se a <= 0 <= b, o resultado é f (-a) + f (b) +1.

O programa implementa primeiro a função F conforme descrito acima (mas aplicada a cada número em uma matriz), depois lê a entrada, converte os números no valor absoluto e os reordena e usa um dos 2 cálculos acima, com base em se um * b> 0 inicialmente.

aditsu
fonte
Não é um método "puro", mas agradável. aqui, receba um +1 :)
Matthew Roh 23/01
@MatthewRoh obrigado, mas o que você quer dizer com não é puro? É uma solução que faz cálculos matemáticos bastante diretos nos números de entrada, sem iterar no intervalo. O que mais você estava esperando?
Aditsu 23/01/19
2

Python 2 , 54 bytes

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

Experimente online!

Não é a resposta mais curta do Python Usa o mesmo algoritmo, mas uma maneira diferente de implementar com um loop while e não é uma função lambda.

ElPedro
fonte
É um programa e não uma função e usa while em vez de for. O que não é diferente? OK, ele ainda está procurando uma sequência "5" dentro da entrada incrementada, concordado. Existe uma maneira melhor?
ElPedro
É exatamente o que é e é por isso que é deferente. Desculpe, talvez devesse ter feito meu comentário diferente.
ElPedro
Mesmo algoritmo, maneira diferente de implementar. Não há problema com seus comentários. Isso é melhor redigido?
ElPedro
Sim, sim :) Vou remover esses comentários para deixar a seção de comentários limpa.
Yytsi
1

Java 7, 77 bytes

Esta é uma melhoria da resposta de Kevins , mas como ainda não tenho reputação de comentar, essa nova resposta terá que ser feita.

Então o que eu fiz foi:

  • Substitua as indexOfinstruções porcontains (-1 byte)
  • Mova a parte de incremento do loop for para a instrução condicional (-2 bytes)

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

Saída:

8
12

8
12

Teste aqui !

Tobias Meister
fonte
Bem-vindo ao PPCG! Achados agradáveis ​​em uma resposta já bastante agradável. Eu não sei muito sobre Java, mas não deve (""+a).contains("5")?0:1ser substituído por !(""+a).contains("5")?
Christoph
1
@ Christoph infelizmente não, já que em Java um booleano é realmente apenas um booleano. Portanto, uma operação ternária é o único caminho a percorrer.
Tobias Meister
Hum, isso é triste. Que tal (""+a).contains("5")||r++?
Christoph
1
@Christoph também não funcionará, porque você não pode ter uma expressão booleana sozinha. Eu tenho tentado fazê-lo funcionar em outros lugares (como a declaração de loop for), mas não com muito sucesso. Boa idéia tho;)
Tobias Meister
1

C #, 67 bytes

a=>b=>{int c=0;for(;a<=b;)c+=(a+++"").Contains("5")?0:1;return c;};
TheLethalCoder
fonte
Eu estava esperando para usar for(int c=0;...), mas depois ele não consegue compilar porque o retorno está fora do escopo parac
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));

Golfed 7 bytes graças a ETHproductions .

Hristiyan Dodov
fonte
1
Você pode usar c+=!/5/.test(s++)para salvar alguns bytes :-)
ETHproductions
Muito obrigado! Eu tive que excluir meus tacos, no entanto. Eu estava tão orgulhoso deles. :(
Hristiyan Dodov
Eu acho que você pode usar currying, ou seja, s => e => `
TheLethalCoder 20/17
A resposta principal usa a sintaxe de currying. Não vou editar o meu, porque ele se tornaria quase o mesmo. Obrigado por apontar isso, no entanto!
Hristiyan Dodov
1

MATL , 10 bytes

&:!V53-!As

Experimente online!

Explicação

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

Chamada lambda anônima.

Usa n(primeiro número) e m(último número) como entrada e, em seguida, verifica via contenção de cadeia ( "".Contains("")).

devRicher
fonte
Não sou eu quem votou mal, mas o módulo 5 não é a solução correta para o desafio dado pelo OP. Ele deve excluir qualquer coisa que contenha o dígito 5em seu número, para 10que (a sua resposta não conte) seja contada.
precisa saber é o seguinte
@KevinCruijssen Fixed.
precisa saber é o seguinte
Isso não compilar como gdeve ser inicializado quando indicado como é chamado var, então você precisa var g="";e você pode usar currying ien=>m=>
TheLethalCoder
Além disso, este gera a lista não a contagem
TheLethalCoder
1
@KevinCruijssen Com suas edições este é essencialmente a minha resposta ...
TheLethalCoder
1

Na verdade , 13 bytes

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

Experimente online!

Explicação:

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
fonte