Найдите и поверните

30

Задание

Это простой вызов. Ваш ввод представляет собой одну непустую строку, содержащую только цифры 0123456789и хэши #. Он будет содержать ровно одну последовательность цифр, которая кодирует неотрицательное целое число и может обернуть конец строки, и хотя бы одну #. Целое число может иметь начальные нули. Так , например, ##44##, 013####и 23###1являются действительными входы, в то время как ###, 0099и #4#4нет.

Ваша задача - извлечь целое число nиз строки и вывести строку с повернутыми nшагами вправо.

Примеры

  • Вход #1##должен быть повернут на 1 шаг вправо, поэтому правильный вывод ##1#.
  • Вход #026###должен быть повернут на 26 шагов вправо, так как начальный 0 игнорируется. Правильный вывод есть 26####0.
  • Вход 1####2 содержит целое число 21, завернутое в конец, поэтому его следует повернуть на 21 шаг вправо. Правильный вывод есть ##21##.

Правила и оценки

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

Вы можете предположить, что число nсоответствует стандартному intтипу вашего языка. И наоборот, если этот стандартный intтип реализует целые числа произвольной точности, вы должны поддерживать (теоретически) сколь угодно большойn .

Контрольные примеры

#1## -> ##1#
##4## -> #4###
1####1 -> ####11
1####2 -> ##21##
#026### -> 26####0
#000### -> #000###
###82399 -> ##82399#
51379#97 -> #9751379
#98##### -> ###98###
#######4## -> #4########
60752#1183 -> 8360752#11
####99366800## -> 366800######99
########9##### -> ###9##########
91#####515694837 -> 1#####5156948379
###6114558###### -> #6114558########
######219088736090042#### -> 9088736090042##########21
#46055080150577874656291186550000138168########### -> 0138168############4605508015057787465629118655000
568375993099127531613012513406622393034741346840434468680494753262730615610086255892915828812820699971764142551702608639695081452206500085233149468399533981039485419872101852######################3680 -> 99533981039485419872101852######################36805683759930991275316130125134066223930347413468404344686804947532627306156100862558929158288128206999717641425517026086396950814522065000852331494683
Zgarb
источник
7
Должны ли мы поддерживать все тесты? Некоторые из этих чисел довольно большие ... Будет ли приемлемым использование языка с 8-битными целыми числами?
Деннис
@Dennis Можно решить проблему с помощью модульной арифметики без фактической загрузки целого числа в память ... но вы правы, это хлопотно во многих языках. Допустим, вам нужно обрабатывать только те тестовые случаи, которые nсоответствуют intтипу вашего языка (который может иметь произвольную точность). Я обновлю текст запроса позже.
Згарб
Что мы должны делать, если input = 1234?
CalculatorFeline
2
@CatsAreFluffy "и хотя бы один #"
FryAmTheEggman

Ответы:

10

CJam, 11 байт

q_'#%W%sim>

Попробуйте онлайн! или проверьте все контрольные примеры .

Обратите внимание, что это не сработает для двух последних тестовых случаев, так как задействованные числа не вписываются в 64 бит.

Как это работает

q_          e# Read all input and push it twice.
  '#%       e# Split at runs of '#'.
     W%     e# Reverse the resulting array.
       si   e# Cast to string, then to int.
         m> e# Rotate the original input that many places to the right.
Деннис
источник
Оооо ... так просто!
Луис Мендо
7

Юлия, 71 65 байт

s->join(circshift([s...],maximum(parse,split(s*s,"#",keep=1<0))))

Это анонимная функция, которая принимает строку и возвращает строку. Чтобы вызвать его, назначьте его переменной.

Мы добавляем входные данные к себе, разделяем их на массив с #разделителем, анализируем каждое целое число и берем максимум. Это определяет количество раз, когда мы сдвигаем строку вправо. Мы разбиваем строку на Charмассив, сдвигаем и joinвозвращаем вместе.

Алекс А.
источник
7

Python, 66 байт

lambda l:(2*l)[-int(''.join(l.split('#')[::-1]))%len(l):][:len(l)]
Линн
источник
5

Сетчатка, 65 57 49

(\ Д *) # * (\ d +)
$ 2 $ 1 $ 0
^ \ D +
$ *
+ `1 (. *) (.)
 $ 2 $ 1
<Пробел>

Сохранено 8 байтов благодаря Мартину!

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

Обратите внимание, что это приведет к истечению времени ожидания / нехватке памяти для очень больших тестовых примеров в Интернете и на большинстве нормальных компьютеров для некоторых из более крупных.

Это берет последний номер в строке и первый или нулевой номер в строке и помещает их перед строкой. Затем он преобразует это объединенное число в одинарное и многократно вращается, выпуская одинарную цифру.

FryAmTheEggman
источник
3

Желе, 12 10 байт

ẋ2~ṣ0‘ḌṂṙ@

Попробуйте онлайн! или проверьте все контрольные примеры .

Задний план

Скажите, что вход 51379#97.

Повторяя строку дважды ( 51379#9751379#97), мы можем убедиться, что она будет содержать непрерывное представление числа.

Далее мы применяем побитовое НЕ ко всем символам. Это попытается привести к int, поэтому '1' оценивается как 1 , а затем отображается на ~ 1 = -2 . При сбое ( #) возвращается 0 .

Для нашего примера это дает

[-6, -2, -4, -8, -10, 0, -10, -8, -6, -2, -4, -8, -10, 0, -10, -8]

Затем мы разделяем нули, чтобы отделить часть, которая кодирует число от остальных.

[[-6, -2, -4, -8, -10], [-10, -8, -6, -2, -4, -8, -10], [-10, -8]]

Побитовое НЕ отображает n в -n - 1 , поэтому мы увеличиваем каждый для получения -n .

[[-5, -1, -3, -7, -9], [-9, -7, -5, -1, -3, -7, -9], [-9, -7]]

Далее мы конвертируем каждый список из базы 10 в целое число.

[-51379, -9751379, -97]

Наименьшее число является отрицательным значением того, которое мы ищем. Поскольку атом вращения списка желе вращается влево , это позволяет избежать умножения на -1 для поворота вправо.

Как это работает

ẋ2~ṣ0‘ḌṂṙ@  Main link. Input: S (string)

ẋ2          Repeat the string twice.
  ~         Apply bitwise NOT to all characters.
            This maps 'n' to ~n = -(n+1) and '# to 0.
   ṣ0       Split at occurrences of zeroes.
     ‘      Increment all single-digit numbers.
      Ḍ     Convert each list from base 10 to integer.
       Ṃ    Take the minimum.
        ṙ@  Rotate S that many places to the left.
Деннис
источник
3

MATL , 28 25 17 16 байт

!G1Y4XXPZcXvUYS!

На 8 байт меньше, заимствуя идею Денниса о разбиении массива и изменении порядка частей

Два последних теста не работают, потому что число слишком велико.

РЕДАКТИРОВАТЬ (20 мая 2016 г.) Код в ссылке используется Xzвместо Xv, в связи с недавними изменениями в языке.

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

!         % take implicit input: string. Transpose into column char array
G         % push input string again
1Y4       % predefined literal '\d' (for regexp)
XX        % match regexp. Gives cell array with 1 or 2 strings
P         % flip that array
ZcXv      % join the strings in that array, without spaces
U         % convert to number
YS        % rotate the transposed input that many times
!         % put back into row form (string). Implicitly display
Луис Мендо
источник
2

PowerShell, 153 байта

(Но см. Раздел «Дополнительные кредиты» ниже)

param($a)$d=[System.collections.arraylist][char[]]$a;for($b=+("$a$a"-split"#"-ne'')[1];$b;$b--){$r=$d[-1];$d.removeAt($d.Count-1);$d.insert(0,$r)}-join$d

В PowerShell нет концепции «сдвига» массива, поэтому мне пришлось развернуть собственное решение. Для больших чисел потребуется много времени, но в конечном итоге он должен завершить все, что уместится в 32-битном int.

Принимает ввод $aи устанавливает новую переменную $dкак [System.Collections.ArrayList] . Это сделано потому, что с технической точки зрения массивы в PowerShell являются неизменяемыми (более подробное объяснение приведено ниже в разделе «Дополнительные кредиты») и, следовательно, не поддерживают произвольные вставки или удаления, которые необходимы для сдвига. Затем мы входим в forцикл.

Начальное условие - хитрость, которую я нашел - если мы объединяем входные данные, разделяем их #и игнорируем пустые значения, второй элемент полученного массива будет равен нашему числу независимо от переноса. Мы устанавливаем это значение $bи уменьшаем $bкаждый раз, пока оно не станет равным нулю.

На каждой итерации мы устанавливаем хелпер $rв качестве последнего элемента в массиве, удаляем этот последний элемент, а затем вставляем элемент вперед ... эффективно "сдвигая" массив вправо на один элемент.

Наконец, мы просто выводим с -join$d таким образом, что он объединяется в одну строку.


Дополнительный кредит

Если проблема заключалась в смещении массива влево, а не вправо , мы можем сделать это значительно короче, используя множественное присваивание . По сути, «если значение присваивания содержит больше элементов, чем переменных, все остальные значения присваиваются последней переменной».

По сути, это означает что-то вроде $c=@(1,2,3)и $a,$b=$c
будет иметь $a=1int и $b=@(2,3)массив.

PowerShell, 90 байт, выполняет сдвиг влево вместо сдвига вправо

param($a)$b=+("$a$a"-split"#"-ne'')[1];$a=[char[]]$a;for(;$b;$b--){$r,$a=$a;$a+=$r}-join$a

Здесь мы снова принимаем данные и устанавливаем, $bкак указано выше. Мы повторно приводим $aкак массив символов, а затем вводим тот же forцикл, что и выше. Однако в этот раз нам не нужно было поддерживать произвольное удаление / вставку, поэтому нам не нужно использовать дорогостоящий [System.Collections.ArrayList]объект или дорогостоящие вызовы методов. Вместо этого мы просто устанавливаем $rбыть первым элементом $a, а остальные элементы повторно сохраняются в $a. Тогда мы +=вернемся к концу.

(Как я уже сказал, массивы PowerShell являются технически неизменными, но +=оператор здесь перегружен - он принимает массив и другой объект, объединяет их (технический термин) в новый массив, возвращает его, сохраняет его как имя переменной и уничтожает исходный массив. Функционально мы только что добавили элемент в конец массива, но технически (и с точки зрения очистки памяти / мусора и т. д.) это совершенно новый массив. Это, очевидно, может стать дорогостоящей операцией если массив большой или сложный. Обратная сторона в том, что, поскольку массивы неизменны, индексирование в них или итерации по ним очень дешевы.)

Выход остается тем же действием, с -joinоператором, чтобы превратить его в одну строку.

AdmBorkBork
источник
1

Серьезно, 21 байт

,;;+'#@s`≈`MM@#@`/`nΣ

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

Предупреждение: это решение очень неэффективно, поэтому для больших тестовых случаев тайм-аут на TIO истекает. Используйте местного переводчика.

Объяснение:

,;;+'#@s`≈`MM@#@`/`nΣ
,;;+                   make 3 copies of input, and concatenate two of them
    '#@s               split on #s
        `≈`MM          convert strings to ints, take maximum
             @#@       explode final copy of input
                `/`n   rotate to the right n times
                    Σ  join
Mego
источник
Согласитесь и возьмите максимум: отличная идея!
Луис Мендо
@LuisMendo Я был удивлен, увидев ответ Алекса с той же стратегией, пока я писал здесь объяснение.
Mego
Похоже, единственным, кто изначально использовал наивный подход, был я :-) (вращение исходной строки, пока все цифры не были смежными)
Луис Мендо
1

Mathematica, 69 байт

#~StringRotateRight~ToExpression[""<>Reverse@TextCases[#,"Number"]]&

Найти последовательности чисел в, если есть 2, то их порядок должен быть обратным. Объединить строки (если он только один, он просто возвращает строку чисел). Преобразуйте строку в числовое и поверните строку столько раз.

IPoiler
источник
FromDigitsработает вместо ToExpression.
CalculatorFeline
1

Pyth, 22 14 байтов

.>zs-.<zxz\#\#

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

объяснение

.> zs -. <zxz \ # \ # # z = input

     . <z # повернуть z влево на
        xz \ # # индекс первого вхождения хэша
                  # это гарантирует, что целое число не обернуто вокруг конца
    - \ # # фильтр все хэши
   s # приведение к целому числу, также удаляет ведущие нули
.> z # сделать окончательный поворот входной строки и распечатать ее

Это работает для всех тестовых случаев, а также почти всегда заканчивается для очень больших чисел.

Denker
источник
Вы можете сделать -...\#вместо h:..."\d+"1. Кроме того, нет необходимости преобразовывать zв список символов, .>работает также на строку.
Якуб
@Jakube Спасибо за подсказку, очень устал, когда я это сделал. ^^
Денкер
1

JavaScript (ES6) 66

На этот раз %полезен тупой минус javascript для отрицательных чисел

z=>(z+z).substr(-(l=z.length,[a,b]=z.match(/\d+/g),b?b+a:a)%l-l,l)
edc65
источник
1
@WashingtonGuedes нет, сумма в b+aпредставляет собой конкатенацию строк. a='32',b='1', (b?b+a:a)=='132', (b|0+a)==33
edc65
1

JavaScript (ES6), 67 64 байта

s=>(l=s.length,s+s).substr(l-s.split(/#+/).reverse().join``%l,l)

Еще один порт CJam ответа Денниса.

Редактировать: Сохранение 3 байтов путем присвоения части ответа edc65, на которую он не обратил внимания.

Нил
источник
Используя троичную сумму и сумму вместо reverse ().
Join
@ Downgoat Извините, в последнее время я получил их в основном правильно, но я сделал это поздно ночью, и поэтому я не думал прямо.
Нил
@ edc65 Нет, это повысило мою оценку. Поэтому я скопировал s+sтрюк вместо этого. (Я действительно думал об этом прошлой ночью, но я был слишком устал, чтобы попробовать это в то время.)
Нил
1

Perl 5, 41 байт

39 байтов плюс два для -lFфлагов ( -M5.01бесплатно):perl -lF -M5.01 script.pl

/#+/;map{unshift@F,pop@F}1..$'.$`;say@F

Объяснение:

  • -lF читает входные данные, удаляет завершающий символ новой строки, помещает остаток в строку $_ символ , разбивает его на символы и помещает этот раздел в массив @F.
  • /#+/находит первую строку #s в$_ и устанавливает $`равным материалу перед ним и $'равным материалу после него. Если $`пусто, то $'может содержать больше# s. Тем не менее, $'.$`это строка, чья начальная подстрока является числом поворотов массива.
  • Теперь мы строим список 1..$'.$`, который обрабатывается $'.$`как целое число и, таким образом, нумерует его, что удаляет любой окончательный# s, поэтому список составляет от 1количества массива.
  • Для каждого элемента в этом списке мы вращаем массив ( popпоследний элемент и unshiftего начало).
  • Тогда sayвсе элементы повернуты массивом.
msh210
источник
1

Рубин - 68 72 70 байт

s=ARGV[0]
p s.split(//).rotate(-(s+s).scan(/\d+/).map(&:to_i).max)*""
  • split преобразует строку в массив
  • (s+s).scan(/\d+/) объединить строку с собой и получить массив чисел (в виде строк)
  • map(&:to_i) конвертировать строки в целые
  • max выбрать самый большой int
  • rotate max раз
  • *""преобразовать массив обратно в строку (сокращение от join)

Использование : ruby scriptname.rb "[string]"

FuzzyTree
источник
я здесь новенький. каков порядок размещения нескольких ответов на разных языках? Я добавил отдельный ответ на тот случай, если один ошибся. если не удастся добавить несколько ответов, дайте мне знать, и я их
опущу
1
Несколько ответов на разных языках хорошо, даже поощряется (при условии, что они все правильные).
Згарб
0

05AB1E , 14 13 байт

Что ж, код вряд ли закончится для чисел больше 100000, но если вы достаточно терпеливы, будет вывод :). Код:

'#¡rJ¹sF¤rS\J

Объяснение:

'#¡             # Split the input on '#'
   r            # Reverse the stack
    J           # Join the stack
     ¹          # Take the first input
      s         # Swap with the number
       F        # For N in range(0, number), do...
        ¤       #   Obtain the last character
         r      #   Reverse the stack
          S     #   Split everything to individual characters
           \    #   Delete the last character
            J   #   Join the stack

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

Использует кодировку CP-1252

Аднан
источник
0

VBSCRIPT, 82 99 БАЙТОВ

предыдущий код не обрабатывал случаи с числом, завернутым в конец

b=len(a):f=replace(a,"#","/",1,1):c=replace(split(f&f,"/")(1),"#",d) mod b:d=right(a,c)&left(a,b-c)

UNGOLFED

b=len(a)                                 -a->implicit input, get its length 
f=replace(a,"#","/",1,1)  -replace first instance of # so we can split later
c=replace(split(f&f,"/")(1),"#",d) mod b    -get the number and calc the mod
d=right(a,c)&left(a,b-c)                    -d->implicit output

это отстой ... возможно, есть лучший способ сделать это, даже в VBscript

Traceur
источник
Добро пожаловать в Программирование Пазлов и Code Golf Stack Exchange. Этот ответ можно улучшить, добавив разбивку кода и пояснение под кодом для игры в гольф. Кроме того, не могли бы вы сохранить байты, создав функцию вместо программы, где aнаходится функция ввода и она возвращает результат? Таким образом, вам не нужно бы inputboxи msgboxзвонки.
wizzwizz4
Зачем вам нужен b?
CalculatorFeline
0

Mathematica, 73 58 байт

#~StringRotateRight~Max[FromDigits/@StringSplit[#<>#,"#"]]&

Много байт. 15 байт сохранено благодаря в IPoiler

CalculatorFeline
источник
StringRotateRightсохраняет несколько байтов здесь.
IPoiler
0

Matlab (73)

  @(a)regexprep(a,'(\d*)#*(\d*)#*','${circshift($0,[0 str2num([$2 $1])])}')
  • Это использует другой подход, который мне интересен, если @luis использовал его, потому что, ссылаясь на его описание, есть некоторые общие черты, в то время как (un) - к счастью, я не понимаю обрезанный язык Matl.
Abr001am
источник
0

Matlab (86) 72

 @(n)circshift(n,[0 str2num(circshift(n(n~='#'),[0,-find(n=='#',1)+1]))])
  • Функция выполняет суммирование строки два раза, один раз для целочисленного извлечения, второй для желаемой задачи, это не занимает слишком много времени, потому что Matlab продолжает вращаться на (Dim)modulus(Length) за исключением того, что он падает из-за ошибки сегментации для больших диапазонов.

  • Будут бороться, как в гольф это больше ....


(86)

  @(n)circshift(n,[0 str2num([strtok(n(find(n=='#',1,'last'):end),'#') strtok(n,'#')])])
  • Разница между этой функцией и предыдущей, эта действительно объединяет два удаленных вхождения целых чисел назад, в то время как первая просто вращает ее.
Abr001am
источник