Quanto eu tenho que escrever?

35

Escrever números está entre os mundos Hello da programação, geralmente os números 1 a 10.

Eu quero escrever muitos números! Muitos, muitos números. Mas quantos números eu tenho que escrever?

Tarefa

Dada uma entrada inteira, forneça um número como saída que me daria o número de dígitos que estariam em uma sequência contendo todos os números inteiros no intervalo de 0 à entrada, inclusive. O identificador de negação ("-") conta como um único caractere.

Exemplo de E / S

Entrada: 8
Escrita: 0,1,2,3,4,5,6,7,8
Saída: 9

Entrada: 101
gravada: 0,1,2,3 ...., 99,100,101
Saída: 196

Entrada: 102
gravada: 0,1,2,3 ...., 100.101.102
saída: 199

Entrada -10
Gravada: 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10
saída: 22

Este é um . O menor número de bytes vence!

tuskiomi
fonte

Respostas:

23

05AB1E , 3 bytes

Código:

ÝJg

Usa a codificação CP-1252 . Experimente online!

Explicação:

Ý     # Range [0 .. input]
 J    # Join into one string
  g   # Get the length of the string
Adnan
fonte
13

Python 2 , 55 46 bytes

lambda n:len(`range(abs(n)+1)`)+2*~n+3*n*(n<0)

Experimente online!

Melhorando.

Jonathan Allan
fonte
11

Röda , 23 bytes

f x{[#([seq(0,x)]&"")]}

Experimente online!

Explicado:

f x{[#([seq(0,x)]&"")]}
f x{                  } /* Defines function f with parameter x. */
        seq(0,x)        /* Creates a stream of numbers from 0 to x. */
       [        ]       /* Creates an array. */
                 &""    /* Joins with "". */
     #(             )   /* Calculates the length of the resulting string. */
    [                ]  /* Returns the value. */
fergusq
fonte
10

Python 2 , 41 bytes

f=lambda n:len(`n`)+(n and f(n+cmp(0,n)))

Experimente online!

Dennis
fonte
+1: Você realmente não pode superar esta solução recursiva inteligentemente feito com Python
micsthepick
7

Utilitários Bash + OS X (BSD), 24 22 bytes

Obrigado a @seshoumara por salvar 2 bytes.

seq 0 $1|fold -1|wc -l

O teste é executado no Mac OS X:

$ for n in 8 101 102 -10 -1 0 1; do printf %6d $n; ./digitcount $n; done
     8       9
   101     196
   102     199
   -10      22
    -1       3
     0       1
     1       2

Aqui está uma versão do GNU:

Bash + coreutils, 40 38 bytes

Mais uma vez, foram salvos 2 bytes graças a @seshoumara.

(seq $1 0;seq 0 $1)|uniq|fold -1|wc -l

Experimente online!

Mitchell Spector
fonte
@tuskiomi Eu escrevi coreutils quando quis dizer utilitários BSD - eu testei no Mac OS X, onde também funciona com entradas negativas (seq não existe o mesmo que GNU seq).
Mitchell Spector
@DigitalTrauma Nice GNU solution. Vá em frente e publique você mesmo, se desejar; Eu acho que é muito diferente para contar como uma variante minha.
Mitchell Spector
Ok, aqui está você :)
Digital Trauma
Que tal usar fold -1|wc -lpara fazer a contagem? É mais curto.
seshoumara
6

Python 2, 83 , 78 64 bytes

versão mais curta:

lambda x:sum(map(len,map(str,(range(0,x+cmp(x,.5),cmp(x,.5))))))

esta versão economizou 5 bytes, graças a @numbermaniac:

x=input()
print len(''.join(map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))

Experimente online!

este que eu criei sozinho depois disso (mesma quantidade de bytes):

x=input()
print sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))

Experimente online!

micsthepick
fonte
Você pode usar mapna segunda linha de 78 bytes: print len(''.join(map(str,(range(x+1)if x>0 else range(0,x-1,-1))))). Você pode economizar ainda mais transformando-o em uma lambda.
numbermaniac
11
@numbermaniac posso fazer algo semelhante desta maneira?
micsthepick
11
@numbermaniac aqui é um equivalente:print sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))
micsthepick
lambda x:sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))para 71 bytes
Felipe Nardi Batista
6

Java 7, 74 bytes (recursivo - incluindo o segundo parâmetro padrão)

int c(int r,int n){r+=(n+"").length();return n>0?c(r,n-1):n<0?c(r,n+1):r;}

Explicação (1):

int c(int r, int n){     // Recursive method with two integer parameters and integer return-type
                         // Parameter `r` is the previous result of this recursive method (starting at 0)
  r += (n+"").length();  //  Append the result with the current number's width
  return n > 0 ?         //  If the input is positive
     c(r, n-1)           //   Continue recursive method with n-1
    : n < 0 ?            //  Else if the input is negative
     c(r, n+1)           //   Continue recursive method with n+1
    ?                    //  Else (input is zero)
     r;                  //   Return the result
}                        // End of method

Java 7, 81 79 bytes (loop - parâmetro único)

Se 0não for permitido ter um segundo parâmetro padrão para essa abordagem recursiva, por algum motivo, um loop for como este pode ser usado:

int d(int n){String r="x";for(int i=n;i!=0;i+=n<0?1:-1)r+=i;return r.length();}

Explicação (2)

int d(int n){                 // Method with integer parameter and integer return-type
  String r = "x";             //  Initial String (with length 1 so we won't have to +1 in the end)
  for(int i=n; i != 0;        //  Loop as long as the current number isn't 0
      i += n < 0 ? 1 : 1)     //   After every iteration of the loop: go to next number
    r += i;                   //   Append String with current number
                              //  End of loop (implicit / single-line body)
  return r.length();          //  Return the length of the String
}                             // End of method

Código do teste:

Experimente aqui.

class M{
  static int c(int r,int n){r+=(n+"").length();return n>0?c(r,n-1):n<0?c(r,n+1):r;}

  static int d(int n){String r="x";for(int i=n;i!=0;i+=n<0?1:-1)r+=i;return r.length();}

  public static void main(String[] a){
    System.out.println(c(0, 8) + "\t" + d(8));
    System.out.println(c(0, 101) + "\t" + d(101));
    System.out.println(c(0, 102) + "\t" + d(102));
    System.out.println(c(0, -10) + "\t" + d(-10));
  }
}

Saída:

9   9
196 196
199 199
22  22
Kevin Cruijssen
fonte
11
Eu gosto desta solução, :)
tuskiomi
4

RProgN 2 , 5 bytes

n0R.L

Explicação

n0R   # A Stack of all numbers between 0 and the input converted to a number.
   .L # The length of the stringification of this.

Solução simples, funciona como um encanto.

Experimente online!

ATaco
fonte
4

Braquilog , 5 bytes

⟦ṡᵐcl

Experimente online!

Cria o intervalo [0, entrada], converte cada número em sequência, concatena em uma única sequência e retorna o comprimento do resultado

Leo
fonte
Notei que o TIO tem uma discussão Z; o que há com isso? Deveria estar na contagem?
steenbergh
3
@steenbergh: A submissão de Leo é uma função, não um programa completo. Dando o argumentoZ ao interpretador Brachylog solicita que ele adicione um wrapper apropriado para tornar a função testável. (Se você o executasse como um programa completo, ele não produziria nenhuma saída.) Permitimos envios de programas ou funções aqui, para que não sejam contabilizados na contagem de bytes, pois na verdade não faz parte do envio.
4

PHP, 59 60 bytes

Outgolfed by Roberto06 - https://codegolf.stackexchange.com/a/112536/38505

Obrigado a roberto06 por perceber que a versão anterior não funcionava para números negativos.

Simplesmente cria uma matriz de números, coloca-a em uma string e conta os dígitos (e o sinal de menos)

<?=preg_match_all("/\-|\d/",implode(",",range(0,$argv[1])));

Execute o exemplo: php -f 112504.php 8

ʰᵈˑ
fonte
Isso não funciona para uma entrada negativa, veja aqui
roberto06 10/17/17
Você pode salvar 3 bytes usando em joinvez de implodeporque é um alias.
Mario
não há necessidade de escapar do -1 byte negativo. Por outro lado, você pode alterar seu regex para[--9]
Jörg Hülsermann 11/11
4

Haskell , 39 38 bytes

f 0=1
f n=length$show=<<[0..n]++[n..0]

Experimente online! Editar: salvou 1 byte graças a @xnor!

Explicação:

Em Haskell para números ae b [a..b]é o intervalo de aaté b1 em incrementos ou 1 em decréscimos, dependendo se bé maior a. Portanto, para um positivo, na primeira lista [0..n]++[n..0]é [0,1,2,...,n]e a segunda está vazia. Para negativo, no segundo intervalo cede [0,-1,-2,...,n]e o primeiro está vazio. No entanto, se os n=0dois intervalos produzirem a lista [0], a concatenação [0,0]levaria a um resultado falso de 2. É por isso0 é tratado como um caso especial.

O =<<operador-em uma lista é o mesmo que concatMap, portanto, cada número é convertido em uma cadeia de caracteres por showe todas essas cadeias são concatenadas em uma cadeia longa, da qual ela lengthfinalmente é retornada.


Antes da dica do xnor, usei em [0,signum n..n]vez de [0..n]++[n..0]. signum né -1para números negativos, 0para zero e 1para números positivos, e um intervalo do formulário [a,b..c]cria a lista de números de apara ccom incremento b. Assim, [0,signum n..n]cria o intervalo [0,1,2,...,n]para positivo ne [0,-1,-2,...,n]negativo n. Pois n=0criaria a lista infinita, por [0,0,0,...]isso também precisamos lidar 0com um caso especial.

Laikoni
fonte
Eu acho que [0..n]++[n..0]deveria fazer por [0,signum n..n].
Xnor
4

PHP, 41 35 bytes

Guardado 6 bytes graças a user59178

Como a resposta de was estava errada para uma entrada negativa, decidi criar uma nova solução:

<?=strlen(join(range(0,$argv[1])));

Esta função:

  • Cria uma matriz de 0para $argv[1](também conhecida como entrada)
  • Implica-o com um caractere vazio (ou seja, transforma-o em uma string)
  • Repete o comprimento da string

Experimente aqui!

roberto06
fonte
Esta é uma solução mais agradável para o meu, idk porque eu pensei que eu tinha que fazer isso preg_match():(
ʰᵈˑ
Bem, eu não teria pensado range()se não fosse para a sua solução, eu acho que estamos quites;)
Roberto06
11
você pode salvar 3 bytes usando em join()vez de implode(). é um apelido para a mesma coisa. php.net/manual/en/function.join.php
01/17
11
E mais 3 omitindo o parâmetro 'cola'.
user59178
Eu sabia que havia um apelido para implode, mas não sabia que poderia omitir o parâmetro gue. Obrigado !
22417 robert06
4

Ruby , 20 26 29 bytes

->x{[*x..-1,0,*1..x]*''=~/$/}

Experimente online!

GB
fonte
Por que o aumento?
Brian Minton
A primeira versão não funcionou para números negativos, a segunda versão teve um problema com zero como entrada.
GB
4

R, 26 20 bytes

sum(nchar(0:scan()))

Abordagem muito básica:

  • Faça um vetor 0: x

  • Contar os caracteres em cada valor (será coagido a uma sequência automaticamente)

  • Soma

Não sabe se existem truques para reduzir a definição de função? 6 bytes salvos graças a Giuseppe, recebendo a entrada de stdin.

user2390246
fonte
você poderia fazer sum(nchar(0:scan()))e ler a npartir de stdin.
Giuseppe
4

Mathematica, 48 47 46 bytes

-1 byte graças a Martin Ender !

StringLength[""<>ToString/@Range[0,#,Sign@#]]&

Função anônima, tomando o número como argumento.

Solução mais curta de Greg Martin , 39 bytes

1-#~Min~0+Tr@IntegerLength@Range@Abs@#&
numbermaniac
fonte
11
Você pode usar Sign@#para #/Abs@#.
Martin Ender
11
Você pode economizar alguns bytes com uma abordagem um pouco diferente: 1-#~Min~0+Tr@IntegerLength@Range@Abs@#&. A inicial é 1responsável pelo dígito 0, enquanto -#~Min~0a todos os sinais negativos, se a entrada for negativa.
Greg Martin
3

Lote, 110 bytes

@set/a"n=%1,t=n>>31,n*=t|1,t=1-t*n,i=0
@for /l %%i in (0,1,9)do @set/a"t+=(i-n)*(i-n>>31),i=i*10+9
@echo %t%

Computa sum(min(0,abs(n)+1-10^k),k=0..9)+(n<0?1-n:1). (Eu só tenho que ir 9devido às limitações da aritmética de número inteiro do lote).

Neil
fonte
3

Python 2 , 68 bytes

def f(i,j=1):
 if i==0:print j
 else:j+=len(`i`);f((i-1,i+1)[i<0],j)

Experimente online!

Mais do que mas diferente de outras soluções Python. Define uma função recursiva chamada como por exemplof(10)

ElPedro
fonte
3

MATL , 11 bytes

0hSZ}&:VXzn

Experimente online!

0h           % Implicitly input n. Append a 0: gives array [n 0]
  S          % Sort
   Z}        % Split array: pushes 0, n or n, 0 according to the previous sorting
     &:      % Binary range: from 0 to n or from n to 0
       V     % Convert to string. Inserts spaces between numbers
        Xz   % Remove spaces
          n  % Length of string. Implicit display
Luis Mendo
fonte
3

PowerShell , 23 bytes

-join(0.."$args")|% Le*

Experimente online! (vomitará no TIO para entradas muito grandes (absolutas))

Usa o ..operador range para construir um intervalo 0para a entrada $args(convertido como uma string para converter a partir da matriz de entrada). Isso é -joineditado em uma sequência (por exemplo, 01234) e, em seguida, o Lenúmero é deduzido. Isso é deixado no pipeline e a saída está implícita.

AdmBorkBork
fonte
A solução exata que eu tinha na minha cabeça quando eu li esta pergunta 😝
briantist
3

Perl 6 , 18 bytes

{chars [~] 0...$_}

Tente

Expandido:

{  # bare block lambda with implicit parameter 「$_」

  chars        # how many characters (digits + '-')
    [~]        # reduce using string concatenation operator &infix:<~>
      0 ... $_ # deductive sequence from 0 to the input
}
Brad Gilbert b2gills
fonte
3

QBIC , 25 bytes

:[0,a,sgn(a)|A=A+!b$]?_lA

Explicação:

:[0,a     Read 'a' from the cmd line, start a FOR loop from 0 to 'a'
,sgn(a)|  with incrementer set to -1 for negative ranges and 1 for positive ones
A=A+!b$   Add a string cast of each iteration (var 'b') to A$
]         NEXT
?_lA      Print the length of A$
steenbergh
fonte
3

JavaScript, 50 bytes

Colaborou com @ETHproductions

n=>{for(t="";n;n<0?n++:n--)t+=n;alert(++t.length)}
Oliver
fonte
3

Retina , 28 bytes

\d+
$*
1
$`1¶
1+
$.&
^-?
0
.

Experimente online!

Explicação

\d+
$*

Converta o número em unário, mantendo o sinal intocado.

1
$`1¶

Cada 1 é substituído por tudo, além de uma nova linha. Com isso, obtemos um intervalo de 1 a n se n for positivo, de -1 a n com um adicional -no início se for negativo. Todos os números são unários e separados por novas linhas.

1+
$.&

Converta cada sequência de unidades para o número decimal correspondente.

^-?
0

Coloque um 0no início, substituindo o extra, -se estiver lá.

.

Conte o número de caracteres (que não são de nova linha).

Leo
fonte
3

Emacs, 20 bytes

C-x ( C-x C-k TAB C-x ) M-{input} C-x e C-x h M-=

O comando em si é de 20 pressionamentos de tecla, mas preciso esclarecer como isso deve ser contado como bytes. Eu raciocinei que contar cada pressionamento de tecla como 1 byte seria o mais justo. O comando acima é escrito convencionalmente para facilitar a leitura.

Explicação

C-x (

Comece a definir uma macro do teclado.

C-x C-k TAB

Crie um novo contador de macro. Grava 0no buffer; o valor do contador é agora 1.

C-x )

Finalize a definição da macro do teclado.

M-{input} C-x e

Depois de pressionar META, digite seu número de entrada. O C-x eentão executa a macro tantas vezes.

C-x h

Defina a marca para o início do buffer (que seleciona todo o texto gerado).

M-=

Execute a contagem de caracteres na região selecionada. O número de caracteres será impresso no minibuffer.

Exemplo

Desculpas pela terrível cor de destaque. Este é um exemplo de uso deste comando com a entrada 100. A saída está no minibuffer na parte inferior da tela.

Exemplo de execução com entrada de 100

Cheryllium
fonte
Sim, tenho certeza de que um pressionamento de tecla é um byte.
NoOneIsHere 14/03/19
@NoOneIsHere Há duas idéias que tive sobre isso: 1) O caractere Ctrl + pode ser representado como um único byte? E 2) Vejo muitas respostas aqui contando caracteres Unicode como um byte, mas não são, então pensei que talvez o CodeGolf talvez tenha sua própria definição de "byte"? Obrigado.
cheryllium 14/03
Eu realmente não sei. Mas você pode perguntar no Meta .
NoOneIsHere 14/03
3

Lua, 52 bytes

t=0;for i=0,io.read()do t=t+#tostring(i)end;print(t)

Repete um loop for da entrada 0, converte o número inteiro iem uma string e adiciona o comprimento da string tantes de imprimirt

Josh
fonte
2

C #, 77 73 bytes

-4 bytes graças a @Kevin Cruijssen

Função Lambda:

(r)=>{var l="";for(int i=0,s=r<0?-1:1;i!=r+s;i+=s)l+=i;return l.Length;};

Ungolfed e com casos de teste:

class P
{
    delegate int numbers(int e);
    static void Main()
    {
        numbers n = (r) =>
        {
            var l = ""; 
            for (int i = 0, s = r < 0 ? -1 : 1; i != r + s; i += s)
                l += i; 
            return l.Length;
        };
        System.Console.WriteLine(n(8));
        System.Console.WriteLine(n(101));
        System.Console.WriteLine(n(102));
        System.Console.WriteLine(n(-10));
        System.Console.ReadKey();
    }
}
Scapegrace
fonte
Você pode mudar o whileque forpara salvar um par de bytes: (r)=>{var l="";for(int i=0,s=r<0?-1:1;i!=r+s;i+=s)l+=i;return l.Length;};( 73 bytes )
Kevin Cruijssen
@Kevin Cruijssen Você está certo, obrigado.
Scapegrace
Você provavelmente pode usar um contador int e adicionar o comprimento dentro do loop para salvar alguns bytes. Se você compilar com a, Func<int, int>poderá chamar as funções como r=>...salvar 2 bytes (provavelmente pode fazer isso de qualquer maneira).
TheLethalCoder
2

JavaScript, 44 bytes

f=(n,i=1)=>n<0?f(-n)-n:n<i?1:n+1-i+f(n,i*10)
<input type=number oninput=o.textContent=f(+this.value)><pre id=o>

Neil
fonte
2

REXX, 56 bytes

arg n
l=0
do i=0 to n by sign(n)
  l=l+length(i)
  end
say l
idrougge
fonte