Author Topic: Можно ли вывести в лог однозначное число в виде двухзначного (2 как 02)?  (Read 5600 times)

0 Members and 1 Guest are viewing this topic.

Grivus74

  • Зашел в гости
  • *
  • Posts: 1
    • View Profile
Здравствуйте! Можно ли вывести в лог однозначное число в виде двухзначного, с нулём впереди, 2 как 02? Переменная от 1 до 20. Несколько в ряд, нарушается рядность по вертикали, т.к. длина цифр не всегда 2 знака. Может быть тут есть возможность сетки в логе. Спасибо за ответ.
« Last Edit: June 04, 2020, 09:30:10 PM by Grivus74 »

4.У.В.@.К

  • Активный участник
  • ***
  • Posts: 117
    • View Profile
Привет!
Возможности "сетки в логе" я что-то не припомню в Clickermann'е. Но это реализуемо в самом коде.
Можно напридумывать своих форматов вывода в лог.

Пара примеров:
Code: (clickermann) [Select]
$var = 2

IF($var < 10) // Если цифра меньше 10,
   $var = STRCONCAT("0", $var) // дописываем перед ней 0
END_IF

LOGWRITE ($var)

HALT

Можно оформить в виде подпрограммы.
Code: (clickermann) [Select]
SUB(Формат_1) // вывести в лог строку из однозначных чисел в виде двузначных
   STRSEPARATE($str, " ", $arr)
   $str = ""
   FOR($n = 0, $n < ARRSIZE($arr))
      IF(STRLEN($arr[$n]) < 2)
         $arr[$n] = STRCONCAT("0", $arr[$n])
      END_IF
      $str = STRCONCAT($str, " ", $arr[$n])
   END_CYC
   LOGWRITE (STRREPLACE($str, " ", ""))
END_SUB
//--------------------------------
$str = "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20" // Строка для вывода в лог

Формат_1() // Вывод в лог строки "$str" в формате "Формат_1"

HALT


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Вот для любого количества разрядов. Здесь "2" - количество разрядов
Code: (clickermann) [Select]
WHILE(STRLEN($t) < 2)
    $t = STRCONCAT("0", $t)
END_CYC


4.У.В.@.К

  • Активный участник
  • ***
  • Posts: 117
    • View Profile
Подобная конструкция с циклом WHILE и STRREPLACE хорошо работает если из строки нужно удалить несколько вхождений подстроки. А здесь непонятно зачем цикл. Он выполнится только один раз. В данном примере - только, если в переменной $t всего один символ. Да и конкатенация будет стремиться завершить цикл.
Если планировалось в цикле перебирать строку по разделителям, находить в ней нужные цифры и добивать их разрядность нулями, то чего-то в скрипте сильно не хватает.
Или я чего-то тупо не понимаю.
« Last Edit: June 05, 2020, 04:54:21 PM by 4.У.В.@.К »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Изначально он был на 6 разрядов. Конструкция просто универсальная. Дана как пример.
« Last Edit: June 05, 2020, 05:10:51 PM by Vint »


4.У.В.@.К

  • Активный участник
  • ***
  • Posts: 117
    • View Profile
Всё, врубился, оценил преимущество.) Конструкция на 6 разрядов добьет нулями до 6 символов любую переменную $t, содержащую изначально менее 6 символов.
Меня сначала смутило, что по длинной строке с разделителями, эту конструкцию саму тащить надо циклом.)) Но это не планировалось.
Спасибо)

4.У.В.@.К

  • Активный участник
  • ***
  • Posts: 117
    • View Profile
Появился еще один вопрос по алгоритмике и синтаксису...

Вот для любого количества разрядов. Здесь "2" - количество разрядов
Code: (clickermann) [Select]
WHILE(STRLEN($t) < 2)
    $t = STRCONCAT("0", $t)
END_CYC

Верно ли, что подобную универсальную конструкцию можно записать в одну строку так, что при этом она будет работать примерно в 6 раз быстрее, но делать то же самое? Если верно, то как?

UPD: Выражение "примерно в 6 раз быстрее", наверно стоит заменить на "не менее, чем в 5 раз быстрее".
« Last Edit: June 07, 2020, 03:05:22 PM by 4.У.В.@.К »

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Появился еще один вопрос по алгоритмике и синтаксису...

Верно ли, что подобную универсальную конструкцию можно записать в одну строку так, что при этом она будет работать примерно в 6 раз быстрее, но делать то же самое? Если верно, то как?

UPD: Выражение "примерно в 6 раз быстрее", наверно стоит заменить на "не менее, чем в 5 раз быстрее".

Можно, наверное. Если задаться целью. Нет предела совершенству.
Вот до 10 разрядов без изменения строки. Так же 6 - дополнение до 6 символов.

Code: (clickermann) [Select]
print(STRCONCAT(STRCUT("0000000000", 1, 6-STRLEN($x)), $x))
В одну строку. По скорости должно быть быстрее за счёт отсутствия цикла, не в 6 раз конечно.
« Last Edit: June 08, 2020, 08:43:47 PM by Vint »


4.У.В.@.К

  • Активный участник
  • ***
  • Posts: 117
    • View Profile
Великолепно! Просто кайф, правда? :D
Вроде мелочь и всего одна строка, а сколько удовольствия.)) Такие небольшие задачки удобно таскать голове и иногда может родиться красивое решение.)

У меня получилось точно так же. Эта конструкция работает уверенно в 5 раз быстрее. Но все равно остается чувство, что можно написать по другому, лучше. Есть же всякие математические фокусы, чтобы добавить к числу несколько нулей. Но я этих формул не знаю. :-\

Вот мой "тестовый стенд" для сравнения скорости этих конструкций.
Code: (clickermann) [Select]
LOGCLEAR

$t = 12345

$time_1 = $_ms

FOR($n = 0, $n < 1000)
   WHILE(STRLEN($t) < 10)
      $t = STRCONCAT("0", $t)
   END_CYC
   UNDEFINE($t)
END_CYC

$x1 = $_ms - $time_1

WAITMS(100)

//--------------------------------

$var = 12345

$time_2 = $_ms

FOR($n = 0, $n < 1000)
   $var = STRCONCAT(STRCUT("0000000000", 1, 10 - STRLEN($var)), $var)
   UNDEFINE($var)
END_CYC

$x2 = $_ms - $time_2

//--------------------------------

LOGWRITE (STRCONCAT($x1, " / ", $x2, " = ", $x1 / $x2))

HALT

В логе:
Code: [Select]
1454 / 260 = 5.59230769231

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Тут ещё какая хрень. Когда часто отвечаешь на форуме, где уровень у всех разный и особенно, если отвечаешь новичку, начинаешь учитывать это в ответе. Можно написать легковесное, понятное решение в котором легко разобраться, как в примере с циклом. Оно и структурировано и вложенность низкая и символов мало. А можно решение на 1-2 мс быстрее, но с 3 вложенными функциями, которые их только отпугнут.
Да и не такой это нагруженный участок, чтоб его оптимизировать.
А число не может храниться с незначащими нулями если это именно тип числовой.
« Last Edit: June 08, 2020, 10:28:41 PM by Vint »


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
На питоне, я бы использовал форматирование строк
если var = 23 так
Code: (javascript) [Select]
print(f'{var:0>6}')
или в старом c-стиле
Code: (javascript) [Select]
print('%06d' % var)
или можно так же, как на кликермэне
Code: (javascript) [Select]
print('0'*(6-len(str(var)))+str(var))


4.У.В.@.К

  • Активный участник
  • ***
  • Posts: 117
    • View Profile
Да я прекрасно понимаю как строятся ответы на вопросы на форуме. И согласен с тем, что нет смысла выкатывать продвинутый код в качестве ответа новичкам, в большинстве случаев. Тем более, что в вопросах обычно не хватает элементарных входных данных. Все шифруются. Темы многократно дублируются...
Но есть же люди, которые ищут красивые решения, пусть даже в синтетических задачах, как на Codewars. Они ради этого и посещают форум, именно для прокачки скилла. По этому, думаю, что надо подталкивать людей к достижению совершенства в коде. Например, можно заинтриговать аудиторию вопросом, на который знаешь новый/нестандартный ответ. Как это попытался сделать я.)) Ответ можно скрыть, например в спойлере (если бы он работал; давно не проверял). И это не совсем "синтетика", а реальная задача, пусть даже редко встречающаяся. Но для этого форума вроде как новая. Или я ошибаюсь.
Сейчас же получается, что интерес с к теме пропадает сразу, как только предложен более менее рабочий код.

Теперь по теме:
Не всё так однозначно со скоростью конструкций. В моем тестовом скрипте ошибка, в двух местах. Но все равно обе конструкции тестируются в равных условиях.
Величина выигрыша в скорости не постоянна. Цикл не любит накручивать много нулей, а однострочной конструкции это кажется "по барабану" (это еще одно её достоинство).


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Такой вопрос был минимум 4 раза на форуме и минимум 6 в группе ВК. Можно поискать по частям фразы 'пароль [перебор] от 0000 до 9999 и нажать T'.

Без цикла, конечно, лучше, т.к. сложность константа O(1)
С циклом сложность линейная O(n)


4.У.В.@.К

  • Активный участник
  • ***
  • Posts: 117
    • View Profile
Такой вопрос был минимум 4 раза на форуме и минимум 6 в группе ВК. Можно поискать по частям фразы 'пароль [перебор] от 0000 до 9999 и нажать T'.

Без цикла, конечно, лучше, т.к. сложность константа O(1)
С циклом сложность линейная O(n)

Действительно, тема не нова, что не удивляет почему-то. И точно такой код был предложен, еще 2012 году, вот в этом сообщении - http://crapware.aidf.org/forum/index.php?topic=9.msg340#msg340
Других подобных тем я не просматривал.
Значит можно было и в этой теме выложить старый проверенный код.
Радует то, что я сам допер до этого решения. Увидел возможность и сделал. И как оказалось - угадал. Было интересно. :)

По поводу оценки сложности алгоритма, я не в курсе. По моему всё просто - более простой алгоритм, для сложной задачи составить труднее, но он будет лучше сложного. А менее производительный код - по определению хуже. Чем меньше разных действий и вычислений в алгоритме, тем он проще. Выше скилл программиста - проще алгоритм и производительней код. А что сверх того, то от лукавого.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile