Сколько мне нужно написать?


35

Написание чисел - это один из миров программирования Hello, часто цифры 1-10.

Я хочу выписать много номеров! Много, много номеров. Но сколько цифр мне нужно написать?

задача

Учитывая целочисленный ввод, укажите в качестве выходного числа число, которое даст мне количество цифр в строке, содержащей все целые числа в диапазоне от 0 до ввода включительно. Идентификатор отрицания ("-") считается одним символом.

Пример ввода / вывода

Вход: 8
Записано: 0,1,2,3,4,5,6,7,8
Выход: 9

Входные данные: 101
записано: 0,1,2,3 ...., 99,100,101
Выходные данные: 196

Вход: 102
выписан: 0,1,2,3 ...., 100,101,102
Выход: 199

Вход -10
Записано: 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10,
выход: 22

Это . Наименьшее количество байтов побеждает!

Ответы:




11

Рёда , 23 байта

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

Попробуйте онлайн!

Разъяснение:

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


7

Утилиты Bash + OS X (BSD), 24 22 байта

Спасибо @seshoumara за сохранение 2 байта.

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

Тестовые прогоны на 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

Вот версия GNU:

Баш + кореутилс, 40 38 байт

Опять же, 2 байта сохранены благодаря @seshoumara.

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

Попробуйте онлайн!


@tuskiomi Я написал coreutils, когда имел в виду утилиты BSD - я тестировал его в Mac OS X, где он работает и на отрицательных входах (seq там не то же самое, что GNU seq).
Митчелл Спектор

@DigitalTrauma Хорошее решение GNU. Если хотите, отправьте это сами; Я думаю, что это слишком отличается, чтобы считать мой вариант.
Митчелл Спектор


Как насчет использования fold -1|wc -lдля подсчета? Это короче.
Сешумара

6

Python 2, 83 , 78 64 байта

самая короткая версия:

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

эта версия сэкономила 5 байт, благодаря @numbermaniac:

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

Попробуйте онлайн!

этот я придумал сам после этого (то же количество байтов):

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

Попробуйте онлайн!


Вы можете использовать mapна второй линии на 78 байт: print len(''.join(map(str,(range(x+1)if x>0 else range(0,x-1,-1))))). Вы можете сэкономить еще больше, сделав это лямбда.
Numbermaniac

1
@numbermaniac я могу сделать что-то подобное таким образом?
micsthepick

1
@numbermaniac здесь является эквивалентом: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)))))для 71 байта
Фелипе Нарди Батиста

6

Java 7, 74 байта (рекурсивно - включая второй параметр по умолчанию)

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

Пояснение (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 байт (цикл - один параметр)

Если 0по какой-либо причине наличие второго параметра по умолчанию для этого рекурсивного подхода не разрешено, вместо этого можно использовать цикл for, подобный этому:

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

Объяснение (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

Тестовый код:

Попробуй это здесь.

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

Выход:

9   9
196 196
199 199
22  22

1
Мне нравится это решение, :)
Tuskiomi


4

Брахилог , 5 байт

⟦ṡᵐcl

Попробуйте онлайн!

Создает диапазон [0, input], преобразует каждое число в строку, объединяет в одну строку и возвращает длину результата


Я заметил, что у TIO есть аргумент Z; что с этим? Должно ли это быть в счет?
Steenbergh

3
@steenbergh: представление Лео является функцией, а не полной программой. Давать аргументZ интерпретатору Brachylog, он должен добавить соответствующую оболочку, чтобы сделать функцию тестируемой. (Если вы запустите его как полную программу, она не выдаст никакого вывода.) Здесь мы разрешаем отправку программ или функций, так что это не должно учитываться при подсчете байтов, так как на самом деле это не часть отправки.

4

PHP, 59 60 байт

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

Спасибо roberto06 за то, что заметил, что предыдущая версия не работала для отрицательных чисел.

Просто строит массив чисел, помещает его в строку, затем считает цифры (и знак минус)

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

Пример запуска: php -f 112504.php 8


Это не работает для отрицательного ввода, см. Здесь
roberto06

Вы можете сохранить 3 байта, используя joinвместо, implodeпотому что это псевдоним.
Mario

нет необходимости избегать минус -1 байт. С другой стороны, вы можете изменить свое регулярное выражение на[--9]
Jörg Hülsermann

4

Haskell , 39 38 байт

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

Попробуйте онлайн! Редактировать: 1 байт сохранен благодаря @xnor!

Объяснение:

В Haskell для чисел aи b [a..b]находится диапазон от 1 aдо b1 или 1, в зависимости от того b, больше ли a. Так что для позитива nпервый список в [0..n]++[n..0]это, [0,1,2,...,n]а второй пустой. Отрицательно nвторой диапазон дает, [0,-1,-2,...,n]а первый пустой. Однако, если n=0оба диапазона дают список [0], объединение [0,0]может привести к ложному результату 2. Вот почему 0рассматривается как особый случай.

=<<-Оператором в списке так же , как concatMap, так что каждое число преобразуется в строку путем , showи все эти строки соединяются в одну длинную строку из которой lengthнаконец вернулся.


До чаевых xnor я использовал [0,signum n..n]вместо [0..n]++[n..0]. signum nявляется -1для отрицательных чисел, 0для нуля и 1для положительных чисел и диапазон формы [a,b..c]создает список чисел от aдо cс шагом b. Тем самым [0,signum n..n]выстраивает диапазон [0,1,2,...,n]для положительного nи [0,-1,-2,...,n]отрицательного n. Потому что n=0это создаст бесконечный список, [0,0,0,...]поэтому мы должны обрабатывать его 0как особый случай.


Я думаю, что [0..n]++[n..0]следует сделать для [0,signum n..n].
xnor

4

PHP, 41 35 байт

Сохранено 6 байтов благодаря пользователю 59178

Так как ответ was был неверным для отрицательного вклада, я взял на себя задачу найти новое решение:

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

Эта функция:

  • Строит массив из 0до $argv[1](он же ввод)
  • Внушает это с пустым символом (то есть преобразовывает это в строку)
  • Повторяет длину строки

Попробуй это здесь!


Это лучшее решение для меня, иди, почему я подумал, что должен был это сделать preg_match():(
ʰᵈˑ

Ну, я бы не подумал, range()если бы не твое решение, я думаю, что мы даже;)
roberto06

1
Вы можете сохранить 3 байта, используя join()вместо implode(). это псевдоним для того же. php.net/manual/en/function.join.php
user59178

1
И еще 3, опуская параметр «клей».
user59178

Я знал, что существует псевдоним для implode, но я не знал, что могу опустить параметр gue. Благодарность !
roberto06


4

R, 26 20 байт

sum(nchar(0:scan()))

Очень простой подход:

  • Сделать вектор 0: x

  • Подсчитать символы в каждом значении (будет автоматически приведено к строке)

  • сумма

Не уверены, есть ли какие-нибудь хитрости, чтобы сократить определение функции? 6 байт были сохранены благодаря Джузеппе, взяв вместо этого входные данные из стандартного ввода.


Вы могли бы сделать sum(nchar(0:scan()))вместо этого и читать nсо стандартного ввода вместо этого.
Джузеппе

4

Mathematica, 48 47 46 байт

-1 байт благодаря Мартину Эндеру !

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

Анонимная функция, принимающая число в качестве аргумента.

Сокращенное решение от Грега Мартина , 39 байт

1-#~Min~0+Tr@IntegerLength@Range@Abs@#&

1
Вы можете использовать Sign@#для #/Abs@#.
Мартин Эндер

1
Вы можете сохранить несколько байт с несколько иным подходом: 1-#~Min~0+Tr@IntegerLength@Range@Abs@#&. Первоначально 1учитывается цифра 0, а -#~Min~0учитываются все отрицательные знаки, если ввод отрицательный.
Грег Мартин

3

Пакет, 110 байт

@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%

Вычисляет sum(min(0,abs(n)+1-10^k),k=0..9)+(n<0?1-n:1). (Мне нужно только идти 9из-за ограничений целочисленной арифметики Пакета.)


3

Python 2 , 68 байт

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

Попробуйте онлайн!

Дольше, но отличается от других решений Python. Определяет рекурсивную функцию, которая называется, например,f(10)


3

MATL , 11 байт

0hSZ}&:VXzn

Попробуйте онлайн!

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

3

PowerShell , 23 байта

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

Попробуйте онлайн! (будет работать на TIO для очень больших (абсолютных) входов)

Использует ..оператор диапазона для построения диапазона от 0входного $args(приводится как строка для преобразования из входного массива). Он -joinобъединяется в строку (например, 01234), а затем Leберется ngth. Это остается на конвейере и вывод неявный.


Точное решение, которое у меня было в голове, когда я прочитал этот вопрос 😝
Бриантист


3

QBIC , 25 байтов

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

Объяснение:

:[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$

3

JavaScript, 50 байт

Сотрудничал с @ETHproductions

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


3

Сетчатка , 28 байт

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

Попробуйте онлайн!

объяснение

\d+
$*

Преобразуйте число в одинарное, не трогая знак.

1
$`1¶

Каждый 1 заменяется всем до себя плюс новая строка. При этом мы получаем диапазон от 1 до n, если n был положительным, от -1 до n с дополнительным -в начале, если он был отрицательным. Все числа в одинарных и разделены переводами строк.

1+
$.&

Преобразуйте каждую последовательность единиц в соответствующее десятичное число.

^-?
0

Поставь 0в начале, заменив лишнее, -если оно там есть.

.

Подсчитайте количество (не новых) символов.


3

Emacs, 20 байт

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

Сама команда состоит из 20 нажатий клавиш, но мне нужно уточнить, как это следует считать байтами. Я полагал, что подсчет каждого нажатия клавиши как 1 байта был бы наиболее справедливым. Команда выше написана условно для удобства чтения.

объяснение

C-x (

Начните определять макрос клавиатуры.

C-x C-k TAB

Создать новый счетчик макросов. Пишет 0в буфер; значение счетчика теперь равно 1.

C-x )

Конец определения макроса клавиатуры.

M-{input} C-x e

После нажатия META, введите ваш номер ввода. C-x eЗатем выполняет макрос , который во много раз.

C-x h

Установите метку в начало буфера (который выбирает весь текст, сгенерированный таким образом).

M-=

Выполнить подсчет символов в выбранном регионе. Количество символов будет напечатано в минибуфере.

пример

Извиняюсь за ужасную подсветку цвета. Это пример использования этой команды со входом 100. Выход находится в минибуфере внизу экрана.

Пример выполнения с вводом 100


Да, я уверен, что одно нажатие клавиши - один байт.
NoOneIsHere

@NoOneIsHere У меня есть две мысли по этому поводу: 1) Можно ли представить символ Ctrl + одним байтом? И 2) я вижу много ответов, считая символы Unicode как один байт, но это не так, поэтому я подумал, что, возможно, CodeGolf может иметь свое собственное определение «байта»? Спасибо.
чериллиум

Я действительно не знаю. Но вы можете спросить на Meta .
NoOneIsHere

3

Луа, 52 байта

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

Перебирает цикл for с 0 - ввод, преобразует целое число i в строку и добавляет длину строки tперед печатью.t



2

C #, 77 73 байта

-4 байта благодаря @Kevin Cruijssen

Лямбда-функция:

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

Неуправляемый и с тестовыми случаями:

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

Вы можете изменить на, whileчтобы forсохранить пару байтов: (r)=>{var l="";for(int i=0,s=r<0?-1:1;i!=r+s;i+=s)l+=i;return l.Length;};( 73 байта )
Кевин Круйссен

@Kevin Cruijssen Вы правы, спасибо.
Мистер Скапеграс

Вы можете, вероятно, использовать счетчик int и добавить длину внутри цикла, чтобы сохранить несколько байтов. Если вы компилируете в a, Func<int, int>вы можете вызывать такие функции, как r=>...сохранение 2 байта (возможно, это можно сделать в любом случае).
TheLethalCoder


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.